Skip to main content

Events

We generate events for all system events such as the creation / modification of data. These events are published to an AWS event bridge and can be consumed by client apps.

In order to decouple our event schemas from the modules which publish them we auto generate a set of event schemas and export them to event components in bit.cloud.

Events

All events should derive from the BaseEvent class here components/common/types/base-event.ts \ All event payloads should derive from the BaseEventPayload class here components/common/types/base-event.ts

You can publish events via the eventPublisher on the Context class. The eventPublisher implements the IEventPublisher interface which exposes the following methods

publishAfterCommit<T extends BaseEventPayload>(event: BaseEvent<T>): void
publishBatchAfterCommit<T extends BaseEventPayload>(events: BaseEvent<T>[]): void
publish<T extends BaseEventPayload>(event: BaseEvent<T>): Promise<void>
publishBatch<T extends BaseEventPayload>(events: BaseEvent<T>[]): Promise<void>

This allows you to publish one event or a batch of events. You can publish the events immediately (publish & publishBatch) or, more commonly you can publish the events only after the database session has been successfully committed (publishAfterCommit & publishBatchAfterCommit)

Schema generation process

We looked into the EventBridge schema discovery feature and took some inspiration from this process, but decided it would be more useful to be in control of this process from within our codebase.

The BaseEvent class (components/common/types/base-event.ts) has a public method called schema() which should be overridden in derived classed and a sample schema returned from this method

We have unit tests to ensure a sample schema is provided for all events so this is mandatory, the schema returned should return a sample value for all filds on the event model.

We use factores to centralise generation of example types for tests so often it makes sense to re-use these factories for the event schema generation to reduce code duplication, example of an event schema generated from factories...

import { BaseEventPayload } from '@hectare/platform.components.common'
import { Context, ContextFactory } from '@hectare/platform.components.context'
import { BusinessUnit, BusinessUnits } from '../../models'
import { BusinessUnitsFactory } from '../../factories'

export class BusinessUnitsCreated extends BaseEventPayload {
businessUnits: BusinessUnits

constructor(context: Context, businessUnits: BusinessUnits) {
super(context.event.correlationId, context.user.id, context.user.organisationId)
this.businessUnits = businessUnits
}

public static schema(): string {
return JSON.stringify(new BusinessUnitsCreated(ContextFactory.build(), BusinessUnitsFactory.build()))
}
}

We are using https://quicktype.io/ for interface generation

Consuming events

  HandleTradeInventoryAllocated:
Type: AWS::Serverless::Function
Properties:
CodeUri: dist/trade-allocated
Handler: index.handler
TimeOut: 15
Policies:
- Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- logs:DescribeLogStreams
Resource: '*'
Events:
Trigger:
Type: EventBridgeRule
Properties:
EventBusName: !ImportValue platform-infrastructure-services-event-bus-name
Pattern:
source:
- trading
detail-type:
- TradeInventoryAllocated

Above is a snippet of a lambda that consumes an event. You need to add an EventBus to consume from our custom event bus. If not supplied, the lambda will consume from the default event bus (which only contains AWS events).To see the different event types SAM Lambda could support, see here.

Tailing events

You can tail the event bus in real time via the terminal. This can be a very useful addition to your development workflow as well as for debugging. An easy way to achieve is this is by using the lumgio-cli. It forwards the events onto a SQS queue which it then tails for you.

function tailPlatformEventBus { lumigo-cli tail-eventbridge-bus -r eu-west-2 -n platform-infrastructure-event-bus }
function tailDefaultEventBus { lumigo-cli tail-eventbridge-bus -r eu-west-2 }

Add the above aliases to your bash profile of choice. You can then tail the bus after installing the cli as per the snippet below.

npm i -g lumigo-cli
export AWS_PROFILE=platform.dev
tailPlatformEventBus
// or tailDefaultEventBus