Clarify the Entities vs Features boundary as Read vs Write and add Server‑first guidance (with decision tree, cheat‑sheet, and pitfalls) #863
boaz-hwang
started this conversation in
Ideas
Replies: 1 comment
-
I'm sorry, but this text looks AI-generated to me. If I'm wrong about my assumption, could you please edit the message to explain your thought more briefly? |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Summary
This PR proposes a focused clarification to Feature‑Sliced Design (FSD):
The proposal does not change the layer model, slice/segment rules, or public API rules. It tightens semantics that already exist in FSD and offers pragmatic guardrails that reflect real‑world usage. See FSD layer and slice/segment references for context. ([feature-sliced.design]1)
Motivation
Teams frequently blur boundaries by:
onClick
or router hooks to Entities.While FSD defines layers (app → … → entities → shared) and segments (
ui
,api
,model
, etc.), the docs stop short of a crisp, testable boundary heuristic for Entities vs Features. This PR supplies that heuristic and maps it to modern Server‑first rendering where appropriate. ([feature-sliced.design]1)Additionally, the current “Routing” issue page (WIP) warns about URL logic leaking into lower layers; this PR contributes concrete guidance and examples to operationalize that page. ([feature-sliced.design]2)
Scope of change (documentation only)
New guide: “Read vs Write boundary: Entities (Read) and Features (Write)”
New appendix: “Server‑first mapping (Next.js RSC example)”
Updates to:
No normative changes to import rules, slices/segments, or public API. Cross‑imports and
@x
remain as documented. ([feature-sliced.design]3)Proposed content (draft)
1) Definitions
Entities (Read)
ui
for view,model
for view types/schemas,api
for read/SELECT helpers if needed. ([feature-sliced.design]1)Features (Write)
Purpose: All user interactions and writes.
Categories:
Owns handlers (
on*
), URL/query changes, side‑effects, optimistic UX, permissions for actions, and testing of interactions.Typical segments:
ui
(forms/buttons/observers),model
(local state/validators),api
(mutations). ([feature-sliced.design]1)2) Rules of thumb (operational)
on*
handler, it belongs in Features.Routing addendum: avoid hard‑coding URLs in lower layers; pass them down from Pages/Features via props/builders. ([feature-sliced.design]2)
3) Decision tree
Does this component trigger any write?
(DB, URL, client state, side‑effects like clipboard, prefetch, socket)
→ Yes: Features. → No: go to 2.
Is it pure? (Same input ⇒ same markup.)
→ Yes: Entities. → No: likely Features decides conditions and injects props to an Entity view.
Is it a link?
4) Server‑first appendix (optional, stack‑agnostic; Next.js as example)
Intent: show one concrete mapping; FSD remains stack‑agnostic.
Mapping (Next.js App Router):
Minimal folder sketch (fits existing FSD layers/segments):
(Still honors layers, segments, public API, and import rules.) ([feature-sliced.design]1)
5) Classification cheat‑sheet (abridged)
6) Testing guidance (brief)
7) Common pitfalls (and fixes)
useSearchParams
,router.*
) → move to Features, pass props/href down.@x
→ follow Public API rules and@x
notation. Consider Steiger for enforcement. ([feature-sliced.design]3)Backward compatibility
Alternatives considered
Keep Entities/Features definitions as‑is and rely on team conventions.
Open questions for maintainers
Checklist
Appendix: References (for reviewers)
ui
,api
,model
,lib
,config
). ([feature-sliced.design]5)@x
for cross‑imports). ([feature-sliced.design]3)If maintainers agree with the direction, I can follow up by splitting this into:
Beta Was this translation helpful? Give feedback.
All reactions