Skip to content

Commit cce2771

Browse files
committed
Add API versioning reference documentation
See gh-34569
1 parent bf78980 commit cce2771

File tree

9 files changed

+469
-0
lines changed

9 files changed

+469
-0
lines changed

framework-docs/modules/ROOT/nav.adoc

+3
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@
197197
*** xref:web/webmvc/mvc-uri-building.adoc[]
198198
*** xref:web/webmvc/mvc-ann-async.adoc[]
199199
*** xref:web/webmvc-cors.adoc[]
200+
*** xref:web/webmvc-versioning.adoc[]
200201
*** xref:web/webmvc/mvc-ann-rest-exceptions.adoc[]
201202
*** xref:web/webmvc/mvc-security.adoc[]
202203
*** xref:web/webmvc/mvc-caching.adoc[]
@@ -225,6 +226,7 @@
225226
**** xref:web/webmvc/mvc-config/static-resources.adoc[]
226227
**** xref:web/webmvc/mvc-config/default-servlet-handler.adoc[]
227228
**** xref:web/webmvc/mvc-config/path-matching.adoc[]
229+
**** xref:web/webmvc/mvc-config/api-version.adoc[]
228230
**** xref:web/webmvc/mvc-config/advanced-java.adoc[]
229231
**** xref:web/webmvc/mvc-config/advanced-xml.adoc[]
230232
*** xref:web/webmvc/mvc-http2.adoc[]
@@ -292,6 +294,7 @@
292294
*** xref:web/webflux-functional.adoc[]
293295
*** xref:web/webflux/uri-building.adoc[]
294296
*** xref:web/webflux-cors.adoc[]
297+
*** xref:web/webflux-versioning.adoc[]
295298
*** xref:web/webflux/ann-rest-exceptions.adoc[]
296299
*** xref:web/webflux/security.adoc[]
297300
*** xref:web/webflux/caching.adoc[]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
[[webflux-versioning]]
2+
= API Versioning
3+
:page-section-summary-toc: 1
4+
5+
[.small]#xref:web/webmvc-versioning.adoc[See equivalent in the Servlet stack]#
6+
7+
Spring WebFlux supports API versioning. This section provides an overview of the support
8+
and underlying strategies.
9+
10+
Please, see also related content in:
11+
12+
- Use xref:web/webflux/controller/ann-requestmapping.adoc#webflux-ann-requestmapping-version[API Versions]
13+
to map requests to annotated controller methods
14+
- Configure API versioning in xref:web/webflux/config.adoc#webflux-config-api-version[WebFlux Config]
15+
16+
17+
18+
[[webflux-versioning-strategy]]
19+
== ApiVersionStrategy
20+
[.small]#xref:web/webmvc-versioning.adoc#mvc-versioning-strategy[See equivalent in the Servlet stack]#
21+
22+
This strategy holds all application preferences about how to manage versioning.
23+
It delegates to xref:#webflux-versioning-resolver[ApiVersionResolver] to resolve versions
24+
from requests, and to xref:#webflux-versioning-parser[ApiVersionParser] to parse raw version
25+
values into `Comparable<?>`. It also helps to xref:#webflux-versioning-validation[validate]
26+
request versions.
27+
28+
NOTE: `ApiVersionStrategy` helps to map requests to `@RequestMapping` controller methods,
29+
and is initialized by the WebFlux config. Typically, applications do not interact directly with it.
30+
31+
32+
33+
34+
[[webflux-versioning-resolver]]
35+
== ApiVersionResolver
36+
[.small]#xref:web/webmvc-versioning.adoc#mvc-versioning-resolver[See equivalent in the Servlet stack]#
37+
38+
This strategy resolves the API version from a request. The WebFlux config provides built-in
39+
options to resolve from a header, a request parameter, or from the URL path.
40+
You can also use a custom `ApiVersionResolver`.
41+
42+
43+
44+
45+
[[webflux-versioning-parser]]
46+
== ApiVersionParser
47+
[.small]#xref:web/webmvc-versioning.adoc#mvc-versioning-parser[See equivalent in the Servlet stack]#
48+
49+
This strategy helps to parse raw version values into `Comparable<?>`, which helps to
50+
compare, sort, and select versions. By default, the built-in `SemanticApiVersionParser`
51+
parses a version into `major`, `minor`, and `patch` integer values. Minor and patch
52+
values are set to 0 if not present.
53+
54+
55+
56+
57+
[[webflux-versioning-validation]]
58+
== Validation
59+
[.small]#xref:web/webmvc-versioning.adoc#mvc-versioning-validation[See equivalent in the Servlet stack]#
60+
61+
If a request version is not supported, `InvalidApiVersionException` is raised resulting
62+
in a 400 response. By default, the list of supported versions is initialized from declared
63+
versions in annotated controller mappings. You can add to that list, or set it explicitly
64+
to a fixed set of versions (i.e. ignoring declared ones) through the MVC config.
65+
66+
By default, a version is required when API versioning is enabled, but you can turn that
67+
off in which case the highest available version is used. You can also specify a default
68+
version. `MissingApiVersionException` is raised resulting in a 400 response when a
69+
version is required but not present.
70+
71+
72+
73+
74+
[[webflux-versioning-mapping]]
75+
== Request Mapping
76+
[.small]#xref:web/webmvc-versioning.adoc#mvc-versioning-mapping[See equivalent in the Servlet stack]#
77+
78+
`ApiVersionStrategy` supports the mapping of requests to annotated controller methods.
79+
See xref:web/webflux/controller/ann-requestmapping.adoc#webflux-ann-requestmapping-version[API Versions]
80+
for more details.

