Event-Store v0.7
FJ-EventStore is an EventStore heavily inspired by the prooph/event-store v7.0.
Implemented:
- SingleStream Strategy: Create a Stream for each Aggregate
- Loading and saving Aggregates
- Persistent Projections
- ReadModel Projections
- Event Queries
Available Driver
- InMemory
- Sqlite3
- PostgreSQL
- MySQL
Projections / Queries
- You can query and process one or multiple Streams with the
fromStream
,fromStreams
,fromAll
API. - Fetch all or a subset of Events with an optional
MetadataMatcher
- Create persisted State with an
Projector
or temporary created State with aQuery
- Fetching multiple streams creates a merged stream and run over the events in historical order
Basic Usage
The usage of this EventStore is recommended with TypeScript to benefit from the implemented autocompletion features for Events, ProjectionStates.
This EventStore also ships with Decorators
to simplify configuration.
The following descriptions using TypeScript. The integrated example serve using normal JavaScript for reference.
NestJS
Example Project based onFJ EventStore Example is a base Project with an example integration in the NodeJS Framework NestJS. The Example includes different APIs to show you the basic features like:
- Implementing Aggregates, Events, Projection, Repositories and so on
- Create and persist a new Aggregate
- Update an existing Aggregate
For a basic overview you can use the code snippets from this example project below
Initialise the EventStore
Create the EventStore in your Backend
// main.ts ; ; // Creates the event_streams and projections tables if they not existawait eventStore.install;
Create a new EventStream with the integrated CLI helper
event-store event-stream:create <streamName>
Create an Aggregate with the related Events using the included Decorator
Create a basic events with immutable values and payload autocomplete
// model/todo/event/todo-was-added.ts ;
Create and configure an Todo Aggregate with the AbstractAggregate
Class and Aggregate
Decorater to configure them.
Use Aggregate._recordThat to append a new Event to the EventStream of the Aggregate. its not persisted yet.
Each Aggregate calls internal a method with the name-schema _when${EventClassName}
if it exist. This Method is normally used to set the new State from the Events in the Aggregate.
// model/todo/todo.ts ;;;
Load and save Aggregates with Repositories
Create a Repository for your Aggregate. Each Repository has 2 methods to save and load aggregates.
// model/todo/todo-repository.ts ;;
Finally use your Aggregate and Repository to create and persist a Todo
// main.ts ;; ;
Create and using Projections
Create a simple persisted Projection
Using the AbstractProjection class and configure them with the helper Decorator
// projection/todo/todo-list.ts ;;
Run the projection and get the persisted state
// main.ts... ;
Using the Command Line Tool
The CLI event-store
supports the usage of EventStore with different helper commands for EventStreams and Projections.
Usage: event-store [command] --help CLI to manage EventStore streams, requires a event-store.config.js config file. Options: -V, --version output the version number -h, --help output usage information Commands: event-stream:create <streamName> Creates an new EventStream event-stream:delete <streamName> Deletes an existing EventStream projection:run [options] <name> Running a projection projection:reset <name> Reset a projection projection:delete [options] <name> Delete a projection
Run the example
Requirements
- A running Postgres DB - You can use the docker-compose.yaml to start a postgres instance as docker container.
docker-compose up -d postgres
-
Create your .env File under
./example
. You can copy and rename the.env.default
to.env
and change the values to your configuration -
Make the CLI Tool executable with the following command
chmod +x bin/event-store
Running the Example
# Install the dependencies (including DEV-dependencies) npm install # Install peerDependencies for a Postgres EventStore npm i pg @types/pg --no-save # Transpile Typescript npm run watch # Run the Example Server npm run serve
After the Server started you should see the Message EventStore installed
in your Terminal if the DB preparation was succeeded
Existing APIs are
Create a User:
http://localhost:3000/append/user/:username
(Returns the UserID you can fetch afterwards)
Fetch a User Aggregate:
http://localhost:3000/user/:aggregateId
(Returns the latest user state)
Change the Username:
http://localhost:3000/user/:aggregateId/change-name?name=:username
(Returns the updated user)
Write a comment:
http://localhost:3000/user/:aggregateId/write-comment?message=:message
(Returns the updated user)
Create and show a persistend Projection: User List:
http://localhost:3000/user/list
(Returns the updated user)
Query Events: User EventHistory:
http://localhost:3000/user/:id/history
(Returns the updated user)
Query multilpe StreamEvents: User Comment List:
http://localhost:3000/user/:id/comments