go-api-design · git:20261029.84ab386 · 2026-10-29 · sha256 cf120300c3e29aac
go-api-design git:20261029.84ab386A
Immutable. This exact content never changes and is served at /api/v1/blob/cf120300c3e29aac.
--- name: go-api-design description: > Use when designing or reviewing Go public APIs, generic constraints and type inference, interface method sets or typed nil, consumer-owned contracts, SOLID tradeoffs, constructors and functional options, or creation, composition and behavioral design patterns such as adapters, middleware, observers and state. --- # Go API Design ## Route by decision | Need or symptom | Default / local reference | |---|---| | Generic signature, `~`, inference, `comparable`, generic methods | Preserve type relationships, not abstraction for its own sake — [Generics](references/generics.md) | | Interface boundary, method set, typed nil, SOLID, substitutability | Define the consumer's behavioral contract — [Contracts](references/contracts.md) | | Constructor, singleton, factory, builder, clone, pool, options | Ordinary construction first — [Construction](references/construction-patterns.md) | | Adapter, bridge, composite, decorator, facade, flyweight, proxy | Explicit composition — [Composition](references/composition-patterns.md) | | Chain, command, iterator, mediator, memento, observer, state, strategy, template, visitor | Functions and owned state — [Behavior](references/behavior-patterns.md) | Load only the needed local reference. For Composition and Behavior, read the task table and contents first, then only the relevant sections. Sibling and online documentation is optional. Pattern names do not mandate interfaces or structs. ## Workflow 1. **Read consumers.** Record supported versions, callers and dependency owners. Specify inputs, zero/nil, missing versus failed results, ordering, partial success, blocking, mutation and cleanup. 2. **Minimize representation.** Prefer concrete values/functions; function parameters for one policy, consumer-owned interfaces for capabilities, type parameters for relationships across types. External boundaries may have one implementation. 3. **State invariants.** Validate external data before side effects. Define constructor copy/borrow rules for slices/maps, zero-value usability, resource closers and independence of built snapshots. 4. **Wire at the owner.** Construct dependencies explicitly in `main` or their owning scope and pass them to consumers. Prefer stdlib contracts. Expose startup errors and release acquisitions when later construction fails. 5. **Test real consumers.** Method satisfaction proves only compilation. Exercise size limits, EOF/short writes, errors, cancellation, typed nil, aliasing and failure-state preservation across implementations. 6. **Finish migration.** Update all affected callers, docs and tests. Document signature/default/error/ownership/lifecycle changes; unresolved consumers block completion, rather than count as compatibility work. For renames, optionally consult [semantic tool limits](../go-idiomatic/references/workflow-versions.md#semantic-navigation-and-refactoring) if **go-idiomatic** is installed. ## High-risk guardrails - **Interfaces are not pointers.** A typed nil pointer stored in an interface is non-nil. Return literal `nil` for success; do not hide producer bugs with a universal reflection-based nil check. Pointer/value method sets differ. - **`comparable` is not panic immunity.** Since Go 1.20, `any` can satisfy a `comparable` constraint; comparing equal dynamic slice/map/function types or using an unhashable dynamic map key can panic. NaN is not equal to itself. - **Composition is not inheritance.** Embedding promotes methods; it does not provide virtual dispatch or automatically preserve wrapper optional interfaces. - **Ownership survives a pattern name.** Shallow copies keep nested aliases; `sync.Once` protects initialization, not future mutation; `sync.Pool` neither bounds resources nor guarantees retention or cleanup. Never copy used sync types. - **SOLID is a tradeoff.** No fixed interface method count, mandatory repository, automatic registry or interface-per-struct rule. Keep closed branching when clear. ## Version gate Read `go.mod`, `toolchain`, CI and supported consumers before using newer syntax. Generics require Go 1.18; comparison constraint satisfaction changed in 1.20; `cmp`/`slices`/`maps` and `sync.OnceValues` arrived in 1.21; range-over-function and iterator collection helpers in 1.23; generic aliases in 1.24. This bundle's isolated [examples](examples/go.mod) declare **Go 1.25.0**; older versions are not certified. ## Completion and evidence Report toolchain, exact commands, observed results and unperformed checks. Compile acceptance does not prove behavior, race freedom, security or live API compatibility. The [README](README.md) records commands, coverage, correction decisions and the [upstream notice](LICENSE.upstream). Optional handoffs: **go-tdd** for test workflows, **go-concurrency** for synchronization/lifetimes, **go-system-design** for application boundaries, and **go-algorithms** for data-structure implementation; none is required.