networknt / json-schema-validator

A fast Java JSON schema validator that supports draft V4, V6, V7, V2019-09 and V2020-12
Apache License 2.0
807 stars 320 forks source link

Validate json schema against draft-2020-12 #991

Closed rishabh413 closed 4 months ago

rishabh413 commented 4 months ago

Query

How to get a validation error like invalid $ref for the schema: using this library?

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type" : "object",
  "properties" : {
    "myProperty": {
      "$ref": "invalid_ref"
    }
  }
}

More details

I believe this will require validating above json as data against meta-schema of draft 2020-12's . Does this library have a meta schema in-built, which we can load and validate?

justin-tay commented 4 months ago

Yes you can validate a schema against a meta-schema. But this isn't going to do what you are expecting. If what you want is to check whether the $ref can actually resolve then validating against the meta-schema is unlikely to be helpful as this will only perform structural validation.

        String instanceData = "{\r\n"
                + "  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\r\n"
                + "  \"type\" : \"object\",\r\n"
                + "  \"properties\" : {\r\n"
                + "    \"myProperty\": {\r\n"
                + "      \"$ref\": \"invalid_ref\"\r\n"
                + "    }\r\n"
                + "  }\r\n"
                + "}";
        SchemaValidatorsConfig config = new SchemaValidatorsConfig();
        config.setPathType(PathType.JSON_POINTER);
        config.setFormatAssertionsEnabled(true);
        JsonSchema schema = JsonSchemaFactory.getInstance(VersionFlag.V202012).getSchema(SchemaLocation.of(SchemaId.V202012), config);
        System.out.println(schema.validate(instanceData, InputFormat.JSON, OutputFormat.HIERARCHICAL, executionContext -> {
            executionContext.getExecutionConfig().setAnnotationCollectionEnabled(true);
            executionContext.getExecutionConfig().setAnnotationCollectionFilter(keyword -> true);
        }));

In particular the meta-schema will only check if the value in $ref corresponds to to the uri-reference format which it will validate to be true as invalid_ref is a valid uri-reference.

{
  "valid": true,
  "evaluationPath": "/allOf/1/$ref/properties/properties/additionalProperties/$dynamicRef/allOf/0/$ref/properties/$ref/$ref",
  "schemaLocation": "https://json-schema.org/draft/2020-12/meta/core#/$defs/uriReferenceString",
  "instanceLocation": "/properties/myProperty/$ref",
  "annotations": {
    "format": "uri-reference"
  }
}

If you want to check if the schema can properly load and resolve $ref then you need to load the schema by initializing the validators.

        String schemaData = "{\r\n"
                + "  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\r\n"
                + "  \"type\" : \"object\",\r\n"
                + "  \"properties\" : {\r\n"
                + "    \"myProperty\": {\r\n"
                + "      \"$ref\": \"invalid_ref\"\r\n"
                + "    }\r\n"
                + "  }\r\n"
                + "}";
        SchemaValidatorsConfig config = new SchemaValidatorsConfig();
        config.setPathType(PathType.JSON_POINTER);
        config.setFormatAssertionsEnabled(true);
        JsonSchema schema = JsonSchemaFactory.getInstance(VersionFlag.V202012).getSchema(schemaData, config);
        try {
            schema.initializeValidators();
        } catch (Exception e) {
            e.printStackTrace();
        }
rishabh413 commented 4 months ago

thanks