Back to blog
Aug 12, 2024
4 min read

Event Bus

Routing events to targets

As part of my pltfrm work, I needed to build an Event Bus. According to AWS:

An event bus is a router that receives events and delivers them to zero or more
destinations, or targets. Event buses are well-suited for routing events from
many sources to many targets, with optional transformation of events prior to
delivery to a target.

I typically use an SQS queue to route events to a single target, and SNS/SQS if I want to route it to many - with filters on the subscriptions to limit certain cases.

An Event Bus offers a more tradition event-based architecture - with options for filtering and transformations, but I lose the ability to store messages until processed (up until 14 days, at least.) More worryingly, Event Bus is at least-once delivery, and order is not guaranteed.

Data Model

An Event Bus request has this structure:

{
  "version": "0",
  "id": "UUID",
  "detail-type": "event name",
  "source": "event source",
  "account": "ARN",
  "time": "timestamp",
  "region": "region",
  "resources": [
    "ARN"
  ],
  "detail": {
    JSON object
  }
}

Mandatory:

  • source : service creating the event. “We recommend the use of Java package-name style reverse domain-name strings.”
  • detail-type : identifies, in combination with the source field, the fields and values that appear in the detail field.
  • detail : a block of JSON

And you need to specify the Event Bus name.

Values defaulted, but that can be overridden

  • version : optional, always set to 0
  • id : generated as a UUID
  • account : AWS account
  • time : instant of event
  • region : AWS region
  • resources : arns of resources creating the event

Having specified just the 3 mandatory ones, my event looked like this:

{
  "version": "0",
  "id": "eb30327a-7f70-538e-6f22-9b6e8380f03c",
  "detail-type": "WeatherCurrentAndForecast",
  "source": "com.simongarton.pltfrm.weather.lambda.processor",
  "account": "<detail-removed>",
  "time": "2024-08-10T07:00:36Z",
  "region": "ap-southeast-2",
  "resources": [],
  "detail": {<detail-removed>}
}

Documentation

Eventual Consistency

This could be a problem. The only AWS resources that guarantee ordered delivery are SNS FIFO and SQS FIFO.

Article 1

Patterns and rules

Having built an Event Bus, you now need to do something with the events. What you do is set up rules, where the events must match a pattern, and then decide what should happen (e.g. publish to an SQS queue, invoke a lambda, etc)

Patterns

What I would like to do is have a rule that picks up when the forecast says it’s going to rain, and emails me.

I think I can do it like this …

{
  "detail": {
    "current": {
      "rain": [ { "exists": true } ]
    }
  }
}

There is an anything-but operator, but it doesn’t work with nulls.

Operators

Pipes

EventBridge Pipes are yet another alternative:

A pipe routes events from a single source to a single target. The pipe also
includes the ability to filter for specific events, and to perform enrichments
on the event data before it is sent to the target.

It looks … interesting, but I’m not sure it’s any better than the architectures I already use, and I’d rather limit my options.