Book Of Eventicle
Intro
Eventicle is an opinionated library for building distributed event based NodeJS applications.
It uses Domain Driven Design principles, and lets you build systems that use technologies like Kafka natively.
Quick Start
This sets up an in memory event driven system that can later be run on Kafka, Redis and Postgres.
yarn add @eventicle/eventiclejs
import {
setEventSourceName,
eventClientOnDatastore,
InMemoryDatastore,
setDataStore,
setEventClient, eventClient, EventicleEvent
} from '@eventicle/eventiclejs';
setEventSourceName('my-cool-service');
// in service data storage abstraction. Used by the internals of eventicle, can also be used in app code
setDataStore(new InMemoryDatastore());
// The connection to the event transport, this is in memory and stores events and state in the current datastore
setEventClient(eventClientOnDatastore());
Treat an event stream as a simple Topic, do not request any historical data.
eventClient().hotStream("app.streamname", "my-consumer", async (event: EventicleEvent) => {
console.log("An event of type " + event.type)
console.log(event)
}, error => {
console.log("An error occurred");
console.log(error)
})
Emit an event to a stream, all following Eventicle event machinery is built on this
// raw event client. Used mainly for special case external integration
await eventClient().emit([
{
type: "user.created",
data: { (1)
userName: "Personal Person"
}
}
], "app.streamname")
1 | The event payload |
This starts at the beginning of stream app.streamname
, and will receive all historical events, then finish.
_Mostly used for offline, batch or automation actions, such as a view upgrade or full stream schema update
await eventClient().coldStream("app.streamname", async (event: EventicleEvent) => {
console.log("An event of type " + event.type)
console.log(event)
}, error => {
console.log("An error occurred");
console.log(error)
}, () => console.log("Event stream has fully replayed"))
This starts at the beginning of stream app.streamname
, and will receive all historical events. It will then continue
to observe the stream.
Used for most runtime stream consumption
await eventClient().coldStream("app.streamname", async (event: EventicleEvent) => {
console.log("An event of type " + event.type)
console.log(event)
}, error => {
console.log("An error occurred");
console.log(error)
}, () => console.log("Event stream has fully replayed"))
Next …
Now you’ve seen the basics of an event based system, the creation and observation of events, you can start to add in more conceptual pieces.
-
Views, a way to process streams of events into data structures that can be queried efficiently.
-
Aggregate Roots, components that store state, generate events, and enforce rules about how they relate to each other. Often, implemented as a formal state machine using XState.
-
Commands, components that record changes to the system by taking events and emitting them to streams.
-
Sagas, event driven workflows. Implementing asynchronous business logic and integration with external systems in a way that safely isolates them from your core application logic.