framework-docs/modules/ROOT/pages/web/webflux/config.adoc

+57
Original file line numberDiff line numberDiff line change
@@ -686,6 +686,63 @@ reliance on it.
686686

687687

688688

689+
[[webflux-config-api-version]]
690+
== API Version
691+
[.small]#xref:web/webmvc/mvc-config/api-version.adoc[See equivalent in the Servlet stack]#
692+
693+
To enable API versioning with a request header, use the following:
694+
695+
[tabs]
696+
======
697+
Java::
698+
+
699+
[source,java,indent=0,subs="verbatim"]
700+
----
701+
@Configuration
702+
public class WebConfiguration implements WebFluxConfigurer {
703+
704+
@Override
705+
public void configureApiVersioning(ApiVersionConfigurer configurer) {
706+
configurer.useRequestHeader("X-API-Version");
707+
}
708+
}
709+
----
710+
711+
Kotlin::
712+
+
713+
[source,kotlin,indent=0,subs="verbatim"]
714+
----
715+
@Configuration
716+
class WebConfiguration : WebMvcConfigurer {
717+
718+
override fun configureApiVersioning(configurer: ApiVersionConfigurer) {
719+
configurer.useRequestHeader("X-API-Version")
720+
}
721+
}
722+
----
723+
======
724+
725+
Alternatively, the version can be resolved from a request parameter, from a path segment,
726+
or through a custom `ApiVersionResolver`.
727+
728+
TIP: When resolving from a path segment, consider configuring a path prefix once in
729+
xref:web/webmvc/mvc-config/path-matching.adoc[Path Matching] options.
730+
731+
Raw version values are parsed with `SemanticVersionParser` by default, but you can use
732+
a custom xref:web/webflux-versioning.adoc#webflux-versioning-parser[ApiVersionParser].
733+
734+
"Supported" versions are transparently detected from versions declared in request mappings
735+
for convenience, but you can also set the list of supported versions explicitly, and
736+
ignore declared ones. Requests with a version that is not supported are rejected with an
737+
`InvalidApiVersionException` resulting in a 400 response.
738+
739+
Once API versioning is configured, you can begin to map requests to
740+
xref:web/webflux/controller/ann-requestmapping.adoc#webflux-ann-requestmapping-version[controller methods]
741+
according to the request version.
742+
743+
744+
745+
689746
[[webflux-config-blocking-execution]]
690747
== Blocking Execution
691748

framework-docs/modules/ROOT/pages/web/webflux/controller/ann-requestmapping.adoc

