event_sourcing_user_management_poc

PoC for user management in Event Sourcing using SQLite3

Event Sourcing User Management PoC

This is a demo web server written in Go, using simple Event Sourcing.

The goals of this demo are,

This application is not intended to be used as reference or be used in real-world. Because of the goals previously stated, security and performance are not in consideration. Also, I avoided using third-party libraries as much as possible, in order to easily transfer this experience onto Zig source code, which I use for my ongoing personal project.

You will be in trouble if you use part or whole of this application in a real product.

Architecture

The simplest description is “Snapshot-less Event Sourcing HTTP server using SQLite3 as an event store”. Everytime HTTP handler needs the current state of something (user list, one-time password for initial admin creation), the application loads every events then builds state by iterating events one-by-one.

Events are stored in SQLite3 table named user_events with dead simple schema:

Column Data type
seq INTEGER
event_name TEXT
payload BLOB

seq is auto incrementing sequential number. payload is binary data in Protobuf wire format. event_name is schema name of the payload, telling which Protobuf message to use for decoding. As this is demo application, event_name does not contain package name. Table schema is defined in init.sql file and insertion/retrieval logics are inside events/ directory. Protobuf message schemas are under proto/ directory.

Once every events are loaded, the application constructs current state from those events. These logics are in projections/ directory and they have unit tests.

Creation of demo users and one-time password is defined in setups/ directory. This directory is good candidate of unit testing but I’m lazy so there’s none.

The rest is joke. I mean, I don’t care. It’s low-quality simple-as-tutorial net/http server.

Development

This project requires Go toolchain, Protobuf compiler and dprint (source code formatter frontend). Use asdf or mise-en-place to easily install the required tools. See .tool-versions file for specific versions.

Once you setup every required tool, run the following to generate Protobuf binding code.

buf generate
# Go bindings will be generated under "gen/" directory.

Start HTTP server

# This flag generates and prints one-time password to create the first admin user.
# Copy that password and paste it to " Initial user password" form field in browser.
go run . -init-admin-creation-password

# Create demo users.
# Alice is an admin user and Bob is viewer user.
# When -create-* flag is set, the server prints login email and password to terminal.
go run . -create-alice -create-bob

# For available options, run with -help flag.

Run unit tests

# ./... means "this directory and its fucking subdirectories"
go test ./...

Format source code

# This rewrites files in-place.
dprint fmt

Check copyright and license annotation

This command requires REUSE tool.

reuse lint