TS-Serializable 2: с конвертации свойств из snake case и декоратором вместо наследования

от автора

Недавно мне повезло попасть на проект бэкенд которого написан на php. А как принято у php бекэндов json с ответом они отправляют в snake case стиле. И как следствие вся работа с данными на фронте происходила в перемешку в camel case и snake case стилях. Для решения этой проблемы была доработана библиотека сериализации ts-serializable. Теперь при получении данных из json их можно приводить к принятому в js стилю camel case, а при отправке на сервер возвращать в snake case.

ts-serializable

Так же после выхода первой версии у некоторых пользователей были пожелания по функционалу. Эти пожелания реализованы в новой версии.

Если вы не знакомы с библиотекой ts-serializable, то рекомендуется сначала прочитать эту статью.

Конвертация имен свойств

По аналогии с Newtonsoft.Json были добавлены настройки сериализации. Их можно задать глобально, на один объект, или на один вызов десериализации.

Пример класса который будет десериализован из snake case в camel case, а при сериализации вернется в snake case.

import { Serializable, SnackCaseNamingStrategy, jsonObject, jsonProperty, jsonName } from "ts-serializable";  const json = {     first_name: "Jack",     last_name: "Sparrow",     date_of_birth: "1690-05-05T21:29:43.000Z",     "very::strange::json:name": "I love jewelry" };  @jsonObject({ namingStrategy: new SnackCaseNamingStrategy() }) class User extends Serializable {      @jsonProperty(String, null)     public firstName: string | null = null;      @jsonProperty(String, null)     public lastName: string | null = null;      @jsonProperty(Date, null)     public dateOfBirth: Date | null = null;      @jsonName("very::strange::json:name")     @jsonProperty(String, null)     public veryStrangePropertyName: string | null = null;  }  const user = new User().fromJSON(json);  user.firstName === json.first_name; // true user.lastName === json.last_name; // true user.dateOfBirth?.toISOString() === json.date_of_birth; // true user.veryStrangePropertyName === json["very::strange::json:name"]; // true 

Здесь в декоратор jsonObject передаются настройки для работы сериализации и десериализации. Так же из коробки идут KebabCaseNamingStrategy и PascalCaseNamingStrategy. Если этого не достаточно, то можно написать свой конвертер имен свойств и передать его в параметрах.

Так же можно заметить декоратор jsonName, который можно использовать на совсем специфичных именах свойств.

Указание настроек

Настройки можно задавать в разных местах:

  • Глобально. Настройки будут применяться на всех объектах, если они не переопределены в объекте или методе.
  • На объект. Настройки будут применяться на одном объекте, если они не переопределены в методе.
  • На один метод. Настройки будут применяться на одном вызове десериализации и не работают при сериализации.

// Глобальные настройки Serializable.defaultSettings: SerializationSettings = { ...options };  // Настройки для объекта @jsonObject(settings?: Partial<SerializationSettings>) class User extends Serializable { ...code }  // Настройка для одной десериализации new User().fromJSON(json: object, settings?: Partial<SerializationSettings>); 

Декоратор вместо наследования

После выпуска первой версии библиотеки у некоторых пользователей возникла проблема с тем что наследование уже занято другим объектом. Реализовывать monkey patching не лучшая идея, к тому же расширения базового объекта в js ломает библиотеку react.

Но решение было найдено. Теперь объект можно расширить передав в декоратор jsonObject вторым параметром значение true:

 @jsonObject(void 0, true) // расширит объект class User {      public fromJSON!: (json: object) => this; // успокоит typescript      @jsonProperty(String, null)     public firstName: string | null = null;      @jsonProperty(String, null)     public lastName: string | null = null;  } 

Поддержка

Понравилась библиотека? Помоги сделать ее лучше и популярнее. Присылайте issue, ставьте звезды. Не бойтесь экспериментировать!

ссылка на оригинал статьи https://habr.com/ru/post/502290/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *