Carrying immutable data through EventBridge payloads

on 2023-04-08

Back in 2020 Sheen Brisals suggested a clean way of composing EventBridge payloads by splitting detail into data and metadata:

The “metadata” section can be standard and a mandatory section for all the micro-services that produce an event, where as the “data” section can be specific to each service and the content can vary depending on the service.

This pattern can be extended by introducing an additional object within metadata to hold a set of immutable data.

The immutable section can contain special (non-PII) data that our downstream services must persist across the events they produce.

{
  "detail": {
    "metadata": {
      "domain": "SHOP",
      "service": "service-checkout",
      "type": "ORDER",
      "status": "SUBMITTED",
      "immutable": {
        "correlation_id": "f5b5c56f-fb2d-4144-a386-19c9fb7671de",
        "origin": "client_55",
        "features" : [
          "DEBUG",
          "SUPERCOOL_FEATURE",
          "TEST_CASE"
        ]
      }
    },
    "data": {
      "orderNumber": "T123123123",
      "customerId": "23hdfjdf-34ff-34ghj",
      "totalValue": 29.99,
      "items": 5
    }
  }
}

In the example above I have provided a few use cases for this patten.

Tracing

A correlation_id is a unique identifier that can be persisted between events in our domain, allowing metrics and logs to be correlated across multiple micro-services. If using a logging library such as Pino we can temporarily inject this correlation_id to the logger's context at the start of each invocation. Just be sure to reset/clear this context between invocations.

Origin tracking

It may be useful to track the origin of an "event path" in our domain. Imagine the following scenario:

You are a platform team in-charge of an internal shipping API. Having this non-functional auxiliary data available in our logs allows us to immediately identify which client is having issues at an individual "event path" level or across the board.

Feature flag propagation

How can we seamlessly and even partially test out a new courier service provider without disrupting our existing architecture too much and have peace of mind that rollback this change is trivial?

Lets propagate feature flags through our immutable metadata!