Skip to content

feat: Support multiple OpenAPI specs per server#97

Merged
thced merged 18 commits into
masterfrom
feat/multiple-specs
May 22, 2026
Merged

feat: Support multiple OpenAPI specs per server#97
thced merged 18 commits into
masterfrom
feat/multiple-specs

Conversation

@thced

@thced thced commented May 22, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds OpenApiServer.Builder.addSpec(spec, handlers, validators) so one server can host multiple OpenAPI specs (e.g. v1/v2 side-by-side or public + admin in one process)
  • Each spec is mounted at its own basePath as an independent binding with its own handler/validator maps — operationIds and security-scheme names only need to be unique within a single spec
  • Legacy single-spec API (.spec() / .handler() / .securityValidator()) is preserved; mixing it with addSpec() in the same builder is rejected at build time
  • Duplicate basePath across bindings is rejected; nested prefixes (/ plus /api/...) are allowed and resolved by the JDK HttpServer's longest-prefix-match

Design: docs/superpowers/specs/2026-05-22-multiple-specs-design.md
Implementation plan: docs/superpowers/plans/2026-05-22-multiple-specs.md

Test plan

  • mvn test — 470 unit tests pass (5 new in MultiSpecServerTest covering namespacing, duplicate basePath, per-binding security wiring, legacy+addSpec rejection)
  • mvn verify — 67 integration tests pass (new MultiSpecServerIT boots a real HttpServer with two derived specs at /api/v1 and /api/v2)
  • No new OpenAPI fixture files — multi-spec tests derive both Spec instances from the existing openapi.json via a new SpecFixtures helper
  • README documents the new addSpec() usage

thced added 18 commits May 22, 2026 15:11
The constructor now takes List<SpecBinding> instead of Spec; the Builder
synthesises a single-element list so the public API is unchanged.
HandlerConfig drops the handlers and securityValidators fields (moved to
SpecBinding). The not-found catch-all context is registered only when no
binding has a root base path.
Introduces two addSpec() overloads on OpenApiServer.Builder: one accepting
a Spec, handler map, and security-validator map, and one convenience form
with no validators. The build() method is rewritten to either consume the
bindings list (addSpec path) or synthesise a single binding from the legacy
spec()/handlers()/securityValidator() fields. Mixing the two forms throws
IllegalStateException. Cross-binding duplicate-basePath detection added.
@sonarqubecloud

Copy link
Copy Markdown

@thced thced merged commit ce48fc9 into master May 22, 2026
6 checks passed
@thced thced deleted the feat/multiple-specs branch May 22, 2026 14:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant