Как я могу скомпилировать подмножество JSON схемы с Ajv? - PullRequest
1 голос
/ 28 января 2020

Мне нужно следующее JSON Схема:

{
  "type": "object",
  "required": [
    "type",
    "title"
  ],
  "properties": {
    "type": {
      "enum": [
        "journal",
        "book",
        "generic"
      ]
    },
    "title": {
      "type": "string",
      "minLength": 1,
      "maxLength": 500
    }
  }
}

В соответствии с этой схемой действителен следующий объект:

{type: 'journal', title: 'foo'}

А это не так:

{type: 'qux', title: ''}

Есть ли способ, которым я могу повторно использовать подмножества этой схемы, чтобы я мог также проверять типы и заголовки индивидуально?

например (в псевдокоде)

const Ajv = require('ajv');
const ajv = new Ajv;

ajv.addSchema(/* see schema above */);

const validate_document = ajv.compile(/* see schema above */);
const validate_type = ajv.compile(/* reuse corresponding subset */);
const validate_title = ajv.compile(/* reuse corresponding subset */);

validate_document({type: 'qux', title: ''}); // false
validate_type('qux'); // false
validate_title(''); // false

1 Ответ

0 голосов
/ 28 января 2020

Я остановился на этом решении, которое позволяет мне сохранять «целостность» схемы (мне не нужно разбивать ее на более мелкие части, чтобы ее было легко читать и понимать). Все, что мне нужно было сделать, это установить $id ключи в соответствующих схемах:

{
  "$id": "document",          <-- id for the whole schema
  "type": "object",
  "required": [
    "type",
    "title"
  ],
  "properties": {
    "type": {
      "$id": "document-type", <-- id for the type schema
      "enum": [
        "journal",
        "book",
        "generic"
      ]
    },
    "title": {
      "$id": "document-title", <-- id for the title schema
      "type": "string",
      "minLength": 1,
      "maxLength": 500
    }
  }
}

Ajv позволяет ссылаться на схему по ее идентификатору в Ajv#getSchema, который компилирует схему в функцию проверки:

const validate_document = ajv.getSchema('document');
const validate_type = ajv.getSchema('document-type');
const validate_title = ajv.getSchema('document-title');

console.log(
    'Is {type: "journal", title: "foo"} valid? '
  , validate_document({type: "journal", title: "foo"})
); // true

console.log(
    'Is "qux" a valid document type? '
  , validate_type("qux")
); // false

console.log(
    'Is "journal" a valid document type? '
  , validate_type("journal")
); // true

console.log(
    'Is "" a valid document title? '
  , validate_title("")
); // false

console.log(
    'Is "foo" a valid document title? '
  , validate_title("foo")
); // true
<script src="https://cdnjs.cloudflare.com/ajax/libs/ajv/6.11.0/ajv.min.js"></script>
<script>
const ajv = new Ajv;

ajv.addSchema({
  "$id": "document",
  "type": "object",
  "required": [
    "type",
    "title"
  ],
  "properties": {
    "type": {
      "$id": "document-type",
      "enum": [
        "journal",
        "book",
        "generic"
      ]
    },
    "title": {
      "$id": "document-title",
      "type": "string",
      "minLength": 1,
      "maxLength": 500
    }
  }
});

</script>
...