-
Notifications
You must be signed in to change notification settings - Fork 216
docs: excessive-entities page #865
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
fe731e3
docs: excessive-entities page
Solant 532f527
Update i18n/en/docusaurus-plugin-content-docs/current/guides/issues/e…
Solant 26bde66
docs: add bridge phrase
Solant 41cf8e2
docs: apply code review comments
Solant d04b98b
Update i18n/en/docusaurus-plugin-content-docs/current/guides/issues/e…
Solant 9becee0
Update i18n/en/docusaurus-plugin-content-docs/current/guides/issues/e…
Solant File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
116 changes: 116 additions & 0 deletions
116
i18n/en/docusaurus-plugin-content-docs/current/guides/issues/excessive-entities.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,116 @@ | ||
| # Excessive Entities | ||
|
|
||
| The `entities` layer in Feature-Sliced Design is one of the lower layers that's primarily for business logic. That makes it widely accessible — all layers except for `shared` can access it. However, its global nature means that changes to `entities` can have a widespread impact, requiring careful design to avoid costly refactors. | ||
|
|
||
| Excessive entities can lead to ambiguity (what code belongs to this layer), coupling, and constant import dilemmas (code scattered across sibling entities). | ||
|
|
||
| ## How to keep `entities` layer clean | ||
|
|
||
| ### 0. Consider having no `entities` layer | ||
|
|
||
| You might think that your application won't be Feature-Sliced if you don't include this layer, but it is completely fine for the application to have no `entities` layer. It doesn't break FSD in any way, on the contrary, it simplifies the architecture and keeps the `entities` layer available for future scaling. For example, if your application acts as a thin client, most likely it doesn't need `entities` layer. | ||
|
|
||
| :::info[What are thick and thin clients?] | ||
|
|
||
| _Thick_ vs. _thin client_ distinction refers to how the application processes data: | ||
|
|
||
| - _Thin_ clients rely on the backend for most data processing. Client-side business logic is minimal and involves only exchanging data with the backend. | ||
| - _Thick_ clients handle significant client-side business logic, making them suitable candidates for the `entities` layer. | ||
|
|
||
| Keep in mind that this classification is not strictly binary, and different parts of the same application may act as a "thick" or a "thin" client. | ||
|
|
||
| ::: | ||
|
|
||
| ### 1. Avoid preemptive slicing | ||
|
|
||
| In contrast to previous versions, FSD 2.1 encourages deferred decomposition of slices instead of preemptive, and this approach also extends to `entities` layer. At first, you can place all your code in the `model` segment of your page (widget, feature), and then consider refactoring it later, when business requirements are stable. | ||
|
|
||
| Remember: the later you move code to the `entities` layer, the less dangerous your potential refactors will be — code in Entities may affect functionality of any slice on higher layers. | ||
|
|
||
| ### 2. Avoid Unnecessary Entities | ||
|
|
||
| Do not create an entity for every piece of business logic. Instead, leverage types from `shared/api` and place logic in the `model` segment of a current slice. For reusable business logic, use the `model` segment within an entity slice while keeping data definitions in `shared/api`: | ||
|
|
||
| ```plaintext | ||
| 📂 entities | ||
| 📂 order | ||
| 📄 index.ts | ||
| 📂 model | ||
| 📄 apply-discount.ts // Business logic using OrderDto from shared/api | ||
| 📂 shared | ||
| 📂 api | ||
| 📄 index.ts | ||
| 📂 endpoints | ||
| 📄 order.ts | ||
| ``` | ||
|
|
||
| ### 3. Exclude CRUD Operations from Entities | ||
|
|
||
| CRUD operations, while essential, often involve boilerplate code without significant business logic. Including them in the `entities` layer can clutter it and obscure meaningful code. Instead, place CRUD operations in `shared/api`: | ||
|
|
||
| ```plaintext | ||
| 📂 shared | ||
| 📂 api | ||
| 📄 client.ts | ||
| 📄 index.ts | ||
| 📂 endpoints | ||
| 📄 order.ts // Contains all order-related CRUD operations | ||
| 📄 products.ts | ||
| 📄 cart.ts | ||
| ``` | ||
|
|
||
| For complex CRUD operations (e.g., atomic updates, rollbacks, or transactions), evaluate whether the `entities` layer is appropriate, but use it with caution. | ||
|
|
||
| ### 4. Store Authentication Data in `shared` | ||
|
|
||
| Prefer `shared` layer to creating a `user` entity for authentication data, such as tokens or user DTOs returned from the backend. These are context-specific and unlikely to be reused outside authentication scope: | ||
|
|
||
| - Authentication responses (e.g., tokens or DTOs) often lack fields needed for broader reuse or vary by context (e.g., private vs. public user profiles). | ||
| - Using entities for auth data can lead to cross-layer imports (e.g., `entities` into `shared`) or usage of `@x` notation, complicating the architecture. | ||
|
|
||
| Instead, store authentication-related data in `shared/auth` or `shared/api`: | ||
|
|
||
| ```plaintext | ||
| 📂 shared | ||
| 📂 auth | ||
| 📄 use-auth.ts // authenticated user info or token | ||
| 📄 index.ts | ||
| 📂 api | ||
| 📄 client.ts | ||
| 📄 index.ts | ||
| 📂 endpoints | ||
| 📄 order.ts | ||
| ``` | ||
|
|
||
| For more details on implementing authentication, see [the Authentication guide](/docs/guides/examples/auth). | ||
|
|
||
| ### 5. Minimize Cross-Imports | ||
|
|
||
| FSD permits cross-imports via `@x` notation, but they can introduce technical issues like circular dependencies. To avoid this, design entities within isolated business contexts to eliminate the need for cross-imports: | ||
|
|
||
| Non-Isolated Business Context (Avoid): | ||
|
|
||
| ```plaintext | ||
| 📂 entities | ||
| 📂 order | ||
| 📂 @x | ||
| 📂 model | ||
| 📂 order-item | ||
| 📂 @x | ||
| 📂 model | ||
| 📂 order-customer-info | ||
| 📂 @x | ||
| 📂 model | ||
| ``` | ||
|
|
||
| Isolated Business Context (Preferred): | ||
|
|
||
| ```plaintext | ||
| 📂 entities | ||
| 📂 order-info | ||
| 📄 index.ts | ||
| 📂 model | ||
| 📄 order-info.ts | ||
| ``` | ||
|
|
||
| An isolated context encapsulates all related logic (e.g., order items and customer info) within a single module, reducing complexity and preventing external modifications to tightly coupled logic. | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.