Тестовое задание на Angular. Создание базовых интерфейсов.
В данной статье рассмотрим создание интерфейсов для сущностей, которые будут использованы в приложении. Рассмотрим концепт DTO-Entity-Model на примере реализации Room
, Building
и Person
.
Для того, чтобы забронировать номер (room
), нужно на карте выбрать подходящий вариант и кликнуть забронировать. Каждая комната принадлежит какому-то зданию (building
), где здание имеет какого-то собственника (person
).
Интерфейс person
в person/common/person.interface.ts
:
Концепт DTO-Entity-Model
Каждая сущность (что-то полученное извне, например, данные с сервера) может быть разложена на 3 базовых типа:
DTO
(Data Transfer Object) — объект получаемый с backend’а или внешнего сервиса. DTO никогда не переопределяется и всегда соответствует response’у сервераEntity
— обеъкт, который получается из DTO, который в дальнейшем будет сохранен в хранилище Redux’а. Entity обладает рядом новых свойств, которые необходимы для работы приложения.Model
— объект, который наследуется от Entity и добавляет ряд свойств, которые не должны быть сохранены в хранилище. Примером сущности может быть реализация дат. Например с сервера, возвращается поле created — которое содержит дату создания сущности, в виде строки. Для того, чтобы всегда иметь свойство типа Date, можно у модели создать новое поле — createdDate: Date и его заполнять в момент получения из хранилища Redux.
Важно отметить, что все трансформации происходят на уровне State’а. В частности, вызывается события загрузки сущностей. Сущности возвращаются в виде DTO и на их основе создаются Entity
. После того, как сущности созданы и сохранены в state’е, они могут быть запрошены. И при запросе уже загруженной сущности из хранилища, она приводится к Модели, в которой добавляются те или иные характеристики.
Из примера выше, мы имеем PersonDdo
:
export interface PersonDto {
readonly id: number;
readonly firstName: string;
readonly lastName: string;
readonly middleName: string | null;
readonly phone: string;
readonly buildings: number[];
readonly avatar?: string;
readonly created: string;
readonly updated: string;
}
На его основе создается PersonEntity
:
export interface PersonEntity {
id: number;
firstName: string;
lastName: string;
middleName: string | null;
phone: string;
buildings: number[];
avatar?: string;
created: string;
updated: string;
personRemoveRun: boolean;
personRemoveError: Record<string, any> | null;
personChangeRun: boolean;
personChangeError: Record<string, any> | null;
personBuildingRemoveRun: boolean;
personBuildingRemoveError: Record<string, any> | null;
personBuildingAddRun: boolean;
personBuildingAddError: Record<string, any> | null;
}
Как видно из примера, в entity
есть ряд полей, которые будут использоваться в state, в частности поля:
personRemoveRun: boolean;
personRemoveError: Record<string, any> | null;
personChangeRun: boolean;
personChangeError: Record<string, any> | null;
personBuildingRemoveRun: boolean;
personBuildingRemoveError: Record<string, any> | null;
personBuildingAddRun: boolean;
personBuildingAddError: Record<string, any> | null;
И уже на основании PersonEntity
создается модель Person
:
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface Person extends PersonEntity {}
Которая в данном случае просто совпадает с PersonEntiy
.
Остальные интерфейсы и константы из person.interface.ts будут рассмотрены в следующих статьях.
Аналогично добавим интерфейсы для Building
в building/common/building.interface.ts
:
Интерфейс Room
в room/commin/room.interface.ts
:
Отметим, что в реализации мы не ссылаемся на сущности в описании интерфейсов, а только на их ID. Это необходимо для того, чтобы не было цикличных редиректов, а также поможет использовать реляционность, для более простой работы (по аналогии с базами данных). Все данные будут представлены набором справочников (persons, builidings, rooms), где person может иметь несколько зданий, а каждое здание имеет одну или более комнат.
Ссылки
Вернуться к оглавлению — Введение.
Следующая статья — Установка redux и создание root store.
Предыдущая статья — Создание модулей и компонентов.
Все исходники на github/fafnur/barinb.
Группа в Medium: https://medium.com/fafnur
Группа в Vkontakte: https://vk.com/fafnur
Группа в Facebook: https://www.facebook.com/groups/fafnur/
Telegram канал: https://t.me/f_a_f_n_u_r
Twitter: https://twitter.com/Fafnur1
LinkedIn: https://www.linkedin.com/in/fafnur