Extract pkg/openapi into the transport-openapi companion module¶
- Authors
- Matt Cockayne, Claude Opus 4.8 (AI drafting assistant)
- Date
- 2026-07-22
- Status
- IMPLEMENTED (2026-07-22).
go/transport-openapiv0.1.0 published; GTB cut-over deletespkg/openapi(pure deletion — zero consumers, no repoint). Q1 (docs placement) resolved: dedicatedtransport-openapi.go.phpboyscout.ukmicrosite. Coverage 92.3%; gitleaks allowlist added for the vendored Stoplight assets; docs live. - Related
- module-extraction playbook (§5 procedure; §10.5 provider/companion = README-only),
output extraction (the previous, more involved extraction),
extraction report (openapi row — decision: own
transport-openapicompanion)
1. Summary¶
pkg/openapi serves an OpenAPI specification and an interactive
Stoplight Elements docs site (with a
"try it" console) from a single Register(mux, spec, opts...) call. It is
extracted to a standalone companion module
gitlab.com/phpboyscout/go/transport-openapi — not folded into go/transport
core.
This is the cleanest extraction in the programme:
- Already framework-free. Zero
go-tool-baseimports. Its only dependencies arecockroachdb/errorsand the already-extractedgo/transit/http(theMiddlewaretype) andgo/transport/http(SecurityHeadersMiddleware/SecurityHeadersOption). It injects a caller-provided*http.ServeMux. - Zero GTB consumers. Nothing in
go-tool-basereferences it — it is a downstream-facing library feature. So the GTB side is a pure deletion: no repoint, no adapter, no new GTB dependency. - Small. 174 LOC of Go (
openapi.go) + tests, plus a ~2.4 MB embedded asset blob.
2. Why a companion module, not go/transport core¶
go/transport is the server stack (http, grpc, gateway, support code). The
OpenAPI handler belongs to that world — it mounts on a transport server's mux —
but it carries a cost the rest of the stack does not:
| Asset | Size |
|---|---|
assets/web-components.min.js (Stoplight Elements) |
2.08 MB |
assets/styles.min.css |
297 KB |
That ~2.4 MB is //go:embed-ed into the binary. Folding openapi into
go/transport core would add 2.4 MB to every transport-server binary, even
those that never serve API docs. A separate transport-openapi module keeps the
embed opt-in: only a tool that imports it pays for it. This mirrors the
transport-metrics companion direction and the general transport-<companion>
pattern.
3. Module shape & naming¶
Per the playbook §2 and the provider/companion convention (§10.5):
| Concern | Value |
|---|---|
| Module | gitlab.com/phpboyscout/go/transport-openapi |
| GitLab project | phpboyscout/go/transport-openapi |
| Package name | package openapi (bare, single concept) |
| Docs microsite | transport-openapi.go.phpboyscout.uk (dedicated, Q1 resolved) |
The public API moves verbatim — no redesign:
func Register(mux *http.ServeMux, spec []byte, opts ...Option) error
func WithSpecPath(p string) Option
func WithDocsPath(p string) Option
func WithTitle(t string) Option
func WithSecurityHeaderOptions(opts ...transporthttp.SecurityHeadersOption) Option
func WithoutSecurityHeaders() Option
go.mod requires (matching GTB's current pins for lockstep):
gitlab.com/phpboyscout/go/transport v0.1.1gitlab.com/phpboyscout/go/transit v0.1.0github.com/cockroachdb/errors v1.14.0
4. Dependency-footprint guard¶
The companion legitimately depends on go/transport and go/transit, so those
are allowed. depfootprint_test.go forbids what a docs handler should never
pull:
gitlab.com/phpboyscout/go-tool-base(the whole point)spf13/viper,spf13/pflag,spf13/cobra- cloud SDKs (
aws-sdk-go,cloud.google.com/go,Azure/azure-sdk)
OpenTelemetry is not forbidden here: go/transport/go/transit may pull an
OTel-compatible seam transitively, exactly as go/observability does. The guard
checks go list -deps ./... and asserts the forbidden set is absent.
5. Migration procedure (playbook §5)¶
- Bootstrap
phpboyscout/go/transport-openapito §3 (branding-free scaffold; cicd components at GTB's pin v0.24.1, Go 1.26.5;enable_e2e: false; dedicated Diátaxis microsite withzensical.toml+zensical-pages+requirements-lock.txt, custom domaintransport-openapi.go.phpboyscout.ukwith LE cert, per Q1). - Move the code verbatim:
openapi.go,assets/*, and the tests (openapi_test.go,openapi_coverage_test.go— both externalpackage openapi_test, importing only the package + stdlib + testify, so they move cleanly). Adddepfootprint_test.go. - Shared-transitive alignment (§10.6/§11.5): after
go mod tidy, diff every shared transitive against GTB and bump to match; expect the security stage to flag anything the lean graph exposes. - Cut
v0.1.0via the Release-MR flow (human-gated). - GTB cut-over (single MR,
feat): deletepkg/openapi— no repoint (zero consumers), no new GTB dependency.just ci; add adocs/reference/migration/v0.x-openapi-extracted.mdnote. - GTB docs cross-reference: restub
docs/explanation/components/openapi.mdto point at the module; repoint thehow-to/serve-api-docs.mdguide to importgo/transport-openapi; sweepcomponents/index.mdand the grpc/gateway/http pages' passing mentions. - Downstream adopters (any tool using
go-tool-base/pkg/openapi, e.g. afmpeg) repoint togitlab.com/phpboyscout/go/transport-openapi.
6. Version compatibility¶
transport-openapi depends on go/transport (and go/transit). Pre-1.0 the
transport API can break in a minor, and MVS can select a newer transport than the
companion was built against. Document the compatibility (transport-openapi
v0.1.x ↔ transport v0.1.x) in the README, mirroring the core↔sub-module matrix
guidance (§10.10).
7. Open question — RESOLVED (2026-07-22)¶
- Q1 — docs placement. → Dedicated
transport-openapi.go.phpboyscout.ukmicrosite, consistent with the leaf modules (output,workspace, …), rather than README-only. Full Diátaxis nav (tutorial → how-to → explanation → pkg.go.dev),zensical-pages, custom domain + LE cert, branding-free scaffold.
8. Acceptance criteria¶
gitlab.com/phpboyscout/go/transport-openapipublished atv0.1.0; resolves from the proxy; builds in a throwaway consumer (-buildvcs=false).depfootprint_test.gogreen (no go-tool-base / viper / pflag / cobra / cloud SDK); module ≥90% coverage (the existing suite already coversRegisterand the option/error paths).- GTB cut-over MR (
feat(openapi):) deletespkg/openapi,just cigreen, migration note added; docs swept. - README documents the API and the
transportcompatibility.