Reputation: 31
One caveat here is that the OpenAPI Schema is not being used for the purposes of validating requests and responses. The OpenAPI schema can't be changed to a regular JSON Schema.
Say we have an OpenAPI schema in the form
TestSchema.json
{
"components": {
"schemas": {
"book": {
"type": "object",
"properties": {
"title": {
"type": "string"
},
"author": {
"$ref": "#/components/schemas/author"
}
}
},
"author": {
"type": "object",
"properties": {
"name": {
"type": "string"
}
}
}
}
}
}
Now imagine we have some JSON taking the form of a "book" as defined in the above schema
{
"title": "LOTR",
"author": {
"name": "Tolkien"
}
}
Using the json-schema-validator library we've written code to perform this validation as follows
public class SchemaValidator {
private final ObjectMapper mapper = new ObjectMapper();
private final JsonSchema schema;
public SchemaValidator(FileReader schemaFile) throws IOException {
schema = getJsonSchemaFromJsonNode(mapper.readTree(schemaFile));
}
public Set<ValidationMessage> validate(String json) throws IOException {
return schema.validate(mapper.readTree(json));
}
private JsonSchema getJsonSchemaFromJsonNode(JsonNode node) {
return JsonSchemaFactory.getInstance(VersionFlag.V6).getSchema(node);
}
}
Usage:
@Test
void validate_invalidTitle() throws IOException {
var schemaValidator = new SchemaValidator(
new FileReader("src/test/resources/TestSchema.json")
);
var json = "{\"title\":5,\"author\":{\"name\":\"Tolkien\"}}";
assertEquals(
"$.title: integer found, string expected",
schemaValidator.validate(json).stream().findAny().orElseThrow().getMessage()
);
}
Since the OpenAPI schema has two extra nodes, "components"
and "schemas"
this code doesn't perform validation because we can't do a 1-1 validation between our "book" json and the schema.
A way around this is to re-write the constructor with a .findValue("book")
public SchemaValidator(FileReader schemaFile) throws IOException {
schema = getJsonSchemaFromJsonNode(mapper.readTree(schemaFile).findValue("book"));
}
But this results in an error of
#/properties/author/$ref: Reference #/components/schemas/author cannot be resolved
As we have now broken the reference path.
One way around this to get the test to pass is to adjust the $ref
in the schema to #/author
but the schema itself is then invalid.
Am I missing a tool in this library or building the objects incorrectly? What needs to be done to make this validation work?
I dug around in the open-api-validator which ends up using the json-schema-validator
library to perform validation but the request/response validation is not a step I need.
Upvotes: 3
Views: 3654