All Projects → yehohanan7 → Flux

yehohanan7 / Flux

Licence: mit
A simple CQRS Framework for go

Programming Languages

go
31211 projects - #10 most used programming language
golang
3204 projects

Projects that are alternatives of or similar to Flux

Kreta
Modern project management solution
Stars: ✭ 177 (-14.08%)
Mutual labels:  microservices, event-sourcing, cqrs, domain-driven-design
Event Sourcing Jambo
An Hexagonal Architecture with DDD + Aggregates + Event Sourcing using .NET Core, Kafka e MongoDB (Blog Engine)
Stars: ✭ 159 (-22.82%)
Mutual labels:  microservices, event-sourcing, cqrs, domain-driven-design
Akkatecture
a cqrs and event sourcing framework for dotnet core using akka.net
Stars: ✭ 414 (+100.97%)
Mutual labels:  microservices, event-sourcing, cqrs, domain-driven-design
Dotnet New Caju
Learn Clean Architecture with .NET Core 3.0 🔥
Stars: ✭ 228 (+10.68%)
Mutual labels:  microservices, event-sourcing, cqrs, domain-driven-design
User Bundle
A new Symfony user bundle
Stars: ✭ 116 (-43.69%)
Mutual labels:  event-sourcing, cqrs, domain-driven-design
Bifrost
This is the stable release of Dolittle till its out of alpha->beta stages
Stars: ✭ 111 (-46.12%)
Mutual labels:  event-sourcing, cqrs, domain-driven-design
Apworks Core
Apworks framework supporting .NET Core
Stars: ✭ 190 (-7.77%)
Mutual labels:  microservices, cqrs, domain-driven-design
Eshoponcontainersddd
Fork of dotnet-architecture/eShopOnContainers in full DDD/CQRS design using my own patterns
Stars: ✭ 126 (-38.83%)
Mutual labels:  microservices, cqrs, domain-driven-design
Eventflow.example
DDD+CQRS+Event-sourcing examples using EventFlow following CQRS-ES architecture. It is configured with RabbitMQ, MongoDB(Snapshot store), PostgreSQL(Read store), EventStore(GES). It's targeted to .Net Core 2.2 and include docker compose file.
Stars: ✭ 131 (-36.41%)
Mutual labels:  event-sourcing, cqrs, domain-driven-design
Cronus
Cronus is a lightweight framework for building event driven systems with DDD/CQRS in mind
Stars: ✭ 139 (-32.52%)
Mutual labels:  microservices, event-sourcing, cqrs
Revo
Event Sourcing, CQRS and DDD framework for C#/.NET Core.
Stars: ✭ 162 (-21.36%)
Mutual labels:  event-sourcing, cqrs, domain-driven-design
Event Sourcing Microservices Example
Learn about building microservices with event sourcing using Spring Boot and how to deploy a social network to Kubernetes using Docker Compose or Helm.
Stars: ✭ 167 (-18.93%)
Mutual labels:  microservices, event-sourcing, cqrs
Goes
Go Event Sourcing made easy
Stars: ✭ 144 (-30.1%)
Mutual labels:  event-sourcing, cqrs, domain-driven-design
Productcontext Eventsourcing
A practical/experimental Event Sourcing application on Product Bounded Context in an e-commerce
Stars: ✭ 88 (-57.28%)
Mutual labels:  event-sourcing, cqrs, domain-driven-design
Symfony Demo App
A Symfony demo application with basic user management
Stars: ✭ 122 (-40.78%)
Mutual labels:  event-sourcing, cqrs, domain-driven-design
Nestjs Cqrs Starter
NestJS CQRS Microservices Starter Project
Stars: ✭ 80 (-61.17%)
Mutual labels:  microservices, event-sourcing, cqrs
Event Sourcing Castanha
An Event Sourcing service template with DDD, TDD and SOLID. It has High Cohesion and Loose Coupling, it's a good start for your next Microservice application.
Stars: ✭ 68 (-66.99%)
Mutual labels:  event-sourcing, cqrs, domain-driven-design
Cqrs
cqrs framework in go
Stars: ✭ 179 (-13.11%)
Mutual labels:  microservices, event-sourcing, cqrs
Ultimate Backend
Multi tenant SaaS starter kit with cqrs graphql microservice architecture, apollo federation, event source and authentication
Stars: ✭ 978 (+374.76%)
Mutual labels:  microservices, event-sourcing, cqrs
Asombroso Ddd
Una lista cuidadosamente curada de recursos sobre Domain Driven Design, Eventos, Event Sourcing, Command Query Responsibility Segregation (CQRS).
Stars: ✭ 41 (-80.1%)
Mutual labels:  event-sourcing, cqrs, domain-driven-design

Flux Build Status Go Report Card

logo

Introduction

"There is nothing called state. There are events and the story we tell about what it means."

