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.
Essentially the schema generation process works as follows.
- Unit tests raise events from the API handlers that are triggered
- These events are published via the
tests/utils/event-publisher.tscomponent - The
event-publishertracks all published events and writes them to a JSON document herescripts/events/schemas/[module]/[event_name].json - The above generated file contains an array of the publised events from all tests so we have a broader range of events to generate the schemas from
- There are 2 scripts to control the event schema generation \
pnpm run gen:events:resetthis deletes the generated JSON files ready for another test run to regenerate them \pnpm run gen:eventsthis script generates the typescript interfaces for the generated events - These scripts are incorporated into the
pnpm run pcscript (pre-commit script) so running this script before a commit to main will ensure we have generated the latest event schemas. - The event interfaces are written to a component in the
events\[module]folder - We are using https://quicktype.io/ for interface generation
The main advantage of using this process rather than EventBridge is that we do not rely on events being pushed through the eventbridge to be able to generate the latest interfaces, we can do this as a build step on commits to main.
Schema generation considerations
- The process relies on us having tests for all events, if there are no tests for an event the interfaces will not be generated.
- If our published events contain missing fields on the event, these fields will not be included in the generated interfaces, this issue would be present whether we use this process or EventBridge schema discovery.
Consuming events
HandleTradeInventoryAllocated:
Type: AWS::Serverless::Function
Properties:
CodeUri: dist/trade-allocated
Handler: index.handler
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