LogoLogo
  • README
  • VERSION 9
    • Version Begins
  • Overview
    • Show me the code!
    • Basic Concepts
    • Why Brighter?
  • Brighter Configuration
    • Basic Configuration
    • How Configuring the Command Processor Works
    • How Configuring a Dispatcher for an External Bus Works
    • RabbitMQ Configuration
    • AWS SNS Configuration
    • Kafka Configuration
    • Azure Service Bus Configuration
    • Azure Archive Provider Configuration
  • Darker Configuration
    • Basic Configuration
  • Brighter Request Handlers and Middleware Pipelines
    • Building an Async Pipeline of Request Handlers
    • Basic Configuration
    • How to Implement an Async Request Handler
    • Requests, Commands and an Events
    • Dispatching Requests
    • Dispatching An Async Request
    • Returning results from a Handler
    • Using an External Bus
    • Message Mappers
    • Routing
    • Building a Pipeline of Request Handlers
    • Passing information between Handlers in the Pipeline
    • Failure and Dead Letter Queues
    • Supporting Retry and Circuit Breaker
    • Failure and Fallback
    • Feature Switches
  • Guaranteed At Least Once
    • Outbox Support
    • Inbox Support
    • EFCore Outbox
    • Dapper Outbox
    • Dynamo Outbox
    • MSSQL Inbox
    • MySQL Inbox
    • Postgres Inbox
    • Sqlite Inbox
    • Dynamo Inbox
  • Darker Query Handlers and Middleware Pipelines
    • How to Implement a Query Handler
  • Health Checks and Observability
    • Logging
    • Monitoring
    • Health Checks
    • Telemetry
  • Command, Processors and Dispatchers
    • Command, Processor and Dispatcher Patterns
  • Under the Hood
    • How The Command Processor Works
    • How Service Activator Works
  • Event Driven Architectures
    • Microservices
    • Event Driven Collaboration
    • Event Carried State Transfer
    • Outbox Pattern
  • Task Queues
    • Using a Task Queue
  • FAQ
    • FAQ
  • END OF VERSION
    • Version Ends
  • VERSION 10
    • Version Begins
  • Overview
    • Show me the code!
    • Basic Concepts
    • Why Brighter?
  • Brighter Configuration
    • Basic Configuration
    • How Configuring the Command Processor Works
    • How Configuring a Dispatcher for an External Bus Works
    • RabbitMQ Configuration
    • AWS SNS Configuration
    • Kafka Configuration
    • Azure Service Bus Configuration
    • Azure Archive Provider Configuration
  • Darker Configuration
    • Basic Configuration
  • Brighter Request Handlers and Middleware Pipelines
    • Building an Async Pipeline of Request Handlers
    • Basic Configuration
    • How to Implement an Async Request Handler
    • Requests, Commands and an Events
    • Dispatching Requests
    • Dispatching An Async Request
    • Returning results from a Handler
    • Using an External Bus
    • Message Mappers
    • Routing
    • Building a Pipeline of Request Handlers
    • Passing information between Handlers in the Pipeline
    • Failure and Dead Letter Queues
    • Supporting Retry and Circuit Breaker
    • Failure and Fallback
    • Feature Switches
  • Guaranteed At Least Once
    • Outbox Support
    • Inbox Support
    • EFCore Outbox
    • Dapper Outbox
    • Dynamo Outbox
    • MSSQL Inbox
    • MySQL Inbox
    • Postgres Inbox
    • Sqlite Inbox
    • Dynamo Inbox
  • Darker Query Handlers and Middleware Pipelines
    • How to Implement a Query Handler
  • Health Checks and Observability
    • Logging
    • Monitoring
    • Health Checks
    • Telemetry
  • Command, Processors and Dispatchers
    • Command, Processor and Dispatcher Patterns
  • Under the Hood
    • How The Command Processor Works
    • How Service Activator Works
  • Event Driven Architectures
    • Microservices
    • Event Driven Collaboration
    • Event Carried State Transfer
    • Outbox Pattern
  • Task Queues
    • Using a Task Queue
  • FAQ
    • FAQ
  • END OF VERSION
    • Version Ends
Powered by GitBook
On this page
  • Command
  • Command Processor
  • Command-Query Separation (CQS)
  • Event
  • Event Stream
  • External Bus
  • Internal Bus
  • Message
  • Message Oriented Middleware (MoM)
  • Message Mappers
  • Message Queue
  • Pipeline
  • Query
  • Query Handler
  • Query Processor
  • Result
  • Request
  • Request Handler
  • Request-Reply
  • Routing Key (Topic)
  • Service Activator

Was this helpful?

Edit on GitHub
  1. Overview

Basic Concepts

PreviousShow me the code!NextWhy Brighter?

Last updated 1 year ago

Was this helpful?

Command

A command is an instruction to carry out work. It exercises the domain and results in a change of state. It expects a single handler.

An may be used to indicate the outcome of a command.

Command Processor

In Brighter, a command processor allows you to use the Command Pattern to separate caller from the executor, typically when separating I/O from domain code. It acts both as a Command Dispatcher which allows the separation of the parameters of a from the that executes that request and a Command Processor that allows you to use a middleware to provide additional and re-usable behaviors when processing that request.

The Command Processor may dispatch to an or an .

Command-Query Separation (CQS)

Command-Query separation is the principle that because a should never have the unexpected side-effect of updating state, a query should clearly be distinguished from a . A query reports on the state of a domain, a command changes it.

Event

An event is a fact. The domain may be updated to reflect the fact represented by the event. There may be no subscribers to an event. It may be skinny, a notification, where the fact is the event itself, or fat, a document, where the event provides facts describing a change.

