Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. JSON

Проверка данных с помощью JSON-схемы, часть 2

by
Difficulty:AdvancedLength:LongLanguages:
This post is part of a series called Validating Data With JSON-Schema.
Validating Data With JSON-Schema, Part 1

Russian (Pусский) translation by Masha Kolesnikova (you can also view the original English article)

В первой части этого урока вы узнали, как создавать довольно продвинутые схемы, используя все доступные ключевые слова проверки. Многие реальные примеры данных JSON более сложны, чем наш пользовательский пример. Попытка поставить все требования к таким данным в одном файле может привести к очень большой схеме, которая также может иметь много дублирования.

Структурирование ваших схем

Стандарт JSON-схемы позволяет разбивать схемы на несколько частей. Давайте посмотрим на пример данных для навигации по новостным сайтам:

Структура навигации выше несколько похожа на ту, которую вы можете увидеть на веб-сайте http://dailymail.co.uk. Вы можете увидеть более полный пример в репозитории GitHub.

Структура данных сложна и рекурсивна, но схемы, описывающие эти данные, довольно просты:

navigation.json:

page.json:

defs.json:

Посмотрите вышеприведенные схемы и навигационные данные, которые они описывают (что действительно в соответствии с схемой navigation.json). Главное заметить, что схема navigation.json ссылается на схему page.json, которая, в свою очередь, ссылается на первую.

Код JavaScript для проверки пользовательской записи по схеме может быть:

Все образцы кода доступны в репозитории GitHub.

Ajv, валидатор, используемый в примере, является самым быстрым механизмом проверки JSON-Schema для JavaScript. Я создал его, поэтому я собираюсь использовать его в этом уроке. Мы рассмотрим, как он в конечном итоге сравнивается с другими валидаторами, чтобы вы могли выбрать правильный для себя.

Задания

См. часть 1 учебника для получения инструкций о том, как установить репозиторий с задачами и проверить свои ответы.

Ссылки между схемами с ключевым словом «$ref»

Стандарт JSON-Schema позволяет повторно использовать повторяющиеся части схем, используя ссылки с ключевым словом «$ref». Как видно из примера навигации, вы можете ссылаться на расположенную схему:

  • в другом файле: используйте URI схемы, определенный в свойстве «id»
  • в любой части другого файла: добавьте указатель JSON к ссылке схемы
  • в любой части текущей схемы: добавьте указатель JSON к «#»,

Вы также можете обратиться ко всей текущей схеме, используя «$ref», равную «#», - это позволяет создавать рекурсивные схемы, ссылаясь на себя.

Итак, в нашем примере схема в navigation.json относится к:

  • схема page.json
  • definitions в схеме defs.json
  • определение positiveIntOrNull в той же схеме

Схема в page.json означает:

  • назад к схеме navigation.json
  • также к definitions в файле defs.json

Стандарт требует, чтобы «$ref» был единственным свойством в объекте, поэтому, если вы хотите применить ссылочную схему в дополнение к другой схеме, вы должны использовать ключевое слово «allOf».

Задание 1

Рефакторинг пользовательской схемы из части 1 учебника с использованием ссылок. Разделите схему на два файла: user.json и connection.json.

Поместите свои схемы в файлы part2/task1/user.json и part2/task1/connection.json и запустите node part2/task1/validate, чтобы проверить правильность ваших схем.

JSON-Pointer

JSON-pointer - это стандарт, определяющий пути к частям файлов JSON. Стандарт описан в RFC6901.

Этот путь состоит из сегментов (может быть любой строки), связанных с символом «/». Если сегмент содержит символы «~» или «/», их следует заменить на «~ 0» и «~ 1». Каждый сегмент означает свойство или индекс в данных JSON.

Если вы посмотрите на пример навигации, «$ref», который определяет свойство color, это “defs.json#/definitions/color” где «defs.json#» - это URI схемы, а “/definitions/color” - указатель JSON. Он указывает на цвет свойства внутри определений свойств.

