Introduction
The Decorated Saga is built on the the saga pattern but with a few key differences
- The pattern requires an AMQP compliant message broker
- All services share a common message exchange
- Each service has it’s own queue connected to the common exchange – resulting in a fan out configuration
- Services receive messages, decorated them with information from their domain and re-publish the message

The pattern’s primary objective is to facilitate the creation of loosely coupled choreographed microservice systems. The advantages of the pattern are
- No service needs to know of the existence of any other service
- All services have see all messages giving them a chance to both use the information in the message in their own domain and participate in decorating the message for other services.
- Services can be scaled independently of any other service based on their own load simply by deploying another instance of the service connected to the same queue
- Services can easily be added to the system with no impact on any other service
- Services can be removed from the system with minimal impact on other services.
- Braking changes can be handled easily be using semantic versioning and running 2 version of the same service side by side
How the pattern works
Because all services see all messages, one of the most important things to get right is the message validation. Services need to check each message’s properties to determine if they need to take any action. In most cases a service will not be able to act on a message and so it simply acknowledges the message and throws it away. The following flow chart describes the required validation process

Message structure
Messages are sent as json objects. This ensures that services written in any technology can consume the message and that the message remain human readable so that it is easy for developers to debug issues. The following example message illustrates the message contract.
{ “correlationId”: “12345678-1234-1234-1234-1234567890AB”,
“sourceService”: “OrderService”,
“publishTime”: “2023-08-03T13:07:51.4005517Z”,
“lastServiceDecoration”: “WearhouseService”,
“lastDecorationTime”: “2032-08-03T13:07:52.9574687Z”,
“saga”: “OrderPlaced”,
“context”:
{ “UserId”: “12345678-1234-1234-1234-1234567890AB”,
”SKU”: ”PRODUCT-056”,
”quantity”: ”1”,
”pricePaid”: ”9.99”,
”currency”: ”GBP”
},
“decorations”:
[
{ “status”: “stockReserved”,
“stockItem”: “PRODUCT-056”,
”quantity”: ”1”
}
]
}
Message Header
The message contains a number of header properties that are used to determine if a service can act upon a message.
correlationId: this properties remains the same for the lifetime of the message making it easy to trace through a number of services using log aggregation. It also allows for services to know if they have already processed a message in the event of an error in another service so that a rollback can be performed if required.
sourceService: This property remains the same for the lifetime of the message and contains the name of the service that originally published the message. This is useful for understanding why a message was raised and is also use full in request-response scenarios.
publishTime: This property remains the same for the lifetime of the message and contains the data and time that the message was first published
lastServiceDecoration: This property is updated when a service decorates and republishes the message
lastDecorationTime: This property is updated when a service decorates and republishes the message
saga: This is the name of the saga and is used by services to determine if they are interested in a message and can potentially decorate it
Message Body
The body of the message is made up of two properties.
context: This is the information that is added to the message by the service that first published the message. This contains information that other services will inspect to determine if they can act upon the message. For example this might contain information such as the user’s ID and any records the service has just created in it’s own database due to an interaction. This property is a json object and can have any schema. There is no set structure to this object.
decorations: When the message is first published this property is an empty array. When a service determines that it can act upon a message and that it has information with which to decorate the message it either adds a json object to this array, or further decorates an existing object if another service has already added an object. When consuming a messages services may also inspect the decorations to determine if the message contains information they need in order to act upon the message.