Amazon EventBridge Event Metadata
Tags: aws, eventdriven, serverless, webdev
Published: 2024-01-02 10:41:55

[Amazon EventBridge](https://aws.amazon.com/eventbridge/) Event Bus is a serverless event bus that helps you receive, filter, transform, route, and deliver events. It's a very powerful service that allows developers to work with events without worrying about scaling and it offers a very flexible system of rules to send events to virtually any destination.

# Standard
A standard event in EventBridge looks like this:

```
{
    "version": "0", // set by AWS
    "id": "9773f4b3-ff25-5ef2-b41b-791f868d424e", // set by AWS
    "detail-type": "your_event_type", // set by you
    "source": "your_app", // set by you
    "account": "123456789", // set by AWS
    "time": "2023-12-15T14:41:33Z", // set by you, optional
    "region": "eu-west-1", // set by AWS
    "resources": [], // set by you, optional
    "detail": {} // set by you, optional
}
```
While having a source, type and time is a very good base for an event I personally like to add some more details. Occasionally multiple events are published in the same request and then it can be very useful to trace them back to see what happened in which order. Since EventBridge doesn't guarantee the order of events, it's not reliable to depend on the service to process everything in the right order.

# With Metadata
This example shows how I'm populating the detail key with some extra metadata:

```
{
    "version": "0", // always 0
    "id": "9773f4b3-ff25-5ef2-b41b-791f868d424e",
    "detail-type": "your_event_type",
    "source": "your_app",
    "account": "123456789",
    "time": "2023-12-15T14:41:33Z",
    "region": "eu-west-1",
    "resources": [],
    "detail": {
        "createdAt": 1702651293210,
        "correlationId": "2dc5e557-dcc9-4aef-9794-be207ca1a011",
        "sequenceNr": 1,
        "idempotencyKey": "custom_idempotency_key:123",
        "persist": true,
        "context": {
            "foo": "bar"
        }
    }
}
```

As you can see, I'm adding a few things:

**createdAt**
Milisecond unix timestamp.

**correlationId**
A uuid which is the same for all events published in the same request.

**sequenceNr**
An increasing number for every event published in the same request.

**idempotencyKey**
A custom idempotency key so that if for some reason an event got published multiple times (EventBridge provides _at-least-once_ event delivery to targets). The consumer can ignore an event if it was previously handled.

**persist** 
A boolean to indicate if I want to persist this event to S3 using a rule that sends it to Firehose. If you want to learn more, I recommend you to read this article: [Logging EventBridge events to S3 with Firehose](https://dev.to/slootjes/logging-eventbridge-events-to-s3-with-firehose-2hkc).

For some projects, I use the same rule to persist the events in DynamoDB so I can easily look up events by ID, correlation ID (sorted by the Sequence Nr) and event type (sorted by timestamp) using Global Secondary Indexes.

**context**
This is the data that belongs to the event, you can put here what ever you like.

# Benefits
Having a _correlationId_, _sequenceNr_ and _createdAt_ allows you to see which events were published in the same request and in which order. The _idempotencyKey_ adds reliability to the application as it can prevent to do double work (depending on the type of event, this can have quite some impact).

Persisting events can be very useful. It's super useful for debugging but also a gold mine for auditing and analytical purposes.