Соглашение состоит в том, чтобы поместить все части схемы, которые используются в refs внутри свойства definitions схемы (как вы можете видеть в примере). Хотя стандарт JSON-схемы резервирует ключевое слово definitions для этой цели, не требуется размещать подсхемы там. JSON-pointer позволяет вам ссылаться на любую часть файла JSON.

Когда указатели JSON используются в URI, все символы, которые недопустимы в URI, должны быть экранированы (в JavaScript может использоваться глобальная функция encodeURIComponent).

JSON-указатели могут использоваться не только в JSON-схемах. Они могут использоваться для представления пути в данных JSON для любого свойства или элемента. Вы можете использовать json-указатель библиотеки для доступа к объектам с помощью указателей JSON.

Задача 2

В приведенном ниже файле JSON описывается структура папок и файлов (имена папок начинаются с «/»):

Каковы указатели JSON, которые указывают на:

  • размер приложения «Слово»,
  • размер "my_story~.rtf" документ,
  • имя второго приложения, которое может открыть «my_story~.rtf», документ?

Поместите свои ответы в part2/task2/json_pointers.json и запустите node part2/task2/validate, чтобы проверить их.

Идентификаторы схемы

Обычно схемы имеют свойство «id» верхнего уровня, которое имеет URI схемы. Когда «$ref» используется в схеме, его значение рассматривается как URI, который разрешен относительно схемы «id».

Разрешение работает так же, как браузер разрешает URI, которые не являются абсолютными, - они разрешены относительно URI схемы, который находится в свойстве «id». Если «$ref» является именем файла, он заменяет имя файла в «id». В примере навигации идентификатор схемы навигации «http://mynet.com/schemas/navigation.json#», поэтому, когда ссылка «page.json#» разрешена, полный URI схемы страницы становится «http://mynet.com/schemas/page.json#» (то есть «id» схемы page.json).

Если «$ref» схемы страницы - это путь, например. "/page.json", то он был бы разрешен как «http://mynet.com/page.json#». И «/folder/page.json» будет разрешен как «http://mynet.com/folder/page.json#».

Если «$ref» начинается с символа «#», он рассматривается как хэш-фрагмент и добавляется к пути в «id» (заменяя в нем хэш-фрагмент). В примере навигации ссылка "defs.json#/definitions/color" разрешена как "http://mynet.com/schemas/defs.json#/definitions/color" где "http://mynet.com/schemas/defs.json#" - это идентификатор схемы определений, а "definitions/color" рассматривается как указатель JSON внутри него.

Если «$ref» был полным URI с другим доменным именем, так же, как ссылки работают в браузере, он был бы разрешен как один и тот же полный URI.

Внутренние идентификаторы схемы

Стандарт JSON-схемы позволяет вам использовать «id» внутри схемы, чтобы идентифицировать эти подсхемы, а также изменить базовый URI относительно того, какие внутренние ссылки будут разрешены, - это называется «изменение области разрешения». Это, вероятно, одна из самых запутанных частей стандарта, и поэтому она не очень часто используется.

Я бы не рекомендовал чрезмерно использовать внутренние идентификаторы, с одним исключением ниже, по двум причинам:

  • Очень немногие валидаторы последовательно следуют стандарту и правильно разрешают ссылки при использовании внутренних идентификаторов (Ajv полностью соответствует стандарту здесь).
  • Схемы становятся все труднее понять.

Мы по-прежнему рассмотрим, как это работает, потому что вы можете столкнуться с схемами, использующими внутренние идентификаторы, и есть случаи, когда их использование помогает структурировать ваши схемы.

Во-первых, давайте посмотрим на наш пример навигации. Большая часть ссылок находится в объекте definitions и делает ссылки довольно длинными. Есть способ сократить их, добавив идентификаторы в определения. Это обновленная схема defs.json:

Теперь вместо ссылок "defs.json#/definitions/positiveInteger" и "defs.json#/definitions/color" которые используются в навигации и схемах страниц, вы можете использовать более короткие ссылки: "defs.json#positiveInteger" и "defs.json#color". Это очень распространенное использование внутренних идентификаторов, поскольку это позволяет сделать ваши ссылки более короткими и читаемыми. Обратите внимание, что, хотя этот простой случай будет корректно обрабатываться большинством механизмов проверки JSON-схемы, некоторые из них могут его не поддерживать.

Давайте рассмотрим более сложный пример с идентификаторами. Вот пример схемы JSON:

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

Схема определяет объект со свойствами bar, baz и bax. Свойство bar должно быть объектом, действительным в соответствии с подсхемой, которая требует, чтобы его свойство foo было действительным в соответствии с ссылкой «bar». Поскольку подсхема имеет свой собственный «id», полный URI для ссылки будет "http://somewhere.else/completely.json#bar", поэтому он должен быть целым числом.

Теперь посмотрим на свойства baz и bax. Ссылки для них написаны по-другому, но они указывают на ту же ссылку "http://somewhere.else/completely.json#bar" и оба они должны быть целыми числами. Хотя свойство baz указывает непосредственно на схему {"$ ref": "#bar"}, оно все равно должно быть разрешено относительно идентификатора подсхемы, потому что оно находится внутри него. Таким образом, приведенный ниже объект действителен в соответствии с этой схемой:

Многие валидаторы схемы JSON не будут обрабатывать их правильно, и поэтому идентификаторы, которые изменяют область разрешения, следует использовать с осторожностью.

Задача 3

Решение этой головоломки поможет вам лучше понять, как работают ссылки и изменение области разрешения. Ваша схема:

Создайте объект, действительный в соответствии с этой схемой.

Поместите свой ответ в part2/task3/valid_data.json и запустите node part2/task3/validate, чтобы проверить его.

Загрузка ссылочных схем

До сих пор мы рассматривали разные схемы, ссылаясь друг на друга, не обращая внимания на то, как они загружаются в валидатор.

Один из подходов состоит в том, чтобы все подключенные схемы были предварительно загружены, как в приведенном выше примере навигации. Но бывают ситуации, когда это либо непрактично, либо невозможно - например, если схема, которую вам нужно использовать, предоставляется другим приложением или если вы заранее не знаете все возможные схемы, которые могут потребоваться.

В таких случаях валидатор может загружать ссылки на схемы в момент проверки данных. Но это сделает процесс проверки медленным. Ajv позволяет вам скомпилировать схему в функцию проверки асинхронной загрузки отсутствующих ссылочных схем в процессе. Сама проверка будет по-прежнему синхронной и быстрой.

Например, если навигационные схемы доступны для загрузки из URI в их идентификаторах, код для проверки данных по навигационной схеме может быть следующим:

Код определяет функцию validateNavigation, которая загружает схему и компилирует функцию проверки, когда она вызывается в первый раз, и всегда возвращает результат проверки посредством обратного вызова. Существуют различные способы его улучшения, начиная с предварительной загрузки и компиляции схемы отдельно, прежде чем она будет использоваться в первый раз, для учета того факта, что функция может быть вызвана несколько раз, прежде чем она проведет кэширование схемы (ajv.compileAsync уже обеспечивает что схема всегда запрашивается только один раз).

Теперь мы рассмотрим новые ключевые слова, которые предлагаются для версии 5 стандарта JSON-схемы.

Предложения JSON-Schema Version 5

Хотя эти предложения не были доработаны в качестве стандартного проекта, они могут быть использованы сегодня - имитатор Ajv реализует их. Они существенно расширяют то, что вы можете проверить с помощью JSON-схемы, поэтому стоит их использовать.

Чтобы использовать все эти ключевые слова с Ajv, вам нужно использовать опцию v5: true.

Ключевые слова « constant» и « contains»

Эти ключевые слова добавляются для удобства.

