# openapi-versioning Companion code for **springdoc-openapi with Spring Boot 4.1: Generating, Customising and Versioning Your API Spec** on [ankurm.com](https://ankurm.com). Reuses the exact `ApiVersionConfigurer` setup from the companion project for [Spring Framework 7 API Versioning: The Complete Guide](https://ankurm.com/spring-framework-7-api-versioning-guide/) and asks one question on top of it: once springdoc-openapi 3.1.1 is added, what does it actually generate for a path with multiple `version`-scoped handlers — and how do you get a clean, per-version spec out of it? **Tested with:** Spring Boot 4.1.1 / Spring Framework 7.0.9 / springdoc-openapi 3.1.1 / JDK 25 (Temurin 25.0.4.1+1). ## Quickstart ```bash mvn test # runs everything, regenerates docs/output/ mvn spring-boot:run # then, in another shell: curl http://localhost:8080/v3/api-docs # the merged oneOf (default) curl http://localhost:8080/v3/api-docs/accounts-v2 # the collapsed, clean v2-only spec open http://localhost:8080/swagger-ui.html # group selector: default / accounts-v1 / accounts-v1.1 / accounts-v2 ``` ## Where things are | | | |---|---| | Versions and setup | [docs/01-versions-and-setup.md](docs/01-versions-and-setup.md) | | What springdoc actually generates for a versioned path | [docs/02-what-springdoc-actually-generates.md](docs/02-what-springdoc-actually-generates.md) | | Why the fix's version→schema map is hand-maintained | [docs/03-why-a-hand-maintained-map.md](docs/03-why-a-hand-maintained-map.md) | | The functional-endpoint path: officially supported, and worse | [docs/04-the-functional-endpoint-path.md](docs/04-the-functional-endpoint-path.md) | | The fix: one GroupedOpenApi per version | [docs/05-the-grouped-openapi-fix.md](docs/05-the-grouped-openapi-fix.md) | | Known issues, checked directly | [docs/06-known-issues.md](docs/06-known-issues.md) | ## Captured output Every figure quoted in the article is one of these files, regenerated by `mvn test`: | File | What it shows | |---|---| | [docs/output/00-versions.txt](docs/output/00-versions.txt) | Exact resolved versions, including Maven Central metadata for springdoc 3.1.1 | | [docs/output/01-versioned-runtime-behaviour.txt](docs/output/01-versioned-runtime-behaviour.txt) | The three `/accounts/{id}` versions serving their real, distinct shapes | | [docs/output/02-what-springdoc-actually-generates.txt](docs/output/02-what-springdoc-actually-generates.txt) | The default `/v3/api-docs` merging all three versions into one `oneOf` operation | | [docs/output/05-grouped-openapi-fix.txt](docs/output/05-grouped-openapi-fix.txt) | Three `GroupedOpenApi` groups, each collapsed to one clean schema | | [docs/output/06-functional-endpoint-path.txt](docs/output/06-functional-endpoint-path.txt) | The officially-versioning-supported functional-endpoint path silently documenting only one of two registered versions | ## Source layout - `web/` — the annotated `@GetMapping(version = ...)` `AccountController` and its three response records. - `functional/` — the `RouterFunction`-based `WidgetHandler`/`WidgetRouterConfig`, Framework 7's officially-versioning-supported alternative. - `config/WebConfig.java` — the `ApiVersionConfigurer` setup, unchanged from the versioning-mechanics companion project. - `config/VersionedOpenApiConfig.java` — the three per-version `GroupedOpenApi` beans and the `OpenApiCustomizer` that makes them clean.