API

Type-safe slogging

The default slog API is loose enough that a careless line ships broken JSON to production. Pin it down with Attr constructors, LogAttrs, a context-borne logger, and sloglint.

Hoisting wire plumbing out of your Go handlers

Four of the five steps in every unary RPC handler are wire plumbing. Pin the service function signature and they fit in one generic adapter per transport.

Accepted proposal: UUID in the Go standard library

Notes on Go's newly accepted uuid proposal and the tradeoffs behind the API.

What's the ideal dispatch mechanism?

Switch, map of functions, and interface registry for dispatching in Go.

Is passing user ID through context an antipattern?

Why the middleware-to-handler boundary is a special case for context values.

What belongs in Go's context values?

A simple litmus test for when to use context values in Go.

Wrapping a gRPC client in Go

How to wrap a generated gRPC client behind a clean Go API so users never have to touch protobuf types or connection management directly.

Mutate your locked state inside a closure

Why your mutex wrapper should accept a closure for mutation instead of a plain value, with examples from the standard library and Tailscale.

Your Go tests probably don't need a mocking library

Practical patterns for mocking in Go without external libraries. Learn to mock functions, methods, interfaces, HTTP calls, and time using only the standard library

Revisiting interface segregation in Go

Apply SOLID's Interface Segregation Principle in Go with consumer-defined contracts. Learn why small interfaces and implicit implementation matter.

Avoiding collisions in Go context keys

Master Go context keys with custom types, avoid collisions using empty structs, and learn accessor patterns for safe request-scoped values.

Lifecycle management in Go tests

Master Go test lifecycle with t.Cleanup(), subtests, and TestMain. Learn per-test, grouped, and package-wide setup patterns effectively.

You probably don't need a DI framework

Dependency injection in Go doesn't need Dig or Wire. Learn why manual wiring beats reflection magic and how Go's design makes DI frameworks overkill.

Deferred teardown closure in Go testing

Return teardown closures from test helpers to manage cleanup elegantly. Learn patterns for temp files, mock servers, and t.Cleanup() usage.

Stacked middleware vs embedded delegation in Go

Compare middleware stacking with embedded delegation in Go HTTP servers. Learn when to override ServeHTTP for simpler request handling.