-
Notifications
You must be signed in to change notification settings - Fork 0
Router Selection
Two independent questions: which routers' routes appear in the document, and which router serves it.
openapi.NewConfig( openapi.WithIncludeRouters("default", "partner"), openapi.WithExcludeRouters("internal"), openapi.WithServeOnRouter("default"), openapi.WithServePath("/openapi.json"), )
IncludeRouters |
Result |
|---|---|
| empty (default) | the default router only |
"*" |
every router |
| a list of names | exactly those |
ExcludeRouters is applied after include, which is what makes the
"everything except" case expressible:
openapi.WithIncludeRouters("*"), openapi.WithExcludeRouters("internal", "metrics", "health"),
The generator used to collect from every router, so a route on an internal-only listener was published in the document served on the public one.
A router existing on a separate port is usually a statement that its routes are not for the same audience. The document should not contradict that.
This is defence in depth rather than the only protection: a route also has to
implement OpenAPIRoute to appear at all, so an internal endpoint that never
declares itself is excluded twice over. But "the operator forgot" is a normal
state of the world, and the safe default is the one that survives it.
openapi.WithServeOnRouter("docs") // empty means the default router openapi.WithServePath("/openapi.json")
The two are independent, and the useful combinations follow from that:
A public document on the public listener — the common case, and the default.
openapi.NewConfig() // include: default only; serve: default; /openapi.json
A partner-facing document, served internally. Generate from the partner router, serve on an internal one, so the specification is reviewable without being published:
openapi.NewConfig( openapi.WithIncludeRouters("partner"), openapi.WithServeOnRouter("internal"), )
Everything, internally. A complete document including operational routes, reachable only from the private network:
openapi.NewConfig( openapi.WithIncludeRouters("*"), openapi.WithServeOnRouter("internal"), openapi.WithServePath("/full-openapi.json"), )
Register the extension twice with different configurations — the routes are different, and so are the serve paths:
app := rex.New( openapi.WithOpenAPI(openapi.NewConfig( openapi.WithTitle("Public API"), openapi.WithServePath("/openapi.json"), )), openapi.WithOpenAPI(openapi.NewConfig( openapi.WithTitle("Internal API"), openapi.WithIncludeRouters("*"), openapi.WithServeOnRouter("internal"), openapi.WithServePath("/openapi.json"), )), )
Each extension instance holds its own configuration and generates its own document. The serve paths only need to differ within a router.
app := rex.New( openapi.WithOpenAPI(openapi.NewConfig(openapi.WithServePath("/openapi.json"))), swagger.WithSwagger(nil), )
Point the UI at wherever the document is served — including on a different router, if the UI is internal and the document is not.
A route registered to a router nobody created is a startup error from the
framework, before the generator ever runs. Naming a nonexistent router in
IncludeRouters is not an error — it simply matches nothing, and the document
comes out smaller than expected. Check the route count if a document looks thin.
Ecosystem