Ключевое слово «constant» требует, чтобы данные были равны значению ключевого слова. Без этого ключевого слова это могло быть достигнуто с помощью ключевого слова «enum» с одним элементом в массиве элементов.

Эта схема требует, чтобы данные были равны 1:

Ключевое слово «contains» требует, чтобы какой-либо элемент массива соответствовал схеме в этом ключевом слове. Это ключевое слово относится только к массивам; любой другой тип данных будет действителен в соответствии с ним. Сложнее выразить это требование, используя только ключевые слова из версии 4, но это возможно.

Эта схема требует, чтобы, если данные представляют собой массив, то по крайней мере один из его элементов является целым числом:

Это эквивалентно следующему:

Для того чтобы эта схема была действительной, либо данные не должны быть массивом, либо не должны иметь все его элементы нецелыми (то есть какой-то элемент должен быть целым).

Обратите внимание, что и ключевое слово «contains», и эквивалентная схема выше не будут работать, если данные являются пустым массивом.

Ключевое слово "patternGroups"

Это ключевое слово предлагается для замены «patternProperties». Он позволяет ограничить количество свойств, соответствующих шаблону, который должен существовать в объекте. Ajv поддерживает как «patternGroups», так и «patternProperties» в режиме v5, потому что первый из них гораздо более подробный, и если вы не хотите ограничивать количество свойств, которые вы можете предпочесть, используя второй.

Например, схема:

эквивалентна этой схеме:

Они обе требуют, чтобы объект имел только свойства с ключами, состоящими только из строчных букв со значениями типа string и с ключами, состоящими только из чисел со значениями типа число. Они не требуют какого-либо количества таких свойств и не ограничивают максимальное число. Это то, что вы можете сделать с «patternGroups»:

В приведенной выше схеме есть дополнительные требования: должно быть по крайней мере одно свойство, соответствующее каждому шаблону, и не более трех свойств, ключи которых содержат только буквы.

Вы не можете достичь этого с помощью «patternProperties».

Ключевые слова для ограничения форматированных значений «formatMaximum» / «formatMaximum»

Эти ключевые слова вместе с «exclusiveFormatMaximum» / «exclusiveFormatMinimum» позволяют вам устанавливать лимиты на время, дату и потенциально другие строковые значения, которые имеют формат, необходимый для ключевого слова «format».

Эта схема требует, чтобы данные были датой, и она больше или равна 1 января 2016 года:

Ajv поддерживает сравнение форматированных данных для форматов «дата», «время» и «дата-время», и вы можете определить пользовательские форматы, которые будут поддерживать ограничения с помощью ключевых слов «formatMaximum» / «formatMaximum».

Ключевое слово "switch"

Хотя все предыдущие ключевые слова либо позволяли вам лучше выражать то, что было возможно без них, либо немного расширять возможности, они не изменяли декларативный и статический характер схемы. Это ключевое слово позволяет вам выполнять динамическую проверку и зависящую от данных. Он содержит несколько случаев if-then.

Проще объяснить на примере:

Схема выше последовательно проверяет данные против подсхем в ключевых словах «if», пока одна из них не проверит проверку. Когда это произойдет, он проверяет схему в ключе «then» в том же объекте, который будет результатом проверки всей схемы. Если значение «then» равно false, проверка немедленно прекращается.

Таким образом, приведенная выше схема требует, чтобы это значение:

  • либо больше или равно 50, и кратно 5
  • или между 10 и 49 и кратным 2
  • или между 5 и 9

Этот конкретный набор требований может быть выражен без ключевого слова switch, но есть более сложные случаи, когда это невозможно.

Задача 4

Создайте схему, эквивалентную последнему примеру выше, без использования ключевого слова switch.

Поместите свой ответ в part2/task4/no_switch_schema.json и запустите node part2/task4/validate, чтобы проверить его.

