- Providing reactivity to state changes
- Holding onto state
- Updating remote data and providing async states (loading, success, error)
- Expressing model behavior. Also known as domain (interaction) logic.
- React hooks
- Redux
- Context API
- Apollo Client
- RESTful APIs
- xState
- react-query
The `M` is responsible for too much. Business logic lives in between frameworks, ORMs, and controllers.
It's impossible to unit test code and it's also impossible to handle complex domain logic.
This means that you could swap out transport (graphql, rest) or persistence (MySQL, Mongo, event store) technologies per feature.
jimmybogard.com/vertical-slice…
1. Serving a GraphQL request and persisting with Raw SQL.
- View = Desktop React App
- Transport = GraphQL
- Application (use case) = Create user
- Domain = Email, Password, Username models
- Persistence = Raw SQL
- View = Android app
- Transport = REST
- Application (use case) = Create user
- Domain = Email, Password, Username models
- Persistence = @eventstore
- View = React Native app
- Transport = GraphQL
- Application (use case) = Get user by id
- Domain = skip
- Persistence = Sequelize ORM
The clean architecture tells us what each layer is responsible for.
We're missing this same kind of clarity on the client-side.
medium.com/@dan_abramov/s…
If your app has complex behaviour, ie: games, drag-and-drop, data viz, etc. Then separation of concerns is essential.
If you can validate correctness through the UI, integration tests might provide more bang for your buck.
- Interaction logic: Hooks + xState
- State management: Apollo Client (global state)
- Data fetching: Apollo Client
- Interaction logic: Hooks + pojo-observer
- State Management: Apollo Client (global state)
- Data fetching: Apollo Client
github.com/xolvio/pojo-ob…
- Interaction logic: Hooks
- State Management: Redux (global state). Connect for observability/reactivity, and Thunks for signaling async states.
- Data fetching: Fetch or Axios
UI logic can be tested as a side-effect of the model.
To avoid testing view-layer specifics, a library like @TestingLib can be used to perform integration tests.