Default Message Mappers

Using Default Message Mappers

You do not need to implement IAmAMessageMapper for every message type.

In earlier versions, every message sent via an external bus required a message mapper implementation. This created duplicated code when in many cases, what was required was to take details from your Publication and then serialize the body to JSON.

To prevent this, Brighter provides default message mappers that handle common serialization patterns automatically. For most use cases, you can use a default and only create custom mappers when you need specialized message transformation.

Default Mappers Provided

Brighter includes two default message mappers for JSON serialization:

1. JsonMessageMapper<T> (Binary-Mode CloudEvents)

The JsonMessageMapper<T> is the default mapper that uses JSON serialization with binary-mode CloudEvents.

Characteristics:

  • Serializes your Request (Command/Event) to JSON

  • Uses binary-mode CloudEvents (attributes in headers).

  • Populate CloudEvents headers from your Publication.

  • The default when using AutoFromAssemblies() or MapperRegistry when configuring Brighter, but you can override with your own defaultMessageMapper or asyncDefaultMessageMapper instead.

CloudEvents Mode: Binary (recommended for protocols with header support like RabbitMQ, Kafka)

2. CloudEventJsonMessageMapper<T> (Structured-Mode CloudEvents)

The CloudEventJsonMessageMapper<T> uses JSON serialization with structured-mode CloudEvents.

Characteristics:

  • Serializes your Request to JSON

  • Uses structured-mode CloudEvents (attributes in JSON body)

  • Populate CloudEvents headers from your Publication.

  • Can be set as default mapper

  • Useful for protocols without header support or with constrained header support (small number of headers)

CloudEvents Mode: Structured (recommended for AWS SNS/SQS)

How Default Mappers Work

Brighter looks for first for an explicit IAmAMessageMapper<T> registration. If none is found, it falls back to the default mapper.

Automatic Usage (No Registration Needed)

This is the simplest and recommended approach for most scenarios:

When you publish an OrderCreated event:

Brighter automatically:

  1. Uses JsonMessageMapper<OrderCreated>

  2. Serializes to JSON

  3. Applies CloudEvents headers from Publication

  4. Sends the message with binary-mode CloudEvents

Choosing a Different Default Mapper

You can configure which default mapper to use:

This configures structured-mode CloudEvents as the default, useful when your primary transport is AWS SNS/SQS.

When You Need Custom Message Mappers

While default mappers handle most scenarios, you still need custom IAmAMessageMapper implementations in these cases:

1. Non-JSON Serialization Formats

If you need a format other than JSON (Avro, ProtoBuf, XML, etc.) You can register your own default message mapper for these:

2. Transform Pipelines

When you need message transformation (Claim Check, Compression, Encryption, PII removal, etc.), you must use a custom mapper with transform attributes.

Transform Pipeline Example

Transform attributes allow you to apply transformations to messages as they're mapped. This is a powerful pattern for cross-cutting concerns like handling large messages, compression, or encryption.

Claim Check Transform

The Claim Check pattern stores large message payloads externally (e.g., S3) and sends only a reference in the message.

Here's a real example from the Brighter samples:

How it works:

On Send (MapToMessage):

  1. Handler serializes GreetingEvent to JSON

  2. [ClaimCheck] attribute checks message size

  3. If > 256KB, uploads payload to luggage store (e.g., S3)

  4. Replaces body with reference (uses CloudEvents dataref extension)

  5. Sends lightweight message with just the reference

On Receive (MapToRequest):

  1. [RetrieveClaim] attribute checks for dataref

  2. If present, downloads payload from luggage store

  3. Replaces message body with actual payload

  4. Deserializes to GreetingEvent

Compression Transform

Similarly, you can compress messages:

Chaining Multiple Transforms

You can chain transforms by using different step numbers:

The transforms execute in order based on the step parameter. On receive, they execute in reverse order.

Registering Custom Mappers

Explicit Registration

If you have specific messages that need custom mappers, register them explicitly:

Configuration Reference

Using Structured-Mode as Default

Custom Default Mapper (e.g., Avro)

Mixed: Default + Custom Mappers

Best Practices

1. Start with Default Mappers

Use default JsonMessageMapper<T> for all new messages unless you have a specific need:

2. Only Create Custom Mappers When Needed

Don't create custom mappers "just in case". Add them when you need:

  • Non-JSON formats (Avro, ProtoBuf)

  • Transform pipelines (Claim Check, Compression, Encryption)

  • Complex message routing logic

3. Configure CloudEvents in Publication

CloudEvents properties belong in Publication, not in mappers:

4. Use Transform Attributes for Cross-Cutting Concerns

Transform attributes are powerful for cross-cutting concerns:

5. Be Consistent with Default Mapper Choice

Choose one default mapper strategy for your application:

Further Reading

Sample Code

Full working examples can be found in the Brighter samples:

  • Default Mappers: Brighter/samples/WebAPI/ - WebAPI sample using default mappers

  • ClaimCheck Transform: Brighter/samples/Transforms/AWSTransfomers/ClaimCheck/ - Claim check example

  • Compression: Brighter/samples/Transforms/ - Various transform examples

Last updated

Was this helpful?