Ключевое слово «switch» также может содержать ключевое слово «continue» с логическим значением. Если это значение true, проверка будет продолжена после успешного согласования схемы «if» с успешной проверкой схемы «then». Это похоже на переход к следующему случаю в инструкции для оператора JavaScript, хотя в JavaScript провал является поведением по умолчанию, а ключевому слову «switch» требуется явная инструкция «продолжить». Это еще один простой пример с инструкцией «continue»:

Если выполняется первое условие «if» и выполняется требование «then», проверка будет продолжать проверять второе условие.

Ссылка "$data"

Ключевое слово «$data» еще больше расширяет возможности JSON-схемы и делает проверку более динамичной и зависящей от данных. Оно позволяет поместить значения из некоторых свойств данных, элементов или ключей в определенные ключевые слова схемы.

Например, эта схема определяет объект с двумя свойствами, где, если оба определены, «больше» должно быть больше или равно «меньше» - значение «меньше» используется как минимум для «большего»:

Ajv реализует ссылку «$data» для большинства ключевых слов, значения которых не являются схемами. Он не выполняет проверку, если ссылка «$data» указывает на неправильный тип и преуспевает, если она указывает на неопределенное значение (или если путь не существует в объекте).

Итак, что такое строковое значение в ссылке «$data»? Он похож на JSON-указатель, но это не совсем так. Это относительный JSON-указатель, который определяется этим стандартом.

Он состоит из целого числа, которое определяет, сколько раз поиск должен пересекать объект (1 в приведенном выше примере означает прямой родительский элемент), за которым следует указатель «#» или JSON.

Если за номером следует «#», то значение JSON-указателя будет разрешено как имя свойства или индекс элемента, который имеет объект. Таким образом, «0#» вместо «1/smaller» будет разрешать строку « larger», а «1#» будет недопустимой, так как все данные не являются членами какого-либо объекта или массива. Эта схема:

эквивалентно этому:

потому что {"$ data": "0 #"} заменяется именем свойства.

Если за номером в указателе следует указатель JSON, то этот JSON-указатель разрешен, начиная с родительского объекта, к которому относится этот номер. Вы можете увидеть, как это работает в первом примере « smaller» / « larger».

Давайте снова посмотрим на наш пример навигации. Одним из требований, которые вы можете видеть в данных, является то, что свойство page_id в объекте страницы всегда равно свойству parent_id в содержащемся навигационном объекте. Мы можем выразить это требование в схеме page.json, используя ссылку «$data»:

Ключевое слово «switch», добавленное в схему страницы, требует, чтобы, если объект страницы имеет свойство navigation, значение свойства page_id должно быть таким же, как значение свойства parent_id в объекте навигации. То же самое можно достичь без ключевого слова «switch», но оно менее выразительно и содержит дублирование:

Задача 5

Примеры относительных JSON-указателей могут быть полезны.

Используя ключевые слова v5, определите схему для объекта с двумя требуемыми свойствами list и order. Список должен быть массивом, который имеет до пяти номеров. Все элементы должны быть номерами, и их следует заказывать в порядке возрастания или убывания, как определено свойством order, которое может быть «asc» или «desc».

Например, это действительный объект:

и это недействительно:

Поместите свой ответ в part2/task5/schema.json и запустите node part2/task5/validate, чтобы проверить его.

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

Определение новых ключевых слов проверки

Мы рассмотрели новые ключевые слова, которые предлагаются для версии 5 стандарта JSON-схемы. Вы можете использовать их сегодня, но иногда вам может понадобиться больше. Если вы выполнили задачу 5, вы, вероятно, заметили, что некоторые требования трудно выразить с помощью JSON-схемы.

Некоторые валидаторы, включая Ajv, позволяют вам определять настраиваемые ключевые слова. Пользовательские ключевые слова:

  • позволяют создавать сценарии проверки, которые не могут быть выражены с помощью JSON-Schema
  • упростить ваши схемы
  • помочь вам привести большую часть логики проверки к вашим схемам
  • сделать ваши схемы более выразительными, менее подробными и ближе к области вашего приложения