An event may be used to indicate the outcome of a .

Event Stream

Examples: Kafka, Kinesis, Redis Streams

External Bus

Internal Bus

Message

Message Oriented Middleware (MoM)

Brighter abstracts a specific type of message-oriented middleware by a Transport.

For simplicity, Brighter only supports transports that have a broker configuration, not point-to-point. If you need point-to-point semantics, configure your routing table entry so that it only delivers to one consuming queue or stream.

Message Mappers

Each individual transport has code to turn a Brighter format message into a message oriented middleware compatible message, and vice versa, so your code only needs to translate to and from the Brighter format.

Message Queue

Examples: SQS, AMQP 0-9-1 (Rabbit MQ), AMQP 1-0 (Azure Service Bus).

Pipeline

Brighter and Darker's pipelines use a "Russian Doll Model" that is, each handler in the pipeline encompasses the call to the next handler, allowing the handler chain to behave like a call stack.

Query

Query Handler

It is analogous to a method on an ASP.NET Controller.

Query Processor

Result

Request

Request Handler

It is analogous to a method on an ASP.NET Controller.

Request-Reply

Request-Reply is a pattern in which there is a request for work and a response.

A common approach is to change state via Brighter and query for the results of that state change via Darker (and return those results to the caller).

Routing Key (Topic)

A routing key, also called a topic is the key used by message broker to route published messages to a subscriber.

Service Activator

In , an event stream delivers (or records) via a steam. A consumer reads the stream at a specific offset from the start. Consumers can store their offsets to resume reading the stream for where they left off, or reset their offset to re-read a stream. Consumers neither lock, nor delete messages from the stream. For consuming apps to scale, the stream can be partitioned, allowing offsets to be maintained of a partition of the stream. By using separate consumer threads or processes to read a partition, an application can ensure that it is able to reduce the latency of reading the stream.

An external bus allows a or to be turned into a and sent over message-oriented-middleware via broker to a or .

Brighter also offers a to listen for messages published to a queue or stream and forward them to an within another process.

A , or is executed in-process, passed from the or to a .

A message is a packet of data sent over message-oriented-middleware. It's on-the-wire representation is defined by the protocol used by .

The class of applications that deliver a from one process to another. MoM may send messages either point-to-point (with just a ) between sender and receiver, or via a broker, which acts as a dynamic router for messages between sender and receiver. With a broker, the receiver often establishes a subscription to a routing table entry (a routing key or topic) via a or an .

A message mapper turns domain code into a message: a header and a body, or turns a message into domain code. Because typically looks in a header for routing information, it is also where you add routing information via the header.

In , a message queue delivers via a queue. A consumer locks a message, processes it, and when it acknowledges it, it is deleted from the queue. Other consumers can process the same queue, and read past any locked messages. This allows scaling via the competing consumers pattern. A nack will release the lock and make a message visible in the queue again, sometimes with a delay. A dead-letter-queue (DLQ) can be used with a nack, to limit the number of retries before a message is considered to be "posion pill" and moved to another queue for undeliverable messages.

A pipeline is a sequence of that respond to a or . The last handler in the sequence is the "target" handler, which forms the pipeline sink. Handlers prior to that form "middleware" that can transform or respond to the request before it reaches the target handler.

A query asks the domain for facts. The of the query reports these facts - the state of the domain. A query does not change the state of the domain, for that use a .

A handler is the entry point to domain code. It receives a query and returns a to the caller. A handler is always part of an . As such a handler forms part of a .

In Darker, a query processor allows you to use the Query Object Pattern to separate caller from the executor, typically when separating the code required to execute a query on a specific database/backing store from the parameters of that query. It acts both as a Query Dispatcher which allows the separation of the parameters of a from the that executes that query and a Query Processor that allows you to use a middleware to provide additional and re-usable behaviors when processing that query.

The Query Processor dispatches to an .

The Query Processor returns a .

The return value from a . The result is returned from a and exposed to the caller via the .

In Brighter, either a or an , a request for the domain to (potentially) change state in response to an instruction or new facts.

A handler is the entry point to domain code. It receives a request, which may be a or an . A handler is always part of an even when the call to the handler was triggered by a receiving a sent by another process to an . As such a handler forms part of a .

To enforce Brighter handles commands/events and Darker handles queries.

Where the request changes state, Brighter models this as a and a matching which describes the change. (See for a discussion of returning a response directly to the sender of a Command).

Where the request queries for state, Darker models this as a , which returns a directly to the caller.

If the call to Brighter results in a new entity, and the id for the new entity was not given to the command (for example it relies on the Database generating the id), a common problem is how to then request the details of that newly created entity via Darker. A simple solution is to update the command with the id (as a conceptual out parameter), and then retrieve it from there to use in the Darker query. See for more.

A Service Activator triggers execution of your code due to an external input, such as an HTTP call, or a sent over middleware.

In Brighter, the Dispatcher acts as a Service Activator, listening for a message from middleware, which it delivers via the to a . As such, it turns messages sent over middleware to a call on your .

update a field on a command
event
request
handler
pipeline
Internal Bus
External Bus
query
command
command
message oriented middleware
messages
command
event
message
message queue
event stream
service activator
internal bus
query processor
command
event
query
command processor
handler
pipeline
message-oriented-middleware
message
message queue
message queue
event stream
message oriented middleware
message oriented middleware
messages
handlers
request
query
result
request
result
internal bus
pipeline
query
handler
pipeline
Internal Bus
result
query
query handler
QueryProcessor
command
event
command
event
internal bus
service activator
message
external bus
pipeline
Command-Query Separation
Returning Results from a Handler
command
event
query
result
message
command processor
handler
internal bus