harrel56 / json-schema

JSON schema validation library written in Java
https://harrel.dev/json-schema
MIT License
19 stars 4 forks source link

Validation of subschemas via URL fragments #201

Closed demonti closed 5 months ago

demonti commented 5 months ago

I am currently using version 1.3.0 of your schema validator to validate incoming REST requests. I am using the OpenAPI framework, which maintains its API model in a JSON document. Part of the JSON document, in a subtree, there are JSON Schema definitions for each request. Currently, I determine the location of the schema depending on the incoming request, generate a URL with the specific fragment and use the Validator.validate method to perform the validation.

After upgrading the your validator to the latest version, it turned out that it no longer works. Looking at the code, it seems that you have deliberately disabled this feature, but it is unclear, why. You did not refer to the standards in the comment. I am currently a bit puzzled how to solve the problem, if I don't want to stay with 1.3.0. Of course, one could blame the inventors of OpenAPI for their approach of putting all schemes into one file (which actually make use of shared definitions). So is there any chance to relax this again or to provide alternative entry points into the validation, which support this?

harrel56 commented 5 months ago

Hi, could you provide an example which shows exactly what part stopped working? Like a minimal reproducible example so I could understand which behaviour are you talking about specifically.

demonti commented 5 months ago

Hi, although this is not a working example, here are some code fragments which depict the use:

    validator = new ValidatorFactory ().createValidator ();

    ...

    String schema = Json31.pretty (api);   // OpenAPI functions
    URI schema = validator.registerSchema (schema);

    ...
    JsonNode node = ... // parsed request

    String className = type.getSimpleName ();   
      // class name corresponds to name within JSON schema

    URI uri = schema.resolve ("#/components/schemas/" + className);
    Result result = validator.validate (uri, jsonNode);

The stack trace is as follows (from the 1.6.0 release):

java.lang.IllegalArgumentException: Root schema [https://harrel.dev/fba3a7ec#/components/schemas/LoginRequest] cannot contain non-empty fragments
    at dev.harrel.jsonschema.Validator.getRootSchema(Validator.java:154)
    at dev.harrel.jsonschema.Validator.validate(Validator.java:146)
    at dev.harrel.jsonschema.Validator.validate(Validator.java:135)
    at de.knipp.xxxxxx.manager.web.rest.JacksonValidatingProvider.readFrom(JacksonValidatingProvider.java:251)
harrel56 commented 5 months ago

Thanks! Now I get it.

Will have to re-analyse what was the purpose of introducing this constraint. If it's not something mandated by the spec (cannot find anything right now) I think it might make sense to just remove this check. I'll get back to you when I have any updates

harrel56 commented 5 months ago

@demonti Yeah, so believe I added it to behave somewhat like an $id keyword which doesn't support non-empty fragments. But actually there are no mentions about it in specification - tested it with kind of "reference implementation" and they do not forbid such behavior as well.

I personally would advise against using this approach - I'd make any schema that I want to validate against to have an $id keyword so I could easily reference it. But ofc you don't always can nor want to edit your schemas in such way. Then you'd probably end up using some nasty workarounds like registering a schema with just a $ref for each such reference. But yeah, this is just more like an "aesthetic" recommendation.

Summarizing, I just released new patch version 1.6.1 in which this check is removed. Let me know if that fixes your issue and feel free to reopen if there's anything else.

PS: Having some difficulties with uploading to maven central (they recently warned about some kind of migration). So there might be some delays with package availability