Один из разработчиков, который использует Ajv, написал в GitHub:

«Ajv с пользовательскими ключевыми словами очень помог нам с проверкой бизнес-логики на нашем бэкэнде. Мы объединили целую кучу проверок уровня контроллера в JSON-Schema с пользовательскими ключевыми словами. Чистый эффект намного лучше, чем писать индивидуальный код проверки ».

Озабоченность, которую вы должны учитывать при расширении стандарта JSON-схемы с помощью настраиваемых ключевых слов, - это переносимость и понимание ваших схем. Вам нужно будет поддерживать эти настраиваемые ключевые слова на других платформах и правильно документировать эти ключевые слова, чтобы каждый мог понять их в ваших схемах.

Лучшим подходом здесь является определение новой мета-схемы, которая будет расширять мета-схему метаструктуры проекта 4 или метаданных предложений «v5 предложений», которая будет включать как проверку ваших дополнительных ключевых слов, так и их описание. Затем ваши схемы, которые используют эти настраиваемые ключевые слова, должны будут установить свойство $schema в URI новой мета-схемы.

Теперь, когда мы вас предупредили, мы погрузимся и определим пару пользовательских ключевых слов, используя Ajv.

Ajv предоставляет четыре способа определения пользовательских ключевых слов, которые вы можете видеть в документации. Мы рассмотрим два из них:

  • используя функцию, которая компилирует вашу схему в функцию проверки
  • используя макрофункцию, которая принимает вашу схему и возвращает другую схему (с или без настраиваемых ключевых слов)

Начнем с простого примера ключевого слова range. Диапазон - это просто сочетание минимальных и максимальных ключевых слов, но если вам нужно определить многие диапазоны в вашей схеме, особенно если они имеют исключительные границы, это может легко стать скучным.

Вот как должна выглядеть схема:

где, конечно, range будет опциональным. Код для определения этого ключевого слова приведен ниже:

Вот и все! После этого кода вы можете использовать ключевое слово range в своих схемах:

Объект, переданный addKeyword, является определением ключевого слова. Он необязательно содержит тип (или тип как массив), к которому относится ключевое слово. Функция компиляции вызывается с помощью параметров schema и parentSchema и должна возвращать другую функцию, которая проверяет данные. Это делает его почти таким же эффективным, как и собственные ключевые слова, потому что схема анализируется во время ее компиляции, но во время проверки есть стоимость дополнительного вызова функции.

Ajv позволяет избежать этих накладных расходов с ключевыми словами, которые возвращают код (как строку), который будет включен в функцию проверки, но он довольно сложный, поэтому мы не будем рассматривать его здесь. Более простой способ - использовать макрокоманды - вам нужно будет определить функцию, которая принимает схему и возвращает другую схему.

Ниже приведена реализация ключевого слова range с функцией макроса:

Вы можете видеть, что функция просто возвращает новую схему, эквивалентную ключевому слову range, который использует ключевые слова maximum и minimum.

Давайте также посмотрим, как мы можем создать мета-схему, которая будет включать ключевое слово range. Мы будем использовать мета-схему проекта 4 в качестве отправной точки:

Если вы хотите использовать ссылки «$data» с ключевым словом range, вам придется расширить мета-схему предложений «v5», которая включена в Ajv (см. Ссылку выше), чтобы эти ссылки могли быть значениями range и exclusiveRange , И хотя наша первая реализация не будет поддерживать ссылки «$data», вторая с макрофункцией будет поддерживать их.

Теперь, когда у вас есть мета-схема, вам нужно добавить ее в Ajv и использовать ее в схемах с использованием ключевого слова range:

В приведенном выше коде было бы исключение, если недопустимые значения были переданы в range или exclusiveRange.

Задача 6

