-
Notifications
You must be signed in to change notification settings - Fork 354
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Separated files are not validated correctly #396
Comments
Yikes, that's not good! Thanks for the heads-up, will investigate. |
I actually discovered this while using that example spec as a fixture for another library, and suddenly wondered how it could ever work as I was json_decoding it myself before feeding it to the validator, which therefore never even saw the file or base path. So none of the default settings of the On a related note: as there's no documentation whatsoever regarding external references I'm not even sure how I would go about fixing this even if an error were thrown. It would really be a good idea to have some examples for cases like this. |
OK, so I've had a look through the schema, and it only refers to itself and (using an absolute path) to the draft-04 meta-schema. However, I have tested your example, and have confirmed via wireshark that the draft-04 spec is being correctly fetched from http://json-schema.org/draft-04/schema. Could you please clarify whether you are reporting:
[Ed: If it's (2), then it's not a bug, and is working as intended - JSON documents do not have any means of referring to other documents (see here). |
Which version of json-schema are you using? This seems to be working fine from v2.0.0 upwards, including in the current 5.1.0 and in the 6.0.0-dev tree... $ ./validate-json test.json swagger.json Output (v5.1.0):
test.json: {
"paths": {
"/pets": {
"get": {
"responses": {
"default": {
"schema": {
"invalidProperty": "invalidData"
}
}
}
}
}
}
} |
Documentation for |
Thanks for the swift responses! I'm kind of confused with what you are saying. Let's take the most simplified example Swagger file. It contains internal references within its own document:
To my best knowledge this is a native JSON schema feature, and validating this file against the spec should in this case inline expand the Pet definition and validate its contents recursively for whether it's appropriate and valid in this context. If I understand you correctly this library currently just validates this As for the documentation: I was referring on how to properly use the |
@curry684 It's bedtime here - but give me a few hours, and I'll explain in a bit more detail how it works, and what I think you're running into here. |
This is where you're running into problems. You're correct that A JSON schema validator takes two inputs - one is the document to be validated, and the other is the schema to validate against.
I think the bit that's tripping you up is that you are confused why the references in So, in your example, you are asking the question, "Is What your example does not have is the next step of the process, which would be to ask, "Is For the purposes of additional clarification, I would like to point out that the thing which determines whether a file is treated as a schema or as an ordinary JSON document is not what the content of the file looks like. The determining factor is whether you tell the validation library that it's a schema (by passing it as the 'schema' argument), or if you tell the library that it's a normal document (by passing it as the 'please validate this thing against the schema' argument). In summary - this is user error, not a bug. However, if you are still confused by this, please let me know which part you are finding unclear or strange, and I'll try to expand on it a bit more. |
You are right - we definitely need to improve the documentation, particularly in those areas! I think we need to properly nail down which parts of the API are public first (see #392), but once that's done more documentation should definitely be on the cards. |
Thank you very much for the verbose and helpful explanation. I was wrongly under the impression that, in the context of validation, properties starting with a The end result is however afaics that there is no way whatsoever to properly validate an OpenAPI definition right now. Not only is the split-file support absent, it also cannot see then whether an internal reference actually points to an object that is valid in that location. So the followup question: is there some kind of way to patch this behavior into the validator for me as a consumer? All I would actually need is to inline resolve a |
This is a deviation from the spec (the spec defines it as a string URI that references a schema's meta-schema). This library uses it as a fallback option if the user does not provide a schema (by looking there for an inline schema), however this behavior is nothing to do with the standard. It's just an additional non-standard feature that previous developers of this library have chosen to implement.
Unfortunately, without additional logic, this is indeed currently the case. The official JSON standard doesn't support multi-file documents, so any validation behavior that is capable of processing such a thing very definitely falls under the category of custom / non-standard features.
Certainly, although I don't think this kind of behavior belongs in the actual validation library (@shmax / @bighappyface?). You could however certainly repurpose the My recommendation for your particular use-case would be to write a simple preprocessor. This preprocessor would:
This would then allow you to preprocess the references, then feed the entire thing to the validator. It would ensure that everything is properly validated against the schema, including your split files, without needing to introduce nonstandard behavior into the library. An example preprocessor could look something like this (pseudocode):
Please let me know if you'd like me to clarify any of that further, or if you have additional questions. |
Actually that's more or less what I was writing right now :) The following implementation appears to work fine, completely standalone with the separated example:
Obviously lacking a lot of error checking, and not sure how it handles circular references right now, but it's now passing validation fine and triggering the right errors when dependencies are broken. |
That looks pretty good :-). 👍 Note that with
[Ed: Looks like you were a step ahead of me - I think you edited your comment to mention the error situation while I was still typing this, or I didn't see it - either way, sounds like you're already on it ;-)] |
One other thought - your preprocessor as you have written it will not handle recursive or nested references. You may not care about that, but figured it was worth mentioning. |
Yeah I was adding the error checking part to save you the effort of reviewing a proof of concept prototype which I knew was flawed in a lot of ways hehe. The recursion would be a simple matter of repeating the process I noticed that the logic I wrote here more or less resembles what See, your point that the ECMA-404 JSON standard does not in any way define references is completely correct, and as such the point is acceptable that the library does not support them. However JSON Pointers themselves are an accepted standard on their own in RFC 6901 as an optional extension to JSON documents. Hence in my opinion, given how many people are working with OpenAPI/Swagger or related schemas, it would be a good idea to provide optional support for automatically resolving JSON Pointers in a validation library. A simple |
@shmax What's your take on this? |
@curry684 With JSON Schema Draft 04, there was a separate draft RFC for JSON Reference. So OpenAPI could refer to that as its own thing. With JSON Schema Draft 05 (and the forthcoming Draft 06), I am personally hoping to put some thought into how JSON Schema can be used within other formats, as that is very common (it's how OpenAPI uses it). That should re-clarify how to use |
Are you asking if I think that the json-schema library (meaning this one) should be responsible for resolving $refs in the incoming document? I'm not sure. I'm sitting here trying to form an opinion and getting nowhere. It's a use case that's never occurred to me--so far I've only been using json-schema to validate incoming ajax requests from my site's front end, so what you guys are talking about has never come up. That said, I guess I can't think of any real reason why we couldn't do it, from a technical sense; in fact, haven't we already provided everything needed to do it? Something like: $schemaStorage = new SchemaStorage();
$resolvedInput = $schemaStorage->resolveRefSchema($input);
$validator->validate($resolvedInput, $schema); |
Well, no, I guess that wouldn't recurse; I'll poke around a bit more later. |
@shmax Pretty much. It would be technically fairly easy to implement, although it also raises all kind of other questions (e.g. do we support differing resolution bases the way JSON schema does via I guess where I'm coming from is that I know we can, but I don't think we should... but we have a real-world user who needs the functionality, and he won't be the only one. This feels like a case that goes beyond the remit of a JSON validator, particularly noting how easily solveable this one is with a preprocessor, and I want to say no because of that, but I'm feeling conflicted about it. |
@handrews You will have seen many more such cases than this one I suspect, and may have a better perspective - do you have an opinion on whether we should add an option to dereference and expand |
I'm not even opposed to this. The suggestion I made about the So the question in that case becomes: how to expose the functionality. I see multiple options, like a plain and simple |
@curry684 You make some good points - perhaps there's room for a middle-ground approach here. If we were to tweak the architecture so that there was a generic The more I think about it, the more this idea seems reasonable - we don't have to add any nonstandard functionality to the validator (which I would really rather we not do), but there will be a class there that is documented in the public API that can be used to do all the heavy lifting in a preprocessor. The end result could be end-user code that looked somewhat like this: use \JsonSchema\ReferenceResolver;
use \JsonSchema\Validator;
// recursively resolve, fetch & expand $ref
$input = ReferenceResolver::resolve($input, RESOLVE_MODE_FETCH);
$validator = new Validator();
$validator->validate($input, $schema); You'd still need to write the bit above, obviously... but it does seem that it addresses your primary concern here, while avoiding adding anything to the library that would deviate from the standard. @shmax / @bighappyface / @handrews Your thoughts on this? I'm happy to do the work, if we all agree that this is a reasonable approach. If we don't agree, then I'm happy to stick with the status quo until we agree on an alternative way of doing things (or decide to do nothing, which is also a perfectly valid option). |
Obviously such a |
Your suggested code seems perfectly reasonable. If we can reduce a common semi-custom end-user requirement to a single line of code I think that's the optimal solution by definition. |
@erayd I can come up with different answers depending on the goal: From a strict compatibility standpoint, But as an option that can be configured- yeah it seems useful. JSON Reference was a separate thing at one point so it made more sense for OpenAPI to use it without necessarily defining it on their own back then. |
Take a look at the split up OpenAPI/Swagger example definition at https://github.com/OAI/OpenAPI-Specification/blob/master/examples/v2.0/json/petstore-separate/spec/swagger.json.
It's split up into multiple files, for example:
Running the following command on a local copy of that file (schema here):
Happily outputs that validation succeeded... even if I add dozens of random characters anywhere in any of the included documents.
So it would seem that:
The text was updated successfully, but these errors were encountered: