npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@twixtlabs/lambda-cqrs-poc

v0.1.21

Published

Utility/Base classes for a simple Lambda Command/Query Handler POC

Downloads

71

Readme

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