Skip to content

Commit

Permalink
Rewrite the Entities section too
Browse files Browse the repository at this point in the history
  • Loading branch information
illright committed Aug 3, 2024
1 parent 5205f15 commit 8b0e279
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -65,35 +65,17 @@ You are free to add more segments, but make sure that the name of these segments

### Entities

Concepts from the real world that form together the essence of the project. Commonly, these are the terms that the business uses to describe the product.
Slices on this layer represent concepts from the real world that the project is working with. Commonly, they are the terms that the business uses to describe the product. For example, a social network might work with business entities like User, Post, and Group.

Slices in this layer typically contain static UI elements, data stores, and optionally, CRUD operations.
An entity slice might contain the data storage (`📁 model`), data validation schemas (`📁 model`), entity-related API request functions (`📁 api`), as well as the visual representation of this entity in the interface (`📁 ui`). The visual representation doesn't have to produce a complete UI block — it is primarily meant to reuse the same appearance across several pages in the app, and different business logic may be attached to it through props or slots.

**Slice examples**:
#### Entity relationships

<table>
<thead><tr><th> For a social network </th><th> For a Git frontend (e.g., GitHub) </th></tr></thead>
<tbody><tr><td><ul>
<li>User</li>
<li>Post</li>
<li>Group</li>
</ul></td><td><ul>
<li>Repository</li>
<li>File</li>
<li>Commit</li>
</ul></td></tr></tbody></table>
Entities in FSD are slices, and by default, slices cannot know about each other. In real life, however, entities often interact with each other, and sometimes one entity owns or contains other entities. Because of that, the business logic of these interactions is best kept in higher layers, like Features or Pages.

When one entity's data object contains other data objects, usually it's a good idea to make the connection between the entities explicit and side-step the slice isolation by making a cross-reference API with the `@x` notation. The reason is that connected entities need to be refactored together, so it's best to make the connection impossible to miss.

:::tip

You may notice in the example of a Git frontend that a _repository_ contains _files_. This makes the repository a higher-level entity which has other entities nested inside. That is a common situation with entities, and sometimes it's hard to manage such higher-level entities without breaking the import rule on layers.

Here are a few suggestions to overcome this issue:
* The UI of entities should contain slots for places where the lower-level entities are to be inserted
* The business logic related to entity interaction should be placed in features (most of the time)
* The typings of database entities can be extracted to the Shared layer below, next to the API client

:::
TODO: Add a link to the cross-reference API documentation.

### Features

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,35 +65,17 @@ pagination_next: reference/slices-segments

### Entities

Понятия из реального мира, которые вместе образуют суть проекта. Как правило, это термины, которые бизнес использует для описания продукта.
Слайсы на этом слое представляют концепции из реального мира, с которыми работает проект. Обычно это термины, которые бизнес использует для описания продукта. Например, социальная сеть может работать с бизнес-сущностями, такими как Пользователь, Публикация и Группа.

Слайсы на этом слое обычно содержат статические элементы пользовательского интерфейса, хранилища данных и, опционально, операции CRUD (создание-чтение-изменение-удаление).
Слайс сущности может содержать хранилище данных (`📁 model`), схемы валидации данных (`📁 model`), функции запросов API, связанные с сущностями (`📁 api`), а также визуальное представление этой сущности в интерфейсе (`📁 ui`). Это визуальное представление не обязательно должно создавать полный блок пользовательского интерфейса — оно в первую очередь предназначено для переиспользования одного и того же внешнего вида на нескольких страницах приложения, и к нему может быть присоединена различная бизнес-логика через пропы или слоты.

**Примеры слайсов**:
#### Связи между сущностями

<table>
<thead><tr><th> Для социальной сети </th><th> Для Git-фронтенда (например, GitHub) </th></tr></thead>
<tbody><tr><td><ul>
<li>Пользователь</li>
<li>Публикация</li>
<li>Группа</li>
</ul></td><td><ul>
<li>Репозиторий</li>
<li>Файл</li>
<li>Коммит</li>
</ul></td></tr></tbody></table>
Сущности в FSD являются слайсами, и по умолчанию слайсы не могут знать друг о друге. Однако в реальной жизни сущности часто взаимодействуют друг с другом, и иногда одна сущность владеет или содержит другие сущности. Из-за этого бизнес-логику этих взаимодействий лучше всего хранить на более высоких уровнях, таких как Features или Pages.

Когда объект данных одной сущности содержит другие объекты данных, обычно хорошей идеей является сделать связь между сущностями явной и обойти изоляцию слайсов, создав API для кросс-ссылок через `@x`-нотацию. Причина в том, что связанные сущности должны рефакториться вместе, поэтому лучше сделать так, чтоб связь было невозможно не заметить.

:::tip

Вы можете заметить в примере фронтенда для Git, что _репозиторий_ содержит _файлы_. Это делает репозиторий сущностью более высокого уровня, внутри которой вложены другие сущности. Это частая ситуация с сущностями, и иногда трудно иметь такие сущности высокого уровня, не нарушая правило импортов для слоёв.

Вот несколько предложений по решению этой проблемы:
* UI сущностей должен содержать слоты для мест, куда будут вставляться сущности нижнего уровня
* Бизнес-логика, связанная с взаимодействием сущностей, должна быть размещена в Features (в большинстве случаев)
* Интерфейсы сущностей из базы данных могут быть извлечены в слой Shared, рядом с API-клиентом

:::
TODO: Добавить ссылку на документацию API для кросс-ссылок.

### Features

Expand Down

0 comments on commit 8b0e279

Please sign in to comment.