-
Notifications
You must be signed in to change notification settings - Fork 18
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
JsonValidationService.readSchema(InputStream is) doesn't correctly resolve http $ref #6
Comments
I do realize the draft 07 docs give some latitude to the validator impl regarding resolving $ref per the following: "Even though the value of a $ref is a URI, it is not a network locator, only an identifier. This means that the schema doesn’t need to be accessible at that URI, but it may be. It is basically up to the validator implementation how external schema URIs will be handled, but one should not assume the validator will fetch network resources indicated in $ref values." however, if the resulting uri reference is http, it should resolve it over the network. Besides, it would be super convenient if it worked that way. |
I ended up finding and using the mechanism in your api to implement my own JsonSchemaResolver. That works for me. |
Hello @chadlankford. Thank you for using this small library. |
one other question. is there a way to output the effective schema after the $refs are resolved? |
Do you mean you would like to merge the referencing schema and the referenced schemas into a large one schema and output it to a file ? {
"$id": "http://example.org/example.schema.json",
"type": "object",
"properties": {
"foo": {
"$ref": "http://example.org/example.schema.json"
}
}
} |
yeah, I didn't think about the recursive reference situation. I suppose you would just have to make a decision to stop resolving the references for effective schema once recursive situation is detected. maybe, inject a $comment in the effective schema to represent why a reference was not resolved. |
Here is a referencing schema. {
"$id": "https://example.org/a.schema.json",
"type": "object",
"properties": {
"foo": {
"$ref": "b.schema.json"
}
}
} And this is the second schema referenced from the first one. {
"$id": "https://example.org/b.schema.json",
"type": "integer",
"minimum": 0
} Then you can merge the second schema into the first one using {
"$id": "https://example.org/a.schema.json",
"type": "object",
"properties": {
"foo": {
"$ref": "b.schema.json"
},
"definitions": {
"name-whatever-you-like": {
"$id": "https://example.org/b.schema.json",
"type": "integer",
"minimum": 0
}
}
} Practically, why do you need to merge multiple schema files into one? |
yes, the utility of this is strictly for debugging in the cases of complex object graphs whose schemas make heavy use of $ref. Sometimes it can be helpful. |
Another question for you... I have implemented a custom problem handler which basically outputs the problem parameters map. The output is pretty good except it would be nice if the there was more context to the problem. For example, if it problem says a property foo is required, it would nice to see at least to which object the property is supposed to belong. Same situation if the problem is a value validation. Right now, value validation problems just indicate actual and expected value definition maps, but should indicate a property with context. To me, the best solution is to include the entire object path to the property at the center of the problem, using either a json pointer or some sort of json pathing notation, ie, "foo.bar.key". Like the effective schema issue I mentioned, this is also something that is very useful for deep/complex object validations. Does that make sense? |
Thank you @chadlankford. Now I go it. Please see the issue #5 because it is related to your second request. |
Hello @chadlankford, |
Hello @rconnacher |
Thanks, and Hi @leadpony, In my experiment I define a JsonSchemaReaderFactory as in your example, and create a JsonSchemaReader using StringReader over the schema text. (I'm coding in Groovy, so I had to port your example.)
as the jsonData I run this:
But when I try to read the schema, I get a casting exception:
That last call, "AbstractBasicSchemaReader.resolveSchema" is here:
I'm using Groovy 3.0.0, where method references (like ".withSchemaResolver(AbstractConformanceTest::resolveSchema") are pretty new. Is this possibly the problem? Can you suggest any way of creating a reader that can resolve remote references without that recursive sort of configuration? Thanks very much! |
Below, you will find a rough outline of what I did. Basically, the NetworkJsonSchemaResolver, just retrieves the remote file, reads it in with a new SchemaReaderFactory on which its sets itself to the resolver. The getSchemaJson method is just your favorite way to pull the contents of a remote file over http as a String. Now, I did this quickly because I knew all my references were to network locations. I am basically making the assumption every reference is a url. If I was trying to make this more robust, I would impl the NetworkJsonSchemaResolver more generically as a GenericJsonSchemaResolver which perhaps inspects the uri and uses the protocol, if any, as a hint of how to load it. For example, http or https would indicate a network location. Maybe, if the protocol is file or classpath, the resolver could handle this intelligently as a fully qualified local location. And, perhaps if all else fails, treat the reference as this library does by default. Hope this helps.
|
Hello @rconnacher and @chadlankford |
@chadlankford |
@leadpony Mine's not quite working yet (mixing reader methods resulted in random "Unexpected char 0" parsing errors thrown by the glassfish JsonParser when the JsonSchemaReader looks for a next event). I'll report back once I figure it out. Thanks again! |
Hello @rconnacher |
valid schema reference is built taking the value of $ref and applying it relative to the domain of the current schema. It yields a valid URL of the format http://mydomain/myschemafile.json which resolves. however I get the error message:
org.leadpony.justify.api.JsonValidatingException: [line:6,column:65] The schema reference "/myschemafile.json"(http://mydomain/myschemafile.json) cannot be resolved.
since a valid URL is built, curious why it isn't able to resolve it? could you please support this mechanism for referencing an external hosted file in $ref? fyi - I also tried putting the full url in the $ref rather than a domain relative path, same result.
thanks in advance.
The text was updated successfully, but these errors were encountered: