go
everything written here about go — hexagonal architecture, sqlc over an orm, single-binary deploys, authorization, and the boilerplate tax you pay for all of it
go is what i write services in. it has been the day-job language at adidas and now at motogp, and it is what most of my own products run on.
what does this blog cover about go?
structure and the cost of structure, mostly. hexagonal architecture and whether the ceremony pays for itself. sqlc and pgx instead of an orm, because sql that fails at compile time beats sql that fails at 3am. shipping one self-contained binary with the migrations and config embedded in it. authorization — owner scoping, server-stamped ownership, the check that hides when you scatter it across layers. and the honest counterweight to all of it: the boilerplate tax, fourteen entities and an 890-line router.
the through-line is that go pushes back when you get clever, and most of these posts are about finding out where pushing back was right.
these are war stories, not tutorials. every one of them starts from something that broke, or something i built and then had to argue with myself about.
- verifactu in go: a sha-256 hash chain is spain's answer to invoice fraud — implementing spain's anti-fraud e-invoicing as an append-only chained-hash ledger, modelled in the pure domain layer
- i didn't leave go for rust. i split my stack. — the 'which language' question is the wrong question. go for services, rust for tools — and here's the exact line.
- i audited my side project like it was about to go viral (before it was) — seed a fake gone-viral database, EXPLAIN ANALYZE the hot paths, and find the public stats page that was a denial-of-service you host yourself
- your rate limiter trusts x-forwarded-for. mine did too, until it was measured. — two measured bypasses of an anti-abuse limiter — a rotating forwarded header and a missing cookie — and the trusted-proxy fix
- sqlc + pgx over an orm: type-safe sql that fails at compile time — hand-written sql compiled to type-safe go, and why the orm in go.mod was dead code
- testcontainers 103 — testing: the real deal???
- owner-scoped rbac: enforcing 'you can only see your own' — a two-tier global-vs-owned permission model in go, and the authorization inconsistency that hides when you scatter the check across layers
- the boilerplate tax: fourteen entities, an 890-line router, and go — an honest retrospective on structural duplication in a hexagonal go codebase — and when copy-paste actually beats codegen
- shipping a single self-contained go binary — embedded migrations and a self-writing config, so the service boots with zero external files
- hexagonal architecture in go without the ceremony — ports and adapters + ddd in idiomatic go, and exactly where the discipline pays off
- testcontainers 102 — testing: the real deal??
- testcontainers 101 — testing: the real deal
related
if you want the other half of the stack, the tools rather than the services, see rust — and why i didn’t leave go for rust for exactly where the line falls.