Flux allows you to quickly build an application in CQRS way without the hassle of a messaging system like RabbitMQ or Kafka inbetween your command and read model services.

It's a good practice to have one command service per Aggregate (as per DDD terminology) and various read model/view services. the command service stores the events that are emited by each command and expose the same as a json feed for the consumers (read model services) to consume in regular intervals allowing you to easily decouple commands and "read model" services.

Components

architecture

Aggregate

Flux suggests that you use one service per Aggregate, which accepts commands and publishes events.

This is how you can define an aggregate in Flux:

import(
  "github.com/yehohanan7/flux"
  "github.com/yehohanan7/flux/cqrs"
)

//Account is an aggregate
type Account struct {
	cqrs.Aggregate
	Id      string
	Balance int
}

//Initialize the aggregate
acc := new(Account)
acc.Aggregate = cqrs.NewAggregate("account-id", acc, flux.NewBoltStore("path/to/database"))

The last argument is an EventStore, which provides an implementation to store and retrieve events - there are 2 implementations at the moment an inmemory one and a boltdb implementation

store := flux.NewMemoryStore()

Once you have the aggregate initialized, you can execute commands on it which will in turn emit events, make sure to update the state of the aggregate through a handler method (prefixed with the name Handle) on the aggregate

//My event
type AccountCredited struct {
	Amount int
}

//Command
func (acc *Account) Credit(amount int) {
	acc.Update(AccountCredited{amount})
}

//Event handler to allow you to update the state of the aggregate as a result of a command
func (acc *Account) HandleAccountCredited(event AccountCredited) {
	acc.Balance = acc.Balance + event.Amount
}


//Execute command
acc.Credit(100)
acc.Credit(150)
if err := acc.Save(); err == cqrs.Conflict {
  //this error is due to concurrent modification of the aggregate, you should retry the request
}

FeedHandler

Feed handler allows you to publish the events as a json feed for the outside world.

router.HandleFunc("/events", flux.FeedHandler(store))
router.HandleFunc("/events/{id}", flux.FeedHandler(store))

Same feed exposed by the endpoint /events is as below

{
  "description": "event feed",
  "events": [
    {
      "event_id": "47d074c3-ba83-40e2-8720-804b73a202b9",
      "url": "http://localhost:3000/events/47d074c3-ba83-40e2-8720-804b73a202b9",
      "aggregate_name": "*account.Account",
      "aggregate_version": 0,
      "event_type": "account.AccountCreated",
      "created": "Fri Apr  7 15:19:18 2017"
    },
    {
      "event_id": "174a40b6-104a-4be5-a352-4e61b524d3dc",
      "url": "http://localhost:3000/events/174a40b6-104a-4be5-a352-4e61b524d3dc",
      "aggregate_name": "*account.Account",
      "aggregate_version": 1,
      "event_type": "account.AccountCredited",
      "created": "Fri Apr  7 15:19:27 2017"
    }
  ]
}

EventConsumer

Event consumer allows you to consumer the events emitted by the aggreate in another service. you can start the event consumer like shown below, in the below example the consumer polls the aggregate service every 5 seconds to check for new events.

//stores the offset to know where to consumer from after a restart
offsetStore := flux.NewMemoryOffsetStore()
consumer := flux.NewEventConsumer("http://entityservicehost:port/events", 5 * time.Second, []interface{}{AccountCredited{}}, offsetStore)
eventCh := make(chan interface{})

//Start consuming
go consumer.Start(eventCh)

//Fetch the events and build your read models
for {
  event := <-eventCh
  switch event.(type) {
  case AccountCredited:
    fmt.Println(event.(AccountCredited))
  }
}

You could pause,resume & stop the consumer

consumer.Pause()
consumer.Resume()
consumer.Stop()

ReadModel

Read model is nothing but the result of how you interpret the events provided by the consumer shown above.

Sample application

There is a simple example application here if you would like to refer

MongoDB

mongodb as your event & offset store using mgo

import (
  "gopkg.in/mgo.v2"
  "github.com/yehohanan7/flux"
  "github.com/yehohanan7/flux/mongodb"
)

// Create mongodb session
session, err := mgo.Dial("localhost")

// ...

// Create event store
eventStore := flux.NewMongoStore(&mongodb.MongoEventStoreOptions{
  Session:               session,
  Database:              "example", // optional
  EventCollection:       "event",
  AggregateCollection:   "aggregate",
  TransactionCollection: "transaction",
})

// Create offset store
offsetStore := flux.NewMongoOffsetStore(&mongodb.MongoOffsetStoreOptions{
  Session:               session,
  Database:              "example", // optional
  Collection:            "offset",
  StoreId:               "a_unique_id_for_consumer",
})

Roadmap

  • [ ] Optimize consumers by using websockets/server push
  • [ ] Support postgres
  • [ ] publish metrics to graphite
  • [ ] Support option to emit events to external systems if required.
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].