Предположим, что вы определили ключевое слово jsonPointers, которое применяет схемы к глубоким свойствам, определенным указателями JSON, которые указывают на данные, начиная с текущего. Это ключевое слово полезно с ключевым словом switch, поскольку оно позволяет вам определять требования к глубоким свойствам и элементам. Например, эта схема с использованием ключевого слова jsonPointers:

эквивалентно:

Предположим, что вы также определили ключевое слово requiredJsonPointers, которое работает аналогично required, но с JSON-указателями вместо свойств.

Если вам нравится, вы можете сами определить эти ключевые слова, или вы можете увидеть, как они определены в файле part2/task6/json_pointers.js.

Ваша задача: использовать ключевые слова jsonPointers и requiredJsonPointers, определить ключевое слово select, аналогичный оператору switch JavaScript, и синтаксис ниже (otherwise и fallthrough необязательны):

Этот синтаксис позволяет использовать значения любого типа. Обратите внимание, что fallthrough отличается от continue в ключевом слове switch. fallthrough применяет схему из следующего случая к данным, не проверяя, что селектор равен значению из следующего случая (поскольку он, скорее всего, не равен).

Поместите свои ответы в part2/task6/select_keyword.js и part2/task6/v5-meta-with-select.json и запустите node part2/task6/validate, чтобы проверить их.

Бонус 1: улучшите свою реализацию, чтобы также поддерживать этот синтаксис:

Он может использоваться, если все значения являются разными строками, и нет fallthrough.

Бонус 2: добавьте мета-схему предложений «v5 предложений», чтобы включить это ключевое слово.

Другие применения JSON-схем

Помимо проверки данных, JSON-схемы могут использоваться для:

  • generate UI
  • генерировать данные
  • изменять данные

Вы можете посмотреть библиотеки, которые генерируют пользовательский интерфейс и данные, если вы заинтересованы. Мы не будем изучать его, так как он выходит за рамки данного руководства.

Мы рассмотрим использование JSON-схемы для изменения данных во время проверки.

Фильтрация данных

Одной из распространенных задач при проверке данных является удаление дополнительных свойств из данных. Это позволяет вам дезинфицировать данные перед их передачей в логику обработки без проверки валидации схемы:

Без опции removeAdditional проверка не удалась бы, так как есть дополнительное свойство bar, которое не допускается схемой. С помощью этой опции выполняется проверка и свойство удаляется из объекта.

Когда значение параметра removeAdditional равно true, дополнительные свойства удаляются, только если ключевое слово extraProperties является ложным. Ajv также позволяет удалить все дополнительные свойства, независимо от ключевого слова AdditionalProperties, или дополнительных свойств, которые не позволяют выполнить проверку (если ключевое слово AdditionalProperties является схемой). Дополнительную информацию см. в документации Ajv.

Присвоение значений по умолчанию свойствам и элементам

Стандарт JSON-схемы определяет ключевое слово «default», которое содержит значение, которое должны иметь данные, если оно не определено в проверенных данных. Ajv позволяет назначать такие значения по умолчанию в процессе проверки:

Без опции useDefaults проверка не прошла бы, поскольку в проверяемом объекте не было требуемого свойства bar. С помощью этой опции выполняется проверка и добавляется свойство со значением по умолчанию.

Типы данных

«type» является одним из наиболее часто используемых ключевых слов в JSON-схемах. Когда вы проверяете входные данные пользователя, все ваши свойства данных, которые вы получаете из форм, обычно являются строками. Ajv позволяет вам принуждать данные к типам, указанным в схеме, как для прохождения проверки, так и для использования правильно введенных данных:

Сравнение JavaScript JSON-Schema Validators

Доступно более десяти активно поддерживаемых JavaScript-валидаторов. Какой из них вы должны использовать?

Вы можете увидеть контрольные показатели производительности и того, как различные валидаторы передают набор тестов из стандарта JSON-схемы в проект json-schema-benchmark.

Существуют также отличительные особенности, которые некоторые валидаторы имеют, что может сделать их наиболее подходящими для вашего проекта. Я сравню некоторые из них ниже.

