Show me the code!

There is an old principle: show don't tell, and this introduction is about showing you what you can do with Brighter and Darker. It's not about how - more detailed documentation elsewhere shows you how to write this code. It's not about why - articles elsewhere discuss some of the reasons behind this approach. It is just, let me see how Brighter works.

Brighter and Darker

Brighter is about Requests

A Request is a message sent over a bus. A request may update state.

A Command is an instruction to execute some behavior. An Event is a notification.

You use the Command Processor to separate the sender from the receiver, and to provide middleware functionality like a retry.

Darker is about Queries

A Query is a message executed via a bus that returns a Result. A query does not update state.

You use the Query Processor to separate the requester from the replier, and to provide middleware functionality like a retry.

Middleware

Both Brighter and Darker allow you to provide middleware that runs between a request or query being made and being handled. The middleware used by a handler is configured by attributes.

Sending and Querying Example

In this example, we show sending a command, and querying for the results of issuing it, from within an ASP.NET WebAPI controller method.

[Route("{name}/new")]
[HttpPost]
public async Task<ActionResult<FindPersonsGreetings>> Post(string name, NewGreeting newGreeting)
{
	await _commandProcessor.SendAsync(new AddGreeting(name, newGreeting.Greeting));

	var personsGreetings = await _queryProcessor.ExecuteAsync(new FindGreetingsForPerson(name));

	if (personsGreetings == null) return new NotFoundResult();

	return Ok(personsGreetings);
}

Handling Examples

Handler code listens for and responds to requests or queries. The handler for the above request and query are:

Using an External Bus

As well as using an Internal Bus, in Brighter you can use an External Bus - middleware such as RabbitMQ or Kafka - to send a request between processes. Brighter supports both sending a request, and provides a Dispatcher that can listen for requests on middleware and forward it to a handler.

📝 Note: Start Simple, Add Complexity Later The examples below show the simplest way to get started with Brighter's external bus. They use the InMemory Outbox for development and testing, which requires no additional infrastructure setup.

⚠️ InMemory Outbox Limitations:

  • Not durable - crashes lose messages

  • Not suitable for production

  • No distributed transactions

For production scenarios, see:

Sending a Message to Another Process

The following code shows the simplest way to send a message to another process using Brighter's external bus:

What's happening here:

  • The handler writes to the database

  • PostAsync() sends a message via the configured transport (RabbitMQ, Kafka, etc.)

  • The message is written to the InMemoryOutbox, then immediately dispatched

  • No explicit message mapper needed - uses default JSON mappers automatically

  • No transactions - This is the simplest approach for getting started

Receiving a Message from Another Process

The following code receives a message sent from another process via a Dispatcher:

What's happening here:

  • The Dispatcher receives the message from the transport

  • Routes it to this handler based on message type

  • The handler processes the message and writes to the database

  • No explicit message mapper needed - V10 automatically deserializes JSON messages

Configuration Example

Here's how to configure Brighter with an InMemory Outbox and a transport:

Next Steps

Once you're comfortable with these basics:

  1. Add Transactional Messaging - Use DepositPost and ClearOutbox for guaranteed message delivery

  2. Add Deduplication - Use Inbox Pattern to handle duplicate messages

  3. Production Outbox - Replace InMemory with database-backed Outbox

  4. Explore Samples - See the WebAPI Sample for production patterns

Last updated

Was this helpful?