[json-schema] How to $ref to a schema within same File?

1,251 views
Skip to first unread message

David P

unread,
Oct 6, 2021, 11:30:03 AM10/6/21
to vert.x
Hello dear Vert.x community,

I want to use the vertx-json-schema ( JSON Schema | Eclipse Vert.x (vertx.io)) to validate a Json thnaks to a schema that refers second schema within the same File.

I could verify when second schema is outside,  in an External File;

This is a sample of JSON schema file below.


----------------------------------
{
  "schema": {
    "$ref": "#/components/schemas/Caller"
  },
  "components": {
    "schemas": {
      "Caller": {
        "type": "object",
        "required": [
          "name"
        ],
        "description": "Name of the caller.",
        "properties": {
          "name": {
            "description": "Name of the caller",
            "type": "string"
          }
        }
      }
    }
  }
}
-----------------------------

I guess, I have to parse the "#/components/schemas/Caller" schema first with providing a correct JsonPointer for registration  in schemaRouter.
However, I cannot find how :/

Any Help?

Thanks,
David

David P

unread,
Oct 6, 2021, 12:10:25 PM10/6/21
to vert.x
I've just found the root cause of the issue:  I was parsing a YAML file that it has been converted to JSON:

JsonNode jsonNode = new YAMLMapper().readTree(new FileInputStream(Paths.get(FILE_PATH).toFile()));
JsonObject openAPIJson = new JsonObject(jsonNode.toString());


Then, I used a JsonPointer like this
JsonPointer callerPointer = JsonPointer.fromURI(Paths.get( FILE_PATH  ).toUri()).append("/components/schemas/Caller");

But when I work directly with a JSON File, it works fine!


Sorry for the  inconvenience  :/
David

David P

unread,
Oct 6, 2021, 12:37:45 PM10/6/21
to vert.x
In fact , the "internal" references are resolved directly using the URI of the parsed schema.
It works only if the URI linked to Json file.

In case it may help:
This is a sample of the code:

JsonObject sampleJson = new JsonObject(new String(Files.readAllBytes(Paths.get(SAMPLE_PATH))));
logger.info("sampleJson: \n{}", sampleJson.encodePrettily());

final SchemaRouter schemaRouter = SchemaRouter.create(vertx, new SchemaRouterOptions());
final SchemaParser draft201909SchemaParser = SchemaParser.createDraft201909SchemaParser(schemaRouter);

JsonObject mainSchemaJson = (JsonObject) JsonPointer.from("/schema").queryJson(sampleJson);
JsonPointer mainSchemaPointer = JsonPointer.fromURI(Paths.get(SAMPLE_PATH).toUri()).append("/schema");
Schema mainSchema = draft201909SchemaParser.parse(mainSchemaJson, mainSchemaPointer);
logger.info("mainSchema: \n{}", ((JsonObject) mainSchema.getJson()).encodePrettily());


mainSchema.validateAsync(new JsonObject().put("name", "Alice")).toCompletionStage()
.thenRun(() ->logger.info("JSON Validation OK" ))
.toCompletableFuture().get(3000, TimeUnit.MILLISECONDS);


-------------------

And logs:

[INFO ] 2021-10-06 18:35:04.493 [Test worker]  sampleJson: 
{
  "schema" : {
    "$ref" : "#/components/schemas/Caller"
  },
  "components" : {
    "schemas" : {
      "Caller" : {
        "type" : "object",
        "required" : [ "name" ],
        "description" : "Name of the caller.",
        "properties" : {
          "name" : {
            "description" : "Name of the caller",
            "type" : "string"
          }
        }
      }
    }
  }
}
[DEBUG] 2021-10-06 18:35:04.622 [Test worker] RefSchema - Parsed /components/schemas/Caller ref for schema {"$ref":"#/components/schemas/Caller"}
[INFO ] 2021-10-06 18:35:04.628 [Test worker] - mainSchema: 
{
  "$ref" : "#/components/schemas/Caller"
}
[INFO ] 2021-10-06 18:35:04.781 [vert.x-eventloop-thread-0] - JSON Validation OK



Reply all
Reply to author
Forward
0 new messages