+79
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,85 @@ Kotlin::
408408
======
409409

410410

411+
[[webflux-ann-requestmapping-version]]
412+
== API Version
413+
[.small]#xref:web/webmvc/mvc-controller/ann-requestmapping.adoc#mvc-ann-requestmapping-version[See equivalent in the Servlet stack]#
414+
415+
There is no standard way to specify an API version, so you need to configure that first
416+
through the xref:web/webflux/config.adoc#webflux-config-api-version[WebFlux Config] along with other
417+
config options. This results in the creation of an
418+
xref:web/webflux-versioning.adoc#webflux-versioning-strategy[ApiVersionStrategy] that in
419+
supports request mapping.
420+
421+
Once API versioning is enabled, you can begin to map requests with versions.
422+
The `@RequestMapping` version attribute supports the following:
423+
424+
- No value -- match any version
425+
- Fixed version ("1.2") -- match the given version only
426+
- Baseline version ("1.2+") -- match the given version and above
427+
428+
If multiple controller methods have a version less than or equal to the request version,
429+
the one closest to the request version is considered for mapping purposes,
430+
in effect superseding the rest.
431+
432+
To illustrate this, consider the following controller mappings:
433+
434+
[tabs]
435+
======
436+
Java::
437+
+
438+
[source,java,indent=0,subs="verbatim,quotes"]
439+
----
440+
@RestController
441+
@RequestMapping("/account/{id}")
442+
public class AccountController {
443+
444+
@GetMapping // <1>
445+
public Account getAccount() {
446+
}
447+
448+
@GetMapping(version = "1.1") // <2>
449+
public Account getAccount1_1() {
450+
}
451+
452+
@GetMapping(version = "1.2+") // <3>
453+
public Account getAccount1_2() {
454+
}
455+
456+
@GetMapping(version = "1.5") // <4>
457+
public Account getAccount1_5() {
458+
}
459+
}
460+
----
461+
<1> match any version
462+
<2> match version 1.1
463+
<3> match version 1.2 and above
464+
<4> match version 1.5
465+
======
466+
467+
For request with version `"1.3"`:
468+
469+
- (1) matches as it matches any version
470+
- (2) does not match
471+
- (3) matches as it matches 1.2 and above, and is *chosen* as the highest match
472+
- (4) is higher and does not match
473+
474+
For request with version `"1.5"`:
475+
476+
- (1) matches as it matches any version
477+
- (2) does not match
478+
- (3) matches as it matches 1.2 and above
479+
- (4) matches and is *chosen* as the highest match
480+
481+
A request with version `"1.6"` does not have a match. (1) and (3) do match, but are
482+
superseded by (4), which does not match. In this scenario, `NotAcceptableApiVersionException`
483+
is raised resulting in a 400 response.
484+
485+
NOTE: The above assumes the request version is a "supported" versions. If not it would
486+
fail xref:web/webflux-versioning.adoc#webflux-versioning-validation[Validation].
487+
488+
489+
411490

