Add openapi-versioning: springdoc-openapi 3.1.1 vs Spring Framework 7 API versioning
Companion module for "springdoc-openapi with Spring Boot 4.1: Generating, Customising and Versioning Your API Spec". Reuses the ApiVersionConfigurer setup from the versioning-mechanics companion project and tests what springdoc-openapi 3.1.1 actually generates for a path with multiple version-scoped handlers: a default oneOf-merged operation with an arbitrary operationId, a working GroupedOpenApi + OpenApiCustomizer fix that collapses it to one clean schema per version, and a check of the officially-versioning-supported functional-endpoint path (springdoc v3.0.2's "Add support for Spring Framework API Versioning with Functional Endpoints"), which turns out to document only one of two registered versions rather than either version separately. Co-Authored-By: Claude Sonnet 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01M1uZDXWkY1MnTfQgt4HMeQ
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
# Why the version→schema map in the fix is hand-maintained
|
||||
|
||||
[`VersionedOpenApiConfig`](../src/main/java/com/ankurm/openapiversioning/config/VersionedOpenApiConfig.java)
|
||||
keeps a small, explicit `Map<String, VersionSpec>` from version string to schema name /
|
||||
operationId / summary, rather than deriving that mapping automatically from the running
|
||||
application. This is a deliberate limitation, not an oversight, and it's worth being honest about
|
||||
why: an `OpenApiCustomizer` (`org.springdoc.core.customizers.OpenApiCustomizer`) receives exactly
|
||||
one argument, the fully-built `io.swagger.v3.oas.models.OpenAPI` document — see
|
||||
`javap org/springdoc/core/customizers/OpenApiCustomizer.class`:
|
||||
|
||||
```
|
||||
public interface org.springdoc.core.customizers.OpenApiCustomizer {
|
||||
public abstract void customise(io.swagger.v3.oas.models.OpenAPI);
|
||||
}
|
||||
```
|
||||
|
||||
By the time a customizer runs, springdoc has already folded the three `HandlerMethod`s into one
|
||||
merged `Operation` (see the previous chapter) — the association between "this specific handler
|
||||
method" and "this specific version string" has already been discarded. An `OperationCustomizer`
|
||||
(`org.springdoc.core.customizers.OperationCustomizer`) does get a `HandlerMethod` argument per
|
||||
call, which looks more promising, but it still runs once per merged operation, not once per
|
||||
original handler — it cannot see the three original mappings separately either, because springdoc
|
||||
folds first and customizes second. There is no supported extension point in 3.1.1 that intercepts
|
||||
before the fold.
|
||||
|
||||
Reflectively pulling the `version` condition back out of Spring's own `RequestMappingInfo` (via
|
||||
`RequestMappingHandlerMapping.getHandlerMethods()`) would work at the Spring MVC layer — Framework
|
||||
7 exposes it there in principle — but wiring that into springdoc's generation pipeline means
|
||||
matching springdoc's internal notion of "this operation" back to Spring's `RequestMappingInfo` by
|
||||
path and method, which is exactly the kind of implementation-detail-coupled reflection that breaks
|
||||
silently on the next springdoc minor version. A hand-maintained map keyed by the version strings
|
||||
you already wrote in your own `@GetMapping(version = ...)` annotations is three lines of
|
||||
boilerplate per version and it does not break when springdoc changes how it folds operations
|
||||
internally.
|
||||
Reference in New Issue
Block a user