is-my-json-valid и jsen

Эти два валидатора очень быстрые и имеют очень простые интерфейсы. Они компилируют схемы для функций JavaScript, как это делает Ajv.

Их недостатком является то, что они оба имеют ограниченную поддержку удаленных ссылок.

schemasaurus

Это единственная в своем роде библиотека, где проверка JSON-схемы почти является побочным эффектом.

Он построен как универсальный и легко расширяемый процессор / итератор JSON-схемы, который можно использовать для создания всех видов инструментов, которые используют JSON-схему: генераторы UI, шаблоны и т.д.

В него уже включен относительно быстрый механизм проверки JSON-схемы.

Однако он не поддерживает удаленные ссылки.

themis

Самый медленный в группе быстрых валидаторов, он имеет полный набор функций с ограниченной поддержкой удаленных ссылок.

Там, где он действительно сияет, это реализация ключевого слова default. Хотя большинство валидаторов имеют ограниченную поддержку этого ключевого слова (Ajv не является исключением), Themis имеет очень сложную логику применения умолчаний с откатами внутри составных ключевых слов, таких как anyOf.

z-schema

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

Он проходит почти все тесты из набора тестов JSON-схемы для валидаторов, и он имеет довольно тщательную реализацию удаленных ссылок.

Он имеет большой набор опций, позволяющий настроить поведение по умолчанию многих ключевых слов JSON (например, не принимать пустые массивы в виде массивов или пустых наборов строк) и накладывать дополнительные требования к схемам JSON (например, для этого требуется ключевое слово minLength для строк).

Я думаю, что в большинстве случаев изменение поведения схемы и включение других сервисов в схему JSON - это неправильные вещи. Но бывают случаи, когда способность делать это упрощает многое.

TV4

Это один из старейших (и самых медленных) валидаторов, поддерживающих версию 4 стандарта. Таким образом, это часто выбор по умолчанию для многих проектов.

Если вы используете его, очень важно понять то, как он сообщает об ошибках и недостающих ссылках и правильно их настраивает, иначе вы получите много ложных срабатываний (т. е. проверка прошла с недопустимыми данными или нерешенными удалёнными ссылками).

Форматы не включены по умолчанию, но они доступны как отдельная библиотека.

Ajv

Я написал Ajv, потому что все существующие валидаторы были либо быстрыми, либо совместимыми со стандартом (особенно в отношении поддержки удаленных ссылок), но не одновременно. Ajv заполнил этот пробел.

На данный момент это единственный валидатор, который:

  • проходит все тесты и полностью поддерживает удаленные ссылки
  • поддерживает ключевые слова проверки, предложенные для версии 5 стандартных и ссылки $data.
  • поддерживает асинхронную проверку пользовательских форматов и ключевых слов

Он имеет опции для изменения процесса проверки и изменения проверенных данных (фильтрация, назначение значений по умолчанию и типов принуждения - см. примеры выше).

Какой валидатор использовать?

Я думаю, что лучший подход - попробовать несколько и выбрать тот, который лучше всего подходит для вас.

Я написал json-schema-consolidate, который предоставляет коллекцию адаптеров, которые унифицируют интерфейсы 12 валидаторов JSON-схемы. Используя этот инструмент, вы можете тратить меньше времени на переключение между валидаторами. Я рекомендую удалить его, как только вы решите, какой валидатор использовать, поскольку его сохранение отрицательно скажется на производительности.

Все! Надеюсь, этот учебник был полезен. Вы узнали о:

  • структурировани ваших схем
  • использовании ссылок и идентификаторов
  • использовании ключевых слов для проверки и ссылок $data из предложений версии 5
  • загрузке асинхронных удаленных схем
  • определении пользовательских ключевых слов
  • изменении данных в процессе проверки
  • преимуществах и недостатках различных валидаторов JSON-схемы

Спасибо за прочтение!

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.