Skip to content

Latest commit

 

History

History
48 lines (32 loc) · 2.89 KB

0017-use-strict-cqs-across-brighter-and-darker.md

File metadata and controls

48 lines (32 loc) · 2.89 KB
id 0017-use-strict-cqs-across-brighter-and-darker
title Use Strict Command Query Separation Across Brighter and Darker
status Accepted
author
Brighter Team
created 2024-07-24
summary Brighter treats all IRequest derivatives (Command, Event) as Commands in CQS terms — they mutate state and return no value; queries belong to Darker, enabling a full CQRS architecture when the two libraries are used together.
tags
cqrs
architecture
api-design

17. Use Strict Command Query Separation Across Brighter and Darker

Date: 2024-07-24

Status

Accepted

Context

Command-Query Separation(CQS) states that an operation should either report state or mutate state, never both. In this way it is reliably side-effect free.

every method should either be a command that performs an action, or a query that returns data to the caller, but not both. In other words, asking a question should not change the answer. More formally, methods should return a value only if they are referentially transparent and hence possess no side effects.

Command-Query Responsibility Segregation(CQRS) generalizes this operation principle to an architectural one where different models - a model for commands that update state, and a model for queries that read state - which often allows the query model to be optimized for reading over supporting operations.

Brighter is intended to support Commands and not Queries; Darker is intended to support Queries and not Commands.

Decision

In Brighter, we treat all derivatives of IRequest such as Command and Event are all Commands in terms of CQS. That is, they mutate state, they do not report it. (An Event has zero or more handlers, a Command has exactly one).

Consequences

The lack of any return value from an IRequest occasionally causes a complication because the flow of the programme means that the caller does not know the identity of any entities created by the command.

Typically this is a problem where the identity is generated by a row being added to an RDBMS with an identity column. Whilst Darker can be used to query for the entity to get it's state, how do you query for it?

  • The caller has enough information to query for the entity. This may be a natural identifier such as the name, or because the caller generates the identity, such as a ULID, over allowing an RDBMS to generate it
  • A property on the IRequest is mutable and can be set by the RequestHandler and then inspected by the caller
  • The handler sets a property in the RequestContext bag and the caller inspects that

If you want to query state, use Darker. The two libraries are intended to work together, to support CQRS.