Fairway
Tiny, independent vertical slices. One shared event log. Zero coupling.
The Problem
Vertical slicing promises independent feature development. Reality usually delivers hidden coupling.
Shared databases — slices touch the same tables. Schema changes require coordination.
Stream-per-aggregate — consistency boundaries are fixed at design time. Commands that cross aggregates need sagas.
Read more: The vertical slicing illusion →
The Solution
Events as the only contract. Slices share nothing but the event log. No shared tables, streams, or types.
Dynamic consistency boundaries. Each command's boundary emerges from what it actually reads — not from architectural diagrams.
Read more: Dynamic consistency →
Architecture
┌─────────────────────────────────────────┐
│ Testing Helpers │ given / when / then
├─────────────────────────────────────────┤
│ HTTP Layer │ HttpChangeRegistry / HttpViewRegistry
├─────────────────────────────────────────┤
│ Framework Layer │ Command / View / Automation
├─────────────────────────────────────────┤
│ FoundationDB │ events (DCB) / queues / KV read models
└─────────────────────────────────────────┘
One datastore for everything: events, job queues, read model persistence.
Three Patterns
Every module implements one of these:
User action Event log Projection
│ │ │
▼ ▼ ▼
┌──────────┐ ┌───────────────┐ ┌──────────┐
│ Command │───▶│ Events │───▶│ View │
└──────────┘ └───────┬───────┘ └──────────┘
│
┌───────▼──────┐
│ Automation │ (View → Command, no user)
└──────────────┘
Quick Start
Prerequisites: Go 1.24+, FoundationDB installed.
git clone https://github.com/err0r500/fairway
cd fairway/examples/todolist
go generate ./...
go run .
curl -X POST http://localhost:8080/api/lists/my-list \
-H "Content-Type: application/json" \
-d '{"name": "Shopping"}'
curl http://localhost:8080/api/lists/my-list
Package Overview
| Package | Description |
|---|---|
| Framework | Commands, views, automations, queues, KV read models |
dcb/ |
DCB-compliant event store on FoundationDB |
utils/ |
HTTP helpers, idempotency middleware |
testing/ |
given, when, then test helpers |
Learn More
- The Problem — why vertical slicing fails
- The Solution — events as contracts
- DCB Store — the foundation
- Framework — commands, views, automations