@twixtlabs/lambda-cqrs-poc
TypeScript icon, indicating that this package has built-in type declarations

0.1.21 • Public • Published

Warning

Package is an experiment for rudimentary serverless implementation of the CQRS architectural style primarily using Lambda and DynamoDB.

Goals

  • Lambda functions for handling commands and events.
  • State-stored aggregates
  • Stretch: Event sourced aggregates
  • DynamoDB for persistence (state-stored aggregates and events)
  • Subscribing Event Processors
  • Stretch: Tracking event processor
  • Base classes for Command Handling and Query Handling.
  • Annotation(Decorator) based validation of command payloads (class-validator)

#Messages

We use the term Message describe the DTOs that carry payloads (commands/events). Lambdas are invoked/receive "Messages". While the accurate / technical term is "event", this would lead to ambiguity given the term "event" has another meaning in this context already.

Message seems like an appropriate term as it does not imply Sync or Async handling. ##Commands Commands are dispatched as a payload within a GenericCommandMessage. ##Events ###"Domain" Events We use the term Domain Event for the events that can be emitted as a result of command processing. This is to remain consistent with common terminology. As a technical implementation matter, these Domain Events generally do not exist as is outside of the Bounded Context. The decision and responsibility to publish events outside of the context for the rest of the Domain belongs to the context. These Domain Events are not defacto published to the rest of the domain.

Domain Events should be dispatched as a payload within a GenericDomainEventMessage ###Event Processing Subscribing Event Processors subscribe themselves to a source of Events and are invoked (logically) by the "publishing" mechanism. In this PoC, DynamoDB Streams plays the role of Subscribing Event Processor, there is no actual function code involved. Event Handlers (implemented is Lambda Functions) subscribe to a stream on the events table and the invocation of handlers is taken care of for us.

There is however no routing/filtering involved in this approach, handlers will receive all events, and must determine what action to take. Routing/filtering could be implemented using an intermediary Lambda function that delivers the events to an SNS Topic, SQS Queue etc, that the handler Lambdas could subscribe to / be triggered by, however that is beyond the scope of this initial Proof of Concept.

Of interest:

  • ordering of events in DynamoDB stream is guaranteed within each shard.
  • Shards scale with partitions, typically* all items for a given key (the collection) are in a single partition
  • DynamoDB stream entries are removed/expire after 24 hours. If you need more the same approach can be implemented with Kinesis which can hold entries for up to 7 days.

#Lambda Functions ##Dispatcher Dispatcher is an implementation of the front controller pattern, similar to how many popular web frameworks operate. The dispatcher is responsible for routing a Message to appropriate controller. Its implementation is fairly simplistic, it will route the message to the first controller in a list (constructor arg) that can handle the message.

Using the dispatcher your function can handle more than one type of message+payload combination. Whether it should or not is left up to the implementor.

When implementing your Lambda functions to handle commands/events, your handler function should instantiate the dispatcher and call doDispatch().

##Controllers ###Command Controllers Controllers for handling commands should extend AbstractCommandController and implement the execute() method.

The AbstractCommandController provides a default implementation of handleMessage that validates the payload within the message using the class-validator package.

The AbstractCommandController provides a default implementation of the canHandle() method using a command name supplied to the constructor and evaluating it against the commandName in the containing message.

It declares no-op preExecutue and postExecute methods that can be overridden in specific command controller implementations.

Build / Publish

npm run release

Readme

Keywords

none

Package Sidebar

Install

npm i @twixtlabs/lambda-cqrs-poc

Weekly Downloads

1

Version

0.1.21

License

none

Unpacked Size

207 kB

Total Files

140

Last publish

Collaborators

  • twixtlabs