412491
[[webflux-ann-requestmapping-head-options]]
413492
== HTTP HEAD, OPTIONS
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
[[mvc-versioning]]
2+
= API Versioning
3+
:page-section-summary-toc: 1
4+
5+
[.small]#xref:web/webflux-versioning.adoc[See equivalent in the Reactive stack]#
6+
7+
Spring MVC supports API versioning. This section provides an overview of the support
8+
and underlying strategies.
9+
10+
Please, see also related content in:
11+
12+
- Use xref:web/webmvc/mvc-controller/ann-requestmapping.adoc#mvc-ann-requestmapping-version[API Version]
13+
to map requests to annotated controller methods
14+
- Configure API versioning in xref:web/webmvc/mvc-config/api-version.adoc[MVC Config]
15+
16+
17+
18+
19+
[[mvc-versioning-strategy]]
20+
== ApiVersionStrategy
21+
[.small]#xref:web/webflux-versioning.adoc#webflux-versioning-strategy[See equivalent in the Reactive stack]#
22+
23+
This strategy holds all application preferences about how to manage versioning.
24+
It delegates to xref:#mvc-versioning-resolver[ApiVersionResolver] to resolve versions
25+
from requests, and to xref:#mvc-versioning-parser[ApiVersionParser] to parse raw version
26+
values into `Comparable<?>`. It also helps to xref:#mvc-versioning-validation[validate]
27+
request versions.
28+
29+
NOTE: `ApiVersionStrategy` helps to map requests to `@RequestMapping` controller methods,
30+
and is initialized by the MVC config. Typically, applications do not interact directly with it.
31+
32+
33+
34+
35+
[[mvc-versioning-resolver]]
36+
== ApiVersionResolver
37+
[.small]#xref:web/webmvc-versioning.adoc#mvc-versioning-resolver[See equivalent in the Reactive stack]#
38+
39+
This strategy resolves the API version from a request. The MVC config provides built-in
40+
options to resolve from a header, from a request parameter, or from the URL path.
41+
You can also use a custom `ApiVersionResolver`.
42+
43+
44+
45+
46+
[[mvc-versioning-parser]]
47+
== ApiVersionParser
48+
[.small]#xref:web/webflux-versioning.adoc#webflux-versioning-parser[See equivalent in the Reactive stack]#
49+
50+
This strategy helps to parse raw version values into `Comparable<?>`, which helps to
51+
compare, sort, and select versions. By default, the built-in `SemanticApiVersionParser`
52+
parses a version into `major`, `minor`, and `patch` integer values. Minor and patch
53+
values are set to 0 if not present.
54+
55+
56+
57+
58+
[[mvc-versioning-validation]]
59+
== Validation
60+
[.small]#xref:web/webflux-versioning.adoc#webflux-versioning-validation[See equivalent in the Reactive stack]#
61+
62+
If a request version is not supported, `InvalidApiVersionException` is raised resulting
63+
in a 400 response. By default, the list of supported versions is initialized from declared
64+
versions in annotated controller mappings. You can add to that list, or set it explicitly
65+
to a fixed set of versions (i.e. ignoring declared ones) through the MVC config.
66+
67+
By default, a version is required when API versioning is enabled, but you can turn that
68+
off in which case the highest available version is used. You can also specify a default
69+
version. `MissingApiVersionException` is raised resulting in a 400 response when a
70+
version is required but not present.
71+
72+
73+
74+
75+
[[mvc-versioning-mapping]]
76+
== Request Mapping
77+
[.small]#xref:web/webflux-versioning.adoc#webflux-versioning-mapping[See equivalent in the Reactive stack]#
78+
79+
`ApiVersionStrategy` supports the mapping of requests to annotated controller methods.
80+
See xref:web/webmvc/mvc-controller/ann-requestmapping.adoc#mvc-ann-requestmapping-version[API Version]
81+
for more details.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
[[mvc-config-api-version]]
2+
= API Version
3+
4+
[.small]#xref:web/webflux/config.adoc#webflux-config-api-version[See equivalent in the Reactive stack]#
5+
6+
To enable API versioning with a request header, use the following:
7+
8+
include-code::./WebConfiguration[tag=snippet,indent=0]
9+
10+
Alternatively, the version can be resolved from a request parameter, from a path segment,
11+
or through a custom `ApiVersionResolver`.
12+
13+
TIP: When resolving from a path segment, consider configuring a path prefix once in
14+
xref:web/webmvc/mvc-config/path-matching.adoc[Path Matching] options.
15+
16+
Raw version values are parsed with `SemanticVersionParser` by default, but you can use
17+
a custom xref:web/webmvc-versioning.adoc#mvc-versioning-parser[ApiVersionParser].
18+
19+
"Supported" versions are transparently detected from versions declared in request mappings
20+
for convenience, but you can also set the list of supported versions explicitly, and
21+
ignore declared ones. Requests with a version that is not supported are rejected with an
22+
`InvalidApiVersionException` resulting in a 400 response.
23+
24+
Once API versioning is configured, you can begin to map requests to
25+
xref:web/webmvc/mvc-controller/ann-requestmapping.adoc#mvc-ann-requestmapping-version[controller methods]
26+
according to the request version.

0 commit comments

Comments
 (0)