Недавно мне повезло попасть на проект бэкенд которого написан на php. А как принято у php бекэндов json с ответом они отправляют в snake case стиле. И как следствие вся работа с данными на фронте происходила в перемешку в camel case и snake case стилях. Для решения этой проблемы была доработана библиотека сериализации ts-serializable. Теперь при получении данных из json их можно приводить к принятому в js стилю camel case, а при отправке на сервер возвращать в snake case.
![ts-serializable](https://habrastorage.org/r/w1560/webt/ch/ac/97/chac97ixe2rno1c49zfobd0iuq8.png)
Так же после выхода первой версии у некоторых пользователей были пожелания по функционалу. Эти пожелания реализованы в новой версии.
Если вы не знакомы с библиотекой ts-serializable, то рекомендуется сначала прочитать эту статью.
По аналогии с Newtonsoft.Json были добавлены настройки сериализации. Их можно задать глобально, на один объект, или на один вызов десериализации.
Пример класса который будет десериализован из snake case в camel case, а при сериализации вернется в snake case.
Здесь в декоратор jsonObject передаются настройки для работы сериализации и десериализации. Так же из коробки идут KebabCaseNamingStrategy и PascalCaseNamingStrategy. Если этого не достаточно, то можно написать свой конвертер имен свойств и передать его в параметрах.
Так же можно заметить декоратор jsonName, который можно использовать на совсем специфичных именах свойств.
Настройки можно задавать в разных местах:
После выпуска первой версии библиотеки у некоторых пользователей возникла проблема с тем что наследование уже занято другим объектом. Реализовывать monkey patching не лучшая идея, к тому же расширения базового объекта в js ломает библиотеку react.
Но решение было найдено. Теперь объект можно расширить передав в декоратор jsonObject вторым параметром значение true:
Понравилась библиотека? Помоги сделать ее лучше и популярнее. Присылайте issue, ставьте звезды. Не бойтесь экспериментировать!
![ts-serializable](https://habrastorage.org/webt/ch/ac/97/chac97ixe2rno1c49zfobd0iuq8.png)
Так же после выхода первой версии у некоторых пользователей были пожелания по функционалу. Эти пожелания реализованы в новой версии.
Если вы не знакомы с библиотекой ts-serializable, то рекомендуется сначала прочитать эту статью.
Конвертация имен свойств
По аналогии с Newtonsoft.Json были добавлены настройки сериализации. Их можно задать глобально, на один объект, или на один вызов десериализации.
Пример класса который будет десериализован из snake case в camel case, а при сериализации вернется в snake case.
import { Serializable, SnakeCaseNamingStrategy, 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 SnakeCaseNamingStrategy() })
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, ставьте звезды. Не бойтесь экспериментировать!