удобное сообщение об ошибке с использованием валидатора схемы ajv json - PullRequest
0 голосов
/ 03 апреля 2020

Если у меня есть схема & JSON:

JSON Схема:

const schema = {
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "required": [ "countries" ],
  "definitions": {
    "europeDef": {
      "type": "object",
      "required": ["type"],
      "properties": { "type": {"const": "europe"} }
    },
    "asiaDef": {
      "type": "object",
      "required": ["type"],
      "properties": { "type": {"const": "asia"} }
    }
  },
  "properties": {
    "countries": {
      "type": "array",
      "items": {
        "oneOf":[
          { "$ref": "#/definitions/europeDef" },
          { "$ref": "#/definitions/asiaDef"}
        ]
      }
    }
  }
}

JSON:

const data = {
  "countries":[
    {"type": "asia1"},
    {"type": "europe1"}
  ]
}
const isValid = ajv.validate(schema, data); //schema, data
if(! isValid){
  console.log(ajv.errors);
}

и сообщение об ошибке:

[ { keyword: 'const',
    dataPath: '/countries/0/type',
    schemaPath: '#/definitions/europeDef/properties/type/const',
    params: { allowedValue: 'europe' },
    message: 'should be equal to constant' },
  { keyword: 'const',
    dataPath: '/countries/0/type',
    schemaPath: '#/definitions/asiaDef/properties/type/const',
    params: { allowedValue: 'asia' },
    message: 'should be equal to constant' },
  { keyword: 'oneOf',
    dataPath: '/countries/0',
    schemaPath: '#/properties/countries/items/oneOf',
    params: { passingSchemas: null },
    message: 'should match exactly one schema in oneOf' },
  { keyword: 'const',
    dataPath: '/countries/1/type',
    schemaPath: '#/definitions/europeDef/properties/type/const',
    params: { allowedValue: 'europe' },
    message: 'should be equal to constant' },
  { keyword: 'const',
    dataPath: '/countries/1/type',
    schemaPath: '#/definitions/asiaDef/properties/type/const',
    params: { allowedValue: 'asia' },
    message: 'should be equal to constant' },
  { keyword: 'oneOf',
    dataPath: '/countries/1',
    schemaPath: '#/properties/countries/items/oneOf',
    params: { passingSchemas: null },
    message: 'should match exactly one schema in oneOf' } ]

Мой вопрос в том, что, поскольку я получил эту схему, я могу в значительной степени понять ошибку. Но для третьего лица определенно понадобится некоторое время, чтобы понять это (и это может занять больше времени, если схема / ошибки более сложны).

Есть ли способ сделать его более удобным для пользователя?

1 Ответ

0 голосов
/ 08 апреля 2020

Вы можете настроить сообщения, используя ajv-errors расширение, которое позволит вам писать более качественные сообщения (или ключи для применения I18N logi c).

Это покажет, что вы установили в errorMessage

const Ajv = require('ajv')
const AjvErrors = require('ajv-errors')

const ajv = new Ajv({ allErrors: true, jsonPointers: true })
AjvErrors(ajv)

const isValid = ajv.validate(yourSchema(), {
  countries: [
    { type: 'asia1' },
    { type: 'europe1' }
  ]
})
console.log(isValid)

if (!isValid) {
  console.log(ajv.errors)
}
function yourSchema () {
  return {
    $schema: 'http://json-schema.org/draft-07/schema#',
    type: 'object',
    required: ['countries'],
    definitions: {
      europeDef: {
        type: 'object',
        required: ['type'],
        properties: { type: { const: 'europe' } },
        errorMessage: 'it must be europe'
      },
      asiaDef: {
        type: 'object',
        required: ['type'],
        properties: { type: { const: 'asia' } },
        errorMessage: 'it must be asia'
      }
    },
    properties: {
      countries: {
        type: 'array',
        errorMessage: 'should be one of asia or europe',
        items: {
          oneOf: [
            { $ref: '#/definitions/europeDef' },
            { $ref: '#/definitions/asiaDef' }
          ]
        }
      }
    }
  }
}
...