From fe731e3895ca842723808dbb18be5f5814eedac3 Mon Sep 17 00:00:00 2001 From: Solant Date: Fri, 3 Oct 2025 12:41:48 +0200 Subject: [PATCH 1/4] docs: excessive-entities page --- .../guides/issues/excessive-entities.md | 98 +++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 i18n/en/docusaurus-plugin-content-docs/current/guides/issues/excessive-entities.md diff --git a/i18n/en/docusaurus-plugin-content-docs/current/guides/issues/excessive-entities.md b/i18n/en/docusaurus-plugin-content-docs/current/guides/issues/excessive-entities.md new file mode 100644 index 000000000..813e66cfa --- /dev/null +++ b/i18n/en/docusaurus-plugin-content-docs/current/guides/issues/excessive-entities.md @@ -0,0 +1,98 @@ +# Excessive Entities + +The entities layer in Feature-Sliced Design is the first layer that incorporates business logic, distinguishing it from the `shared` layer. Unlike the `model` segment, it is globally accessible (except by `shared`), making it reusable across the application. However, its global nature means changes can have a widespread impact, requiring careful design to avoid costly refactors. + +## How to keep `entities` layer clean + +To keep a maintainable `entities` layer, consider the following principles based on the application's data processing needs. Keep in mind that this classification is not strictly binary, as different parts of the same application may have β€œthin” or β€œthick” parts: + +- Thin Clients: These applications rely on the backend for most data processing. They often do not require an `entities` layer, as client-side business logic is minimal and involves only data retrieval. +- Thick Clients: These handle significant client-side business logic, making them suitable candidates for the `entities` layer. + +It is acceptable for an application to lack an `entities` layer if it functions as a thin client. This simplifies the architecture and keeps the `entities` layer available for future scaling if needed. + +### 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 +``` + +### 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. + +### Store Authentication Data in `shared` + +Avoid 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: + +- 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 // Hook returning authenticated user info or token + πŸ“„ index.ts + πŸ“‚ api + πŸ“„ client.ts + πŸ“„ index.ts + πŸ“‚ endpoints + πŸ“„ order.ts +``` + +### 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. From 532f5278df27db0058b9edab70ce7ada0635605f Mon Sep 17 00:00:00 2001 From: Solant Date: Tue, 18 Nov 2025 16:49:27 +0100 Subject: [PATCH 2/4] Update i18n/en/docusaurus-plugin-content-docs/current/guides/issues/excessive-entities.md Co-authored-by: Lev Chelyadinov --- .../current/guides/issues/excessive-entities.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/en/docusaurus-plugin-content-docs/current/guides/issues/excessive-entities.md b/i18n/en/docusaurus-plugin-content-docs/current/guides/issues/excessive-entities.md index 813e66cfa..8f1fddc14 100644 --- a/i18n/en/docusaurus-plugin-content-docs/current/guides/issues/excessive-entities.md +++ b/i18n/en/docusaurus-plugin-content-docs/current/guides/issues/excessive-entities.md @@ -1,6 +1,6 @@ # Excessive Entities -The entities layer in Feature-Sliced Design is the first layer that incorporates business logic, distinguishing it from the `shared` layer. Unlike the `model` segment, it is globally accessible (except by `shared`), making it reusable across the application. However, its global nature means changes can have a widespread impact, requiring careful design to avoid costly refactors. +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 changes to Entities can have a widespread impact, requiring careful design to avoid costly refactors. ## How to keep `entities` layer clean From 26bde66f14bd8c8fe60127400bf4844bcefbf17b Mon Sep 17 00:00:00 2001 From: Solant Date: Tue, 18 Nov 2025 17:05:11 +0100 Subject: [PATCH 3/4] docs: add bridge phrase --- .../current/guides/issues/excessive-entities.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/i18n/en/docusaurus-plugin-content-docs/current/guides/issues/excessive-entities.md b/i18n/en/docusaurus-plugin-content-docs/current/guides/issues/excessive-entities.md index 8f1fddc14..ad873b5e2 100644 --- a/i18n/en/docusaurus-plugin-content-docs/current/guides/issues/excessive-entities.md +++ b/i18n/en/docusaurus-plugin-content-docs/current/guides/issues/excessive-entities.md @@ -1,6 +1,8 @@ # 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 changes to Entities can have a widespread impact, requiring careful design to avoid costly refactors. +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 From 41cf8e2929dd0aff01921cf35df7ebedf20a9d58 Mon Sep 17 00:00:00 2001 From: Solant Date: Wed, 19 Nov 2025 00:37:59 +0100 Subject: [PATCH 4/4] docs: apply code review comments --- .../guides/issues/excessive-entities.md | 32 +++++++++++++------ 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/i18n/en/docusaurus-plugin-content-docs/current/guides/issues/excessive-entities.md b/i18n/en/docusaurus-plugin-content-docs/current/guides/issues/excessive-entities.md index ad873b5e2..7ef0c68d8 100644 --- a/i18n/en/docusaurus-plugin-content-docs/current/guides/issues/excessive-entities.md +++ b/i18n/en/docusaurus-plugin-content-docs/current/guides/issues/excessive-entities.md @@ -6,14 +6,26 @@ Excessive entities can lead to ambiguity (what code belongs to this layer), coup ## How to keep `entities` layer clean -To keep a maintainable `entities` layer, consider the following principles based on the application's data processing needs. Keep in mind that this classification is not strictly binary, as different parts of the same application may have β€œthin” or β€œthick” parts: +### 0. Consider having no `entities` layer -- Thin Clients: These applications rely on the backend for most data processing. They often do not require an `entities` layer, as client-side business logic is minimal and involves only data retrieval. -- Thick Clients: These handle significant client-side business logic, making them suitable candidates for the `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. -It is acceptable for an application to lack an `entities` layer if it functions as a thin client. This simplifies the architecture and keeps the `entities` layer available for future scaling if needed. +:::info[What are thick and thin clients?] -### Avoid Unnecessary Entities +_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: it is much easier and safer to move something into `entities` later, than refactor code inside `entities` that can affect any upper level slice functionality. + +### 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`: @@ -30,7 +42,7 @@ Do not create an entity for every piece of business logic. Instead, leverage typ πŸ“„ order.ts ``` -### Exclude CRUD Operations from Entities +### 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`: @@ -47,9 +59,9 @@ CRUD operations, while essential, often involve boilerplate code without signifi For complex CRUD operations (e.g., atomic updates, rollbacks, or transactions), evaluate whether the `entities` layer is appropriate, but use it with caution. -### Store Authentication Data in `shared` +### 4. Store Authentication Data in `shared` -Avoid 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: +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. @@ -59,7 +71,7 @@ Instead, store authentication-related data in `shared/auth` or `shared/api`: ```plaintext πŸ“‚ shared πŸ“‚ auth - πŸ“„ use-auth.ts // Hook returning authenticated user info or token + πŸ“„ use-auth.ts // authenticated user info or token πŸ“„ index.ts πŸ“‚ api πŸ“„ client.ts @@ -68,7 +80,7 @@ Instead, store authentication-related data in `shared/auth` or `shared/api`: πŸ“„ order.ts ``` -### Minimize Cross-Imports +### 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: