Go

Notes on the Go programming language — interfaces, concurrency, testing, and patterns that have held up in production.

Splintered failure modes in Go

Simplify Go error handling by consolidating validation and system errors. Learn when to return boolean vs error for clearer failure modes.

Re-exec testing Go subprocesses

Test Go subprocesses with the re-exec pattern: spawn your test binary as a subprocess to emulate real command behavior reliably.

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.

Organizing Go tests

Organize Go tests with in-package, external _test packages, and integration tests. Learn white-box vs black-box testing conventions.

Subtest grouping in Go

Organize Go subtests with t.Run nesting and parallel execution. Learn patterns for setup, teardown, and readable test hierarchies.

Let the domain guide your application structure

Organize Go apps by domain, not technology. Learn why models/controllers structure hurts and how bounded contexts create better separation.

Test state, not interactions

Avoid brittle AI-generated tests that check implementation details. Write maintainable tests that verify behavior, not method calls.

Early return and goroutine leak

Prevent goroutine leaks caused by early returns with unbuffered channels. Learn buffering, draining, errgroup patterns, and goleak testing.

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.

Gateway pattern for external service calls

Separate business logic from external service calls using the Gateway pattern. Apply dependency inversion and interface segregation in Go.

Flags for discoverable test config in Go

Control Go test behavior with custom flags instead of build tags or env vars. Enable integration and snapshot tests with discoverable CLI options.

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.

Preventing accidental struct copies in Go

Prevent dangerous struct copies with noCopy sentinel and go vet's copylock checker. Protect mutexes and sync primitives from value copies.

Go 1.24's "tool" directive

Pin tool versions in Go 1.24 with the new 'tool' directive. Replace tools.go pattern with native go.mod support for project tooling.