ArchitectureKit
Building blocks for applications based on Domain-Driven Design, CQRS, and Event Sourcing, in Go and on top of EventSourcingDB. A kit rather than a framework – every piece can be used on its own, and nothing happens behind your back.
Open source under the MIT license.
- License
- MIT License
- Language
- Go
Two places where event-sourced applications rely on luck.
Two concurrent writes to the same thing on the way in, and a read right after a write on the way out. ArchitectureKit handles both, and it covers both sides of an application – commands, events, and state for writing, projections, views, and queries for reading.
- Every command writes with its preconditions. The database rejects duplicates and concurrent changes, not your luck.
- A read can wait for your own write. Views track the revision they have seen, and a query waits until it is reached.
- Tests need no database. A test package checks deciders and projections without a database, and a test calls queries directly.
var acquireBook = architecturekit.NewDecider(bookState,
func(ctx context.Context, cmd AcquireBook, book Book) ([]architecturekit.Event, error) {
if book.IsAcquired {
return nil, architecturekit.NewDomainError("book %s has already been acquired", cmd.BookID)
}
return []architecturekit.Event{
BookAcquired{Title: cmd.Title, Author: cmd.Author, ISBN: cmd.ISBN},
}, nil
})
A decider receives a command and the current state, and returns the events to write. Execute reads the events, evolves the state, decides, and writes.
Both sides of an event-sourced application.
Every capability links to the part of the docs that explains it.
Decisions on commands
- Commands, events, and statePlain structs, with the state evolved from the events of a subject.Defining Commands
- DecidersThe decision on a command, as a function of the command and the state.Making Decisions
- PreconditionsPrevent duplicates, guard against concurrent changes, enforce rules across subjects.Using Preconditions
- Versioned eventsUpcasters translate stored events of an old type into the new one, for state and projections alike.Versioning Events
Views that keep up
- ProjectionsTurn events into views with a typed handler per event type, and resume where they stopped.Projections
- ViewsHold the data that queries read, by key and by index, with a revision for every item.Defining Views
- QueriesFilter, order, page, and count the items of a view.Defining Queries
- Reading your own writesWait until a view has seen the events you have written.Reading Your Own Writes
An API for commands and queries
- Commands over HTTPMap requests to commands, for the user who makes them.Handling Commands over HTTP
- AuthorizationRefuse a command before it is executed.Handling Commands over HTTP
- Queries over HTTPAnswer queries in the default format, or in your own.Handling Queries over HTTP
- Status codesEvery error maps to the status code that matches it.Mapping Errors to Status Codes
Tests without a database
- DecidersGiven events, when a command, then events, a rejection, or preconditions.Testing Deciders
- UpcastersCheck the translation of old events.Testing Deciders
- ProjectionsApply stored events to a projection and inspect its view.Testing Projections
- QueriesAnswer queries against a view filled for the test.Testing Queries
Try it yourself.
Quickstart
This quickstart gets a first command running with ArchitectureKit in a few minutes.
Start the quickstart →First Steps with ArchitectureKit
This tutorial builds a small library in Go step by step.
Start the tutorial →ArchitectureKit Documentation
Quickstart, Fundamentals, and Guides.
Open the docs →Planning something bigger?
Whether you need a quote, support, or a second opinion on your architecture – we are happy to help.