Обзор jsonschema и шаблона DTO

JSON — это фантастический формат для работы с данными, особенно если вы уже работаете с JavaScript или TypeScript, поскольку это почти родная конструкция языка.

Я говорю «почти», потому что, хотя мы склонны смешивать их с литеральными объявлениями объектов JavaScript, они не совсем одинаковы, и, что еще хуже, когда вы имеете дело с TypeScript, разница еще больше из-за отсутствия типов. в формате JSON.

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

Давайте посмотрим на них!

Схема JSON для фанатиков JavaScript

Хорошо известно, что если вы разбираетесь в типах и JavaScript, вам, вероятно, лучше писать на TypeScript. Тем не менее, для данных в формате JSON есть решение, которое вы можете внедрить, оставаясь приверженцем чистоты JS: Схемы JSON.

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

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

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

Всего 2 объекта, ничего особенного. Вот схема, которую можно использовать для проверки формата:

Теперь вы можете видеть, откуда исходит «многословная» жалоба. Вы должны написать 18 строк определения только для проверки 2.

Давайте посмотрим на первые, со 2-й по 6-ю строки:

  • «$schema» просто указывает на используемую вами версию схемы. Это больше для сценария проверки, чтобы знать, как интерпретировать ваше определение и как применять проверку.
  • "$id" указывает URL-адрес, по которому находится этот файл.
  • «название» и «описание» носят просто описательный характер и не служат никакой цели.
  • Наконец, "тип", являющийся "объектом", означает, что вы определяете структуру объекта как часть своей схемы. Если бы вы изменили это, например, на «строку», это означало бы, что ваш JSON на самом деле должен быть простым строковым значением.

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

И последняя деталь, которую я хочу выделить здесь, — это «обязательный» ключ в строке 17. Это необязательный массив строк, каждая строка ссылается на имена ключей, которые не могут отсутствовать в вашем JSON. Если вы не добавите сюда свои ключи, это означает, что все они являются необязательными, и вы не получите сообщение об ошибке, если какой-либо из них отсутствует. Помните это.

Использование схем JSON в моем коде JS

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

Например, мы можем использовать модуль NPM json-schema-validator от Hyperjumps, который вы можете установить следующим образом:

npm install @hyperjump/json-schema

Затем нужно просто загрузить схему и вызвать правильные методы:

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

Если вы решите использовать другой пакет, убедитесь, что он может проверить последнюю версию схемы, иначе вы можете столкнуться с неожиданными ошибками. На момент написания этой статьи (2022 г.) последняя версия схемы JSON — 2020–12.

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

Если вам понравилось то, что вы прочитали до сих пор, рассмотрите возможность подписаться на мою БЕСПЛАТНУЮ рассылку Бессвязная болтовня старого разработчика и получайте регулярные советы об ИТ-отрасли прямо в свой почтовый ящик.

Как насчет TypeScript?

То, что я только что объяснил, на 100% совместимо с TypeScript. На самом деле в библиотеке, которую я использовал, даже есть определения типов для TS.

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

А поскольку в TS встроена проверка типов, нам не о чем особо беспокоиться. Учитывая конкретный JSON, если мы хотим проверить его содержимое, все, что нам нужно сделать, — это превратить его в объект, реализующий определенный класс. Тогда ТС позаботится обо всем остальном.

И для этого мы можем просто использовать шаблон DTO (объект передачи данных). По сути, DTO — это объект, который можно сериализовать на одной стороне провода и передать на другую, где его можно подобрать и превратить обратно в объект.

Если вы задумаетесь об этом на минуту, вы поймете, что все это означает, что у самого объекта нет методов (поскольку они не могут быть сериализованы, по крайней мере, тривиально). Другими словами, мы имеем дело с объектом без методов.

Это означает, что мы можем просто определить наш класс с соответствующими типами, а затем сделать что-то вроде этого:

По сути, мы определяем тип ( BookAttributes ), который указывает атрибуты и типы, которые должен иметь JSON.

Затем мы определяем наш класс DTO, который содержит один атрибут properties. Этот атрибут также имеет тип BookAttributes, и все, что мы делаем внутри конструктора, — это присваиваем ему JSON. Вот тут и происходит волшебство, выполняя это присваивание, если типы не совпадают, TypeScript будет жаловаться на это.

Вот что происходит в строке 24, поскольку myInvalidBook JSON не имеет атрибута title, а тип атрибута isbn неверен, мы получаем неприятное сообщение об ошибке:

Argument of type '{ isbn: string; }' is not assignable to parameter of type 'BookAttributes'.   Property 'title' is missing in type '{ isbn: string; }' but required in type 'BookAttributes'.

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

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

Не забудьте оставить комментарий, если вы не понимаете какой-либо из примеров или хотите попробовать что-то более сложное!

Создавайте компонуемые веб-приложения

Не создавайте веб-монолиты. Используйте Bit для создания и компоновки несвязанных программных компонентов — в ваших любимых средах, таких как React или Node. Создавайте масштабируемые и модульные приложения с мощными и приятными возможностями разработки.

Перенесите свою команду в Bit Cloud, чтобы вместе размещать компоненты и совместно работать над ними, а также ускорять, масштабировать и стандартизировать разработку в команде. Попробуйте компонуемые внешние интерфейсы с помощью Design System или Микроинтерфейсы или изучите компонуемые внутренние интерфейсы с серверными компонентами. .

Попробуйте →

Узнать больше