Case Studies

Whisky Collection API

A Rust/Axum API for tracking whisky collections — built to learn real backend Rust instead of just reading about it.

Problem

I wanted to write real backend Rust — routing, typed extractors, proper error handling — but toy examples never teach the parts that actually matter. I needed a project with real data, real constraints, and a reason to keep coming back to it.

Approach

Build a whisky collection tracker as a full-stack Rust application: a REST API with server-rendered pages, backed by PostgreSQL, with enough moving parts to encounter real engineering problems.

The key technical decisions:

Stack

Rust, Axum, Askama, Datastar, sqlx, PostgreSQL, Meilisearch, NATS JetStream, S3, Tailwind CSS + DaisyUI.

Outcome

The API runs in production. It has its own migration-driven schema, test harness, merge queue with CI tiers, and Beads issue tracker. The codebase lives in the same monorepo as this site but has its own toolchain (mise), hooks, and deployment pipeline.

What it taught me: Rust’s type system forces decisions about data shape up front, which is uncomfortable at first and then makes the rest of the code much harder to get wrong. The compiler catches entire categories of bugs that in other languages would surface at runtime or in production.