Hi,
Although having a valid JSON, my input never pass the validation, I have noticed the reason is the presence of justinrainbow/json-schema. I was searching the web about this and realized that it has caused some problem in other modules as well. Can you please check it out.
Many thanks,
Ramin
PS: Here is the logged error messages:
Validation errors: [{"property":"[0]","pointer":"\/0","message":"Array value found, but an object is required","constraint":"type","context":1},{"property":"[0].headers","pointer":"\/0\/headers","message":"Array value found, but an object is required","constraint":"type","context":1}]
Response failed validation: [{"action":"create","uri":"\/jsonapi\/node\/article","headers":{"Accept":"application\/vnd.api+json","Content-Type":"application\/vnd.api+json"},"requestId":"42f34c4b-9472-4414-9296-097f3dd920f4","body":"{\u0022data\u0022:{\u0022id\u0022:\u002242f34c4b-9472-4414-9296-097f3dd920f4\u0022,\u0022type\u0022:\u0022node--article\u0022,\u0022attributes\u0022:{\u0022title\u0022:\u0022this article has only a title\u0022,\u0022comment\u0022:{\u0022status\u0022:\u00220\u0022,\u0022cid\u0022:\u00220\u0022,\u0022last_comment_timestamp\u0022:\u00221525337478\u0022,\u0022last_comment_name\u0022:null,\u0022last_comment_uid\u0022:\u00221\u0022,\u0022comment_count\u0022:\u00220\u0022},\u0022metatag\u0022:[]},\u0022relationships\u0022:[]}}"}]
| Comment | File | Size | Author |
|---|---|---|---|
| #22 | image.png | 712.49 KB | symbioquine |
| #20 | 2971295-20.patch | 1 KB | paul121 |
| #19 | subrequests-2971295-19.patch | 842 bytes | nrogers |
| #17 | subrequests-2971295-17.patch | 2.58 KB | ikphilip |
| #15 | 2971295-json-schema-fails-15.patch | 626 bytes | paulmckibben |
Comments
Comment #2
e0ipsoI have never had validation errors in the past. It is possible that you have an empty array that needs to be converted to an empty object? Arrays and objects are confusing in PHP.
Comment #3
hedeshy commentedWell, I have some more info about this. It is just a warning message which makes no sense since I have checked my input with the schema provided in the module folder. So, I've just ignored it because even though this warning is logged, Subrequests and JSONAPI work the way they are supposed to and the client receives a successful response.
Comment #4
hedeshy commentedComment #5
e0ipsoThanks for taking the time to loop back on this.
Comment #6
skdrupal88I have the same problem with backend based on Contenta, the result of quick investigation:
`$input` variable in `JsonBlueprintDenormalizer.php:validateInput`method is nested array.
But validator tries to validate it with `/subrequests/schema.json`, and `schema.json` says that `subrequest` and `headers` should be objects, but these values are arrays inside $input variable.
Any request returns validation error and blocks work with the module.
Please let me know if I can provide more information.
Thanks.
Comment #7
ikphilipI'm also having the same problem referenced by shorzh#6. There's no warning because JsonBlueprintDenormalizer->doValidateInput() is throwing a PHP exception with the current schema.json configuration.
My fix here is to update subrequest.type and headers.type to "array".
Comment #8
e0ipso@ikphilip @skorzh do you have a patch to look at?
Comment #9
ikphilip@e0ipso Yes, see attached file.
Comment #10
e0ipsoHmmm. It seems that the example in the project page shows this:
Moreover, the code that uses that input (
Drupal\subrequests\Normalizer\JsonSubrequestDenormalizer::55) saysSo it really looks like the headers property is a key-value object.
Can you validate this? (feel free to re-open).
Comment #11
ikphilipI can confirm that my (sub)request header structure and body is correctly formatted. Authorization removed for simplicity.
When I analyze the data which passes through the deserializer the structure of the JSON is already converted to a PHP. That is, the $data object passed into
Drupal\subrequests\Normalizer\JsonBlueprintDenormalizer::doValidateInput()is a PHP array.See my debug screen shot of the $data object passed into doValidateInput().
The following error appears when headers.type = "object" or subrequest.type = "object". You can see from my trace that they are treated as arrays in PHP.
Regarding
Drupal\subrequests\Normalizer\JsonSubrequestDenormalizer::55, by the time that code is executed $data has been transformed into aDrupal\subrequests\Subrequestobject and is no longer simply a PHP array. See my SS that traces that code location.Comment #12
e0ipsoIt looks like that the problem is on calling
doValidatein the wrong place, the problem doesn't seem to be the JSON Schema, does it?Do you think you can work in a patch in that direction? Many thanks in advance!
Comment #13
ikphilipI would like to work on this and I installed new Drupal and subrequests module and the problem did not reoccur. I'm going to chase down this problem as it might be a product of our app's composer dependencies. I will return this issue to Closed (cannot reproduce) since I can't replicate it.
Comment #14
paulmckibbenI am seeing this problem in Drupal 8.7.7 and subrequests 8.x-2.2. I will try to figure out more.
Comment #15
paulmckibbenOverall, I'm stumped on how best to fix this, especially not being familiar with the codebase.
@e0ipso, you had suggested that the call
doValidateInput()needs to be moved, but I'm not sure to where, or if that would even help.What I am seeing:
$this->doValidateInput($data)fails because of the way the request was deserialized in the step above.For now, I'm providing this patch which just eliminates the call to
doValidate(). It's a workaround, not a fix, to keep my project going, and to help anyone else running into the same thing.I'm happy to work with others to find a more appropriate fix.
Thanks!
Paul
Comment #16
briangonzalezmiaI'm also experiencing the same validation failure issue as the others (Drupal core 8.7.8, and Subrequests 8.x-2.2) and can confirm that the patch in #9 and #15 both work, although I opted #9 as it it still maintains some functional validation. Thank you all!!
Comment #17
ikphilipI agree with paulmckibben's summary of the issue. I dug a little bit and found that the current schema works with Drupal 8.6.x but these problems begin with 8.7.x so there is probably a change in the Serialization between these versions.
I think this should testable. There's no reason we can't feed the validation function schema that we know is valid and invalid. Please consider this patch a step towards testing the updated schema.
Comment #18
bjcooper commentedI've seen two separate issues that manifest with "failed validation" warnings (not sure which the OP is referring to).
The first is where subrequest blueprints fail validation. Lots of people talked about this above (and in this issue also). The patch in #9 fixed that for us.
The second issue is where the final, actual response from the Subrequests module (containing the results of all the subrequests) fails validation. For me, this is accompanied in the logs with an "assert(): A JSON:API response failed validation" warning. This only happens when you (1) have the JSON:API module enabled, (2) set the response format to JSON in the original request like so: "/subrequests?_format=json", and (3) all subrequest blueprints have "
Accept: application/vnd.api+json" headers (like if all your subrequests are to JSON:API resources).In this case, the
normalize()function insubrequests/src/Normalizer/MultiresponseJsonNormalizer.phpkicks in and sets the response header "Content-Type: application/json; type=application/vnd.api+json" (the "type=application/vnd.api+json" bit is sniffed from the subrequest content types).Meanwhile, the JSON:API module is subscribed to HTTP Response events (
jsonapi/src/EventSubscriber/ResourceResponseValidator.php) and processes the response before it goes out. You can see in itsonResponse()method that it simply checks to see if the Content-Type of the response contains the string "application/vnd.api+json". If so, it runs the response through the JSON:API response validation. Since the Subrequests module response is not itself a valid JSON:API response (it's just JSON), it fails validation.You can get around this in two ways. First, you could patch JSON:API module (core) to be smarter about how it checks to see if responses are JSON:API results (technically the Subrequests module isn't saying it's response Content-Type is a JSON:API result, it just contains that special string in a non-standard "type" attribute). Second, you could patch Subrequests to skip including the non-standard "type" attribute that is confusing the JSON:API module. We'll post a patch for that below.
Edit: Patch in #19.
Comment #19
nrogers commentedHere's the patch mentioned in #18.
Comment #20
paul121 commentedI was able to fix the errors by specifying
Constraint::CHECK_MODE_TYPE_CASTas the validator check mode as documented in justinrainbow/json-schema here: https://github.com/justinrainbow/json-schema#configuration-optionsIt's description is to "Enable fuzzy type checking for associative arrays and objects" which I think makes sense in this case. One thing I noticed, that I'm not sure has been pointed out above, is that the SubrequestsTree class extends the PHP ArrayObject class. This might explain where the validator is trying to enforce arrays, not objects?
For what it's worth, I tested the next check mode on the list
CHECK_MODE_COERCE_TYPES, described as "Convert data types to match the schema where possible", and it did not work. I thought it would work, but was afraid it would be too heavy-handed.This seems like a better solution than changing the schema type to be an "array", since that really should be an "object" in order for the other JSONAPI Schema "properties", "required", etc to work. I'm not sure we need this included in test coverage, but perhaps something like the test in #17 could be added.
I do not think this fixes what @bjcooper described in #18 which seems like a separate issue. Still going to mark this for review because it would be nice to get this fixed.
Comment #21
paul121 commentedI think I'm seeing the same behavior as @bjcooper in #18. The watchdog message I have is "Response failed validation. Response: {...the subrequest response}" (different than they reported, but seems similar?). The patch in #19 fixes the issue.
Comment #22
symbioquine commentedWithout any patches but with the
?_format=jsonparameter I was getting warnings about the response validation failing because the request id keys weren't among the expected set of keys for a JSON:API response. (See my attached screenshot.)The patch from comment #19 fixes those warnings in my case. Any chance it can be merged some time soon?
Comment #24
e0ipsoI merged #20 and a modified version of #19. This also corrects some incorrect behavior from a previous fix.