Недавно мне повезло попасть на проект бэкенд которого написан на php. А как принято у php бекэндов json с ответом они отправляют в snake case стиле. И как следствие вся работа с данными на фронте происходила в перемешку в camel case и snake case стилях. Для решения этой проблемы была доработана библиотека сериализации ts-serializable. Теперь при получении данных из json их можно приводить к принятому в js стилю camel case, а при отправке на сервер возвращать в snake case.
Так же после выхода первой версии у некоторых пользователей были пожелания по функционалу. Эти пожелания реализованы в новой версии.
Если вы не знакомы с библиотекой ts-serializable, то рекомендуется сначала прочитать эту статью.
По аналогии с Newtonsoft.Json были добавлены настройки сериализации. Их можно задать глобально, на один объект, или на один вызов десериализации.
Пример класса который будет десериализован из snake case в camel case, а при сериализации вернется в snake case.
Здесь в декоратор jsonObject передаются настройки для работы сериализации и десериализации. Так же из коробки идут KebabCaseNamingStrategy и PascalCaseNamingStrategy. Если этого не достаточно, то можно написать свой конвертер имен свойств и передать его в параметрах.
Так же можно заметить декоратор jsonName, который можно использовать на совсем специфичных именах свойств.
Настройки можно задавать в разных местах:
После выпуска первой версии библиотеки у некоторых пользователей возникла проблема с тем что наследование уже занято другим объектом. Реализовывать monkey patching не лучшая идея, к тому же расширения базового объекта в js ломает библиотеку react.
Но решение было найдено. Теперь объект можно расширить передав в декоратор jsonObject вторым параметром значение true:
Понравилась библиотека? Помоги сделать ее лучше и популярнее. Присылайте issue, ставьте звезды. Не бойтесь экспериментировать!
Так же после выхода первой версии у некоторых пользователей были пожелания по функционалу. Эти пожелания реализованы в новой версии.
Если вы не знакомы с библиотекой 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, ставьте звезды. Не бойтесь экспериментировать!
Rastishka
А можно просто насквозь во всём проекте (JS, PHP, SQL) установить только camelCase (или только snake_case) как стандарт наименования переменных.
Мне одному вот эти вот все преобразования кажутся каким то безумием?
Стандарты ради стандартов.
LabEG Автор
Все равно получится смешанный стиль. Потому что кроме твоего кода, есть еще апи и библиотеки в стандартном стиле.