Serve on a go/transport server¶
transport-openapi mounts onto a plain *http.ServeMux, which is exactly what a
go/transport HTTP server is built around.
Register your API docs on the same mux you give the transport server, and they are
served alongside your API — same process, same port, same origin.
import (
"net/http"
transporthttp "gitlab.com/phpboyscout/go/transport/http"
openapi "gitlab.com/phpboyscout/go/transport-openapi"
)
//go:embed openapi.yaml
var spec []byte
func newServer() (*transporthttp.Server, error) {
mux := http.NewServeMux()
// API handlers…
mux.HandleFunc("GET /v1/things", listThings)
// API docs on the same mux.
if err := openapi.Register(mux, spec,
openapi.WithSpecPath("/v1/openapi.yaml"),
openapi.WithDocsPath("/v1/docs/"),
); err != nil {
return nil, err
}
// Hand the mux to the transport server (health, lifecycle, middleware…).
return transporthttp.NewServer(mux /* , transport options… */)
}
Now the transport server's lifecycle, health endpoints and middleware apply to the
whole surface, and /v1/docs/ is a first-class route on it.
Why the same server¶
Serving the docs from the transport server (rather than a separate static host) keeps the spec and the try-it console same-origin with the API they document — so the console can call your endpoints without any CORS configuration. See Same-origin docs by design.
Security headers and the transport chain¶
Register applies go/transport's security-header middleware to the docs/spec
handlers by default. If your transport server already wraps the whole mux in an
equivalent header chain, opt the handler out with
WithoutSecurityHeaders to avoid setting them
twice.