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, 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, ставьте звезды. Не бойтесь экспериментировать!

    Средняя зарплата в IT

    120 000 ₽/мес.
    Средняя зарплата по всем IT-специализациям на основании 9 250 анкет, за 1-ое пол. 2021 года Узнать свою зарплату
    Реклама
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее

    Комментарии 2

      0
      А можно просто насквозь во всём проекте (JS, PHP, SQL) установить только camelCase (или только snake_case) как стандарт наименования переменных.

      Мне одному вот эти вот все преобразования кажутся каким то безумием?
      Стандарты ради стандартов.
        0
        Все равно получится смешанный стиль. Потому что кроме твоего кода, есть еще апи и библиотеки в стандартном стиле.

      Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

      Самое читаемое