A lightweight, cloud-native key-value store written in Go. It features a pluggable frontend layer (REST and gRPC), a pluggable persistence backend (file WAL and PostgreSQL), and automatic state restoration on startup by replaying recorded events.
- REST API — simple HTTP/1.1 interface (
GET,PUT,DELETE) via Gorilla Mux - gRPC API — high-performance RPC with TLS, defined via Protocol Buffers
- Pluggable frontends — swap between REST, gRPC, or a no-op zero frontend at runtime
- Pluggable transaction loggers — file-based WAL or PostgreSQL-backed persistence
- Crash recovery — state is fully restored on startup by replaying the event log
- Thread-safe — concurrent reads and writes handled with
sync.RWMutex - Minimal Docker image — multi-stage build producing a scratch-based binary image
┌──────────────────────────────────────┐
│ main.go │
│ (wires frontend ↔ store ↔ logger) │
└───────────┬──────────────┬───────────┘
│ │
┌────────▼──────┐ ┌────▼────────────┐
│ frontend/ │ │ transact/ │
│ REST | gRPC │ │ file | postgres │
└────────┬──────┘ └────┬────────────┘
│ │
┌────▼──────────────▼────┐
│ core/ │
│ KeyValueStore │
│ (in-memory map+mutex) │
└────────────────────────┘
git clone https://github.com/qoofa/key-value-store.git
cd key-value-store
cp env.example .env
make compose-upThe REST API will be available at http://localhost:8080.
git clone https://github.com/qoofa/key-value-store.git
cd key-value-store
cp env.example .env
go run .All endpoints are under /v1/{key}.
| Method | Path | Body | Response | Description |
|---|---|---|---|---|
PUT |
/v1/{key} |
plain text | 201 Created |
Store a value |
GET |
/v1/{key} |
— | 200 OK / 404 |
Retrieve a value |
DELETE |
/v1/{key} |
— | 200 OK |
Delete a key |
# Store a value
curl -X PUT http://localhost:8080/v1/greeting -d "hello world"
# Retrieve the value
curl http://localhost:8080/v1/greeting
# Delete the key
curl -X DELETE http://localhost:8080/v1/greetingCopy env.example to .env and fill in the values. All configuration is driven by environment variables.
| Variable | Description | Example |
|---|---|---|
FRONTEND_TYPE |
Frontend to use: rest, grpc, zero |
rest |
PORT |
HTTP port (REST frontend only) | 8080 |
TLOG_TYPE |
Transaction logger: file, postgres |
postgres |
TLOG_FILENAME |
Log file path (file logger only) | transactions.log |
TLOG_DB_HOST |
PostgreSQL host | localhost |
TLOG_DB_DATABASE |
PostgreSQL database name | transactions |
TLOG_DB_USERNAME |
PostgreSQL username | kvs |
TLOG_DB_PASSWORD |
PostgreSQL password | secret |
Generate a self-signed certificate for local development:
mkdir -p cert
openssl req -x509 -newkey rsa:4096 \
-keyout cert/key.pem -out cert/cert.pem \
-sha256 -days 365 -nodes \
-subj "/C=US/ST=State/L=City/O=Dev/OU=DevOps/CN=localhost"- Go ≥ 1.23
- Docker ≥ 24 + Docker Compose ≥ 2
makeorjustprotoc+protoc-gen-go(only if editing.protofiles)
make build # compile binary
make test # run all tests
make lint # run golangci-lint
make compose-up # start Postgres + the app
make compose-down # tear everything down
make proto # regenerate protobuf code
make clean # remove build artifacts
make help # list all targetsOr with just:
just build
just test
just lint
just compose-up.
├── core/ # In-memory store, TransactionLogger interface, event types
├── frontend/ # REST and gRPC server implementations + factory
├── transact/ # File and PostgreSQL transaction logger implementations + factory
├── pb/ # Generated protobuf code + .proto definition
├── grpc_client/ # Example gRPC client
├── Dockerfile # Multi-stage build (builder → scratch)
├── compose.yml # Docker Compose (app + Postgres)
├── main.go # Entry point — wires everything together
└── env.example # Reference configuration
See CONTRIBUTING.md. All contributions are welcome — bug reports, feature requests, and pull requests.
MIT © qoofa