All Projects → pholactery → Eventsourcing

pholactery / Eventsourcing

Licence: apache-2.0
Event Sourcing Library for Rust

Programming Languages

rust
11053 projects

Projects that are alternatives of or similar to Eventsourcing

Laravel Event Projector
Event sourcing for Artisans 📽
Stars: ✭ 650 (+815.49%)
Mutual labels:  events, event-sourcing, eventstore
Memstate
In-memory event-sourced ACID-transactional distributed object graph engine for .NET Standard
Stars: ✭ 280 (+294.37%)
Mutual labels:  event-sourcing, eventstore
Eventually Rs
Event Sourcing for Rust
Stars: ✭ 277 (+290.14%)
Mutual labels:  event-sourcing, eventstore
Node Eventstore
EventStore Implementation in node.js
Stars: ✭ 503 (+608.45%)
Mutual labels:  event-sourcing, eventstore
OpenCQRS
.NET Standard framework to create simple and clean design. Advanced features for DDD, CQRS and Event Sourcing.
Stars: ✭ 546 (+669.01%)
Mutual labels:  events, event-sourcing
Equinox
.NET Event Sourcing library with CosmosDB, EventStoreDB, SqlStreamStore and integration test backends. Focused at stream level; see https://github.com/jet/propulsion for cross-stream projections/subscriptions/reactions
Stars: ✭ 260 (+266.2%)
Mutual labels:  event-sourcing, eventstore
Kledex
.NET Standard framework to create simple and clean design. Advanced features for DDD, CQRS and Event Sourcing.
Stars: ✭ 502 (+607.04%)
Mutual labels:  events, event-sourcing
CQELight
CQELight is an entreprise grade extensible and customisable framework for creating software with CQRS, DDD & Event Sourcing patterns
Stars: ✭ 21 (-70.42%)
Mutual labels:  events, event-sourcing
Eventstore
Event store using PostgreSQL for persistence
Stars: ✭ 729 (+926.76%)
Mutual labels:  event-sourcing, eventstore
Event bus
🏄 Traceable, extendable and minimalist **event bus** implementation for Elixir with built-in **event store** and **event watcher** based on ETS.
Stars: ✭ 563 (+692.96%)
Mutual labels:  event-sourcing, eventstore
node-cqrs
CQRS backbone with event sourcing for Node.js
Stars: ✭ 63 (-11.27%)
Mutual labels:  eventstore, event-sourcing
Transmute Framework
TypeScript dApp Framework
Stars: ✭ 45 (-36.62%)
Mutual labels:  event-sourcing, eventstore
iam-ddd-cqrs-es-nestjs
Identity and Access Management
Stars: ✭ 34 (-52.11%)
Mutual labels:  eventstore, event-sourcing
Event Sourcing Cqrs Examples
Event Sourcing and CQRS in practice.
Stars: ✭ 265 (+273.24%)
Mutual labels:  events, event-sourcing
fastify-kafka
Fastify plugin to interact with Apache Kafka.
Stars: ✭ 37 (-47.89%)
Mutual labels:  events, event-sourcing
Eventstore
The stream database optimised for event sourcing
Stars: ✭ 4,395 (+6090.14%)
Mutual labels:  event-sourcing, eventstore
eventuous
Minimalistic Event Sourcing library for .NET
Stars: ✭ 236 (+232.39%)
Mutual labels:  eventstore, event-sourcing
fs2-es
Event sourcing utilities for FS2
Stars: ✭ 75 (+5.63%)
Mutual labels:  events, event-sourcing
Equinoxproject
Full ASP.NET Core 5 application with DDD, CQRS and Event Sourcing concepts
Stars: ✭ 5,120 (+7111.27%)
Mutual labels:  event-sourcing, eventstore
Ultimate Backend
Multi tenant SaaS starter kit with cqrs graphql microservice architecture, apollo federation, event source and authentication
Stars: ✭ 978 (+1277.46%)
Mutual labels:  event-sourcing, eventstore

Event Sourcing

An eventsourcing library for Rust

One of the benefits of event sourcing is that in most cases, embracing this pattern does not require that much code. However, there's still a bit of boilerplate required as well as the discipline for ensuring the events, commands, and aggregates all perform their roles without sharing concerns.

The fundamental workflow to remember is that commands are applied to aggregates, which then emit one or more events. An aggregate's business logic is also responsible for returning a new state from a previous state combined with a new event. Put mathematically, this looks like:

f(state1, event) = state2

There are some event sourcing libraries that allow for, or even encourage, mutation of state in memory. I prefer a more functional approach, and the design of this library reflects that. It encourages you to write unit tests for your aggregate business logic that are predictable and can be executed in isolation without concern for how you receive events or how you persist them in a store.

To start, you create an undecorated enum for your Command type:

enum LocationCommand {
   UpdateLocation { lat: f32, long: f32, alt: f32 },
}

Next, you create an enum for your events and use a derive macro to write some boilerplate on your behalf. Note how the command variants are imperative statements while the event variants are verbs phrases in the past tense. While this is by convention and not enforced via code, this is a good practice to adopt.

#[derive(Serialize, Deserialize, Debug, Clone, Event)]
#[event_type_version("1.0")]
#[event_source("events://github.com/pholactery/eventsourcing/samples/location")]
enum LocationEvent {
   LocationUpdated { lat: f32, long: f32, alt: f32 },
}

We then define a type that represents the state to be used by an aggregate. With that in place, we write all of our business logic, the core of our event sourcing system, in the aggregate.

#[derive(Debug, Clone)]
struct LocationData {
    lat: f32,
    long: f32,
    alt: f32,
    generation: u64,
}

impl AggregateState for LocationData {
    fn generation(&self) -> u64 {
        self.generation
    }
}

struct Location;
impl Aggregate for Location {
   type Event = LocationEvent;
   type Command = LocationCommand;
   type State = LocationData;

   fn apply_event(state: &Self::State, evt: &Self::Event) -> Result<Self::State> {
       // TODO: validate event
       let ld = match evt {
           LocationEvent::LocationUpdated { lat, long, alt } => LocationData {
               lat: *lat,
               long: *long,
               alt: *alt,
               generation: state.generation + 1,
           },
       };
       Ok(ld)
   }

   fn handle_command(_state: &Self::State, cmd: &Self::Command) -> Result<Vec<Self::Event>> {
       // TODO: add code to validate state and command

       // if validation passes...
       Ok(vec![LocationEvent::LocationUpdated { lat: 10.0, long: 10.0, alt: 10.0 }])
   }
}

For more examples of usage, check out the examples directory in github.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].