使用 AJV 针对 JSON 架构的 API 验证响应期间输出错误
Wrong output during API validation response against JSON schema using AJV
我正在使用 AJV 验证针对 JSON 模式的 API 响应(招摇)。这是进行验证的脚本:
var Ajv = require('ajv');
var ajv = new Ajv();
var schema = {
"paths": {
"/users": {
"get": {
"security": [
{
"3_legged": [
"userprofile-search"
]
}
],
"parameters": [
{
"$ref": "#/parameters/IdentitiesId"
},
{
"$ref": "#/parameters/IdDocumentValue"
},
{
"$ref": "#/parameters/IdDocumentType"
}
],
"responses": {
"200": {
"headers": {
"x-correlator": {
"type": "string",
"format": "uuid",
}
},
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/UserProfile"
}
}
}
}
}
},
"/users/{user_id}": {
"get": {
"security": [
{
"3_legged": [
"userprofile-read"
]
}
],
"tags": [
"users"
],
"operationId": "getUserProfileInfo",
"parameters": [
{
"$ref": "#/parameters/UserId"
}
],
"responses": {
"200": {
"description": "OK",
"headers": {
"x-correlator": {
"type": "string",
"format": "uuid",
"description": "Correlation id"
}
},
"schema": {
"$ref": "#/definitions/UserProfile"
},
"examples": {
"application/json": {
"id": "A000-0000-0001",
"name": "Andrés Iniesta",
"id_document": {
"country": "ES",
"type": "NIF",
"value": "value"
},
"identities": [
{
"type": "email",
"id": "id",
"services": [
"iptv",
"email"
]
},
{
"type": "phone_number",
"id": "id",
"services": [
"mobile"
]
},
{
"type": "phone_number",
"id": "id",
"services": [
"mobile"
]
},
{
"type": "phone_number",
"id": "id",
"services": [
"landline",
"broadband"
]
}
]
}
}
}
}
}
}
},
"definitions": {
"UserProfile": {
"type": "object",
"required": [
"id",
"name",
"identities"
],
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"id_document": {
"$ref": "common.json#/definitions/IdDocument"
},
"identities": {
"type": "array",
"items": {
"$ref": "#/definitions/Identity"
}
}
}
},
"Identity": {
"type": "object",
"required": [
"id",
"services",
"type"
],
"properties": {
"type": {
"type": "string",
"enum": [
"phone_number",
"email",
"uid"
]
},
"services": {
"type": "array",
"items": {
"type": "string",
"enum": [
"mobile",
"invoicing"
]
}
},
"id": {
"type": "string"
}
}
}
}
}
var common = {
"definitions": {
"MoneyAmount": {
"type": "object",
"properties": {
"amount": {
"type": "number"
}
}
},
"IdDocument": {
"type": "object",
"required": [
"country",
"type",
"value"
],
"properties": {
"country": {
"type": "string"
},
"type": {
"type": "string"
},
"value": {
"type": "string"
}
}
}
}
}
var response={
"id": "123456789",
"name": "pruebas trocafone prepago",
"id_document": {
"country": "ARG",
"type": "P",
"value": "15042016"
},
"identities": [
{
"type": "uid",
"services": [
"invoicing"
],
"id": "511644813"
},
{
"type": "phone_number",
"services": [
"mobile"
],
"id": "00123456789"
},
{
"type": "email",
"services": [
"email"
],
"id": ""
}
]
}
ajv.addSchema(schema, 'user_profile.json');
ajv.addSchema(common, 'common.json');
var testajv = ajv.compile({ $ref: 'common.json#/definitions/IdDocument' });
console.log(testajv(JSON.stringify(response)), testajv.errors);
然后,我得到这个输出:
schema id ignored A000-0000-0001
false [ { keyword: 'type',
dataPath: '',
schemaPath: 'common.json#/definitions/IdDocument/type',
params: { type: 'object' },
message: 'should be object' } ]
1- 我不明白为什么 ajv 告诉我 "schema id" 被忽略了。为什么它很重要?
2- 为什么它告诉我 IdDocument/type "should be object"?它是响应中的对象,定义如下:
"id_document": {
"country": "ARG",
"type": "P",
"value": "15042016"
}
有人能帮我理解一下吗?提前致谢!
Swagger Schema 不是 JSON Schema,因此您必须在 Swagger Schema (schema.definitions.UserProfile
) 中找到正确的位置。
虽然 Swagger Definition 并非 100% 兼容 JSON Schema,但在大多数情况下您可以使用通用验证器。
更多信息:https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#schemaObject。
您需要删除 JSON.stringify
,因为它会从您的数据中创建 string
(string
不是 object
)。
ajv.addSchema(schema.definitions.UserProfile, 'user_profile.json');
ajv.addSchema(common, 'common.json');
var testajv = ajv.compile({ $ref: 'common.json#/definitions/IdDocument' });
console.log(testajv(response), ajv.errorsText(testajv.errors));
我正在使用 AJV 验证针对 JSON 模式的 API 响应(招摇)。这是进行验证的脚本:
var Ajv = require('ajv');
var ajv = new Ajv();
var schema = {
"paths": {
"/users": {
"get": {
"security": [
{
"3_legged": [
"userprofile-search"
]
}
],
"parameters": [
{
"$ref": "#/parameters/IdentitiesId"
},
{
"$ref": "#/parameters/IdDocumentValue"
},
{
"$ref": "#/parameters/IdDocumentType"
}
],
"responses": {
"200": {
"headers": {
"x-correlator": {
"type": "string",
"format": "uuid",
}
},
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/UserProfile"
}
}
}
}
}
},
"/users/{user_id}": {
"get": {
"security": [
{
"3_legged": [
"userprofile-read"
]
}
],
"tags": [
"users"
],
"operationId": "getUserProfileInfo",
"parameters": [
{
"$ref": "#/parameters/UserId"
}
],
"responses": {
"200": {
"description": "OK",
"headers": {
"x-correlator": {
"type": "string",
"format": "uuid",
"description": "Correlation id"
}
},
"schema": {
"$ref": "#/definitions/UserProfile"
},
"examples": {
"application/json": {
"id": "A000-0000-0001",
"name": "Andrés Iniesta",
"id_document": {
"country": "ES",
"type": "NIF",
"value": "value"
},
"identities": [
{
"type": "email",
"id": "id",
"services": [
"iptv",
"email"
]
},
{
"type": "phone_number",
"id": "id",
"services": [
"mobile"
]
},
{
"type": "phone_number",
"id": "id",
"services": [
"mobile"
]
},
{
"type": "phone_number",
"id": "id",
"services": [
"landline",
"broadband"
]
}
]
}
}
}
}
}
}
},
"definitions": {
"UserProfile": {
"type": "object",
"required": [
"id",
"name",
"identities"
],
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"id_document": {
"$ref": "common.json#/definitions/IdDocument"
},
"identities": {
"type": "array",
"items": {
"$ref": "#/definitions/Identity"
}
}
}
},
"Identity": {
"type": "object",
"required": [
"id",
"services",
"type"
],
"properties": {
"type": {
"type": "string",
"enum": [
"phone_number",
"email",
"uid"
]
},
"services": {
"type": "array",
"items": {
"type": "string",
"enum": [
"mobile",
"invoicing"
]
}
},
"id": {
"type": "string"
}
}
}
}
}
var common = {
"definitions": {
"MoneyAmount": {
"type": "object",
"properties": {
"amount": {
"type": "number"
}
}
},
"IdDocument": {
"type": "object",
"required": [
"country",
"type",
"value"
],
"properties": {
"country": {
"type": "string"
},
"type": {
"type": "string"
},
"value": {
"type": "string"
}
}
}
}
}
var response={
"id": "123456789",
"name": "pruebas trocafone prepago",
"id_document": {
"country": "ARG",
"type": "P",
"value": "15042016"
},
"identities": [
{
"type": "uid",
"services": [
"invoicing"
],
"id": "511644813"
},
{
"type": "phone_number",
"services": [
"mobile"
],
"id": "00123456789"
},
{
"type": "email",
"services": [
"email"
],
"id": ""
}
]
}
ajv.addSchema(schema, 'user_profile.json');
ajv.addSchema(common, 'common.json');
var testajv = ajv.compile({ $ref: 'common.json#/definitions/IdDocument' });
console.log(testajv(JSON.stringify(response)), testajv.errors);
然后,我得到这个输出:
schema id ignored A000-0000-0001
false [ { keyword: 'type',
dataPath: '',
schemaPath: 'common.json#/definitions/IdDocument/type',
params: { type: 'object' },
message: 'should be object' } ]
1- 我不明白为什么 ajv 告诉我 "schema id" 被忽略了。为什么它很重要?
2- 为什么它告诉我 IdDocument/type "should be object"?它是响应中的对象,定义如下:
"id_document": {
"country": "ARG",
"type": "P",
"value": "15042016"
}
有人能帮我理解一下吗?提前致谢!
Swagger Schema 不是 JSON Schema,因此您必须在 Swagger Schema (schema.definitions.UserProfile
) 中找到正确的位置。
虽然 Swagger Definition 并非 100% 兼容 JSON Schema,但在大多数情况下您可以使用通用验证器。
更多信息:https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#schemaObject。
您需要删除 JSON.stringify
,因为它会从您的数据中创建 string
(string
不是 object
)。
ajv.addSchema(schema.definitions.UserProfile, 'user_profile.json');
ajv.addSchema(common, 'common.json');
var testajv = ajv.compile({ $ref: 'common.json#/definitions/IdDocument' });
console.log(testajv(response), ajv.errorsText(testajv.errors));