这里需要注意的一点是,OpenAPI Schema 并未用于验证请求和响应的目的。OpenAPI 架构无法更改为常规 JSON 架构。
假设我们在表单中有一个 OpenAPI 模式
TestSchema.json
{
"components": {
"schemas": {
"book": {
"type": "object",
"properties": {
"title": {
"type": "string"
},
"author": {
"$ref": "#/components/schemas/author"
}
}
},
"author": {
"type": "object",
"properties": {
"name": {
"type": "string"
}
}
}
}
}
}
现在假设我们有一些 JSON 采用上述模式中定义的“书”的形式
{
"title": "LOTR",
"author": {
"name": "Tolkien"
}
}
使用json-schema-validator库,我们编写了代码来执行此验证,如下所示
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);
}
}
用法:
@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()
);
}
由于 OpenAPI 模式有两个额外的节点,"components"
并且"schemas"
此代码不执行验证,因为我们无法在我们的“书”json 和模式之间进行 1-1 验证。
解决此问题的一种方法是使用.findValue("book")
public SchemaValidator(FileReader schemaFile) throws IOException {
schema = getJsonSchemaFromJsonNode(mapper.readTree(schemaFile).findValue("book"));
}
但这会导致错误
#/properties/author/$ref: Reference #/components/schemas/author cannot be resolved
因为我们现在已经破坏了参考路径。
解决此问题以通过测试的一种方法是$ref
将架构中的 调整为#/author
但架构本身无效。
我是否缺少此库中的工具或错误地构建对象?需要做什么才能使这个验证工作?
我在open-api-validator中进行了挖掘,最终使用该json-schema-validator
库执行验证,但请求/响应验证不是我需要的步骤。