diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/accept/ApiVersionResolver.java b/spring-webflux/src/main/java/org/springframework/web/reactive/accept/ApiVersionResolver.java index 186abc062d7..7421679093c 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/accept/ApiVersionResolver.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/accept/ApiVersionResolver.java @@ -17,7 +17,6 @@ package org.springframework.web.reactive.accept; import org.jspecify.annotations.Nullable; -import reactor.core.publisher.Mono; import org.springframework.web.server.ServerWebExchange; @@ -25,7 +24,6 @@ import org.springframework.web.server.ServerWebExchange; * Contract to extract the version from a request. * * @author Rossen Stoyanchev - * @author Jonathan Kaplan * @since 7.0 */ @FunctionalInterface @@ -33,21 +31,12 @@ public interface ApiVersionResolver { /** * Resolve the version for the given exchange. - * @param exchange the current exchange - * @return {@code Mono} emitting the version value, or an empty {@code Mono} - * @since 7.0.3 - */ - Mono resolveApiVersion(ServerWebExchange exchange); - - /** - * Resolve the version for the given exchange. + *

Implementations of this method are expected to be non-blocking. + * If you need to resolve the version asynchronously, please implement the + * {@link AsyncApiVersionResolver} subinterface instead. * @param exchange the current exchange * @return the version value, or {@code null} if not found - * @deprecated in favor of {@link #resolveApiVersion(ServerWebExchange)} */ - @Deprecated(since = "7.0.3", forRemoval = true) - default @Nullable String resolveVersion(ServerWebExchange exchange) { - return null; - } + @Nullable String resolveVersion(ServerWebExchange exchange); } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/accept/SyncApiVersionResolver.java b/spring-webflux/src/main/java/org/springframework/web/reactive/accept/AsyncApiVersionResolver.java similarity index 61% rename from spring-webflux/src/main/java/org/springframework/web/reactive/accept/SyncApiVersionResolver.java rename to spring-webflux/src/main/java/org/springframework/web/reactive/accept/AsyncApiVersionResolver.java index 9cabcbf1373..0a31f9e42d9 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/accept/SyncApiVersionResolver.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/accept/AsyncApiVersionResolver.java @@ -23,35 +23,26 @@ import org.springframework.web.server.ServerWebExchange; /** * Extension of {@link ApiVersionResolver} for implementations that resolve the - * version in an imperative way without blocking. + * version in an asynchronous way. * * @author Rossen Stoyanchev + * @author Jonathan Kaplan * @since 7.0.3 */ @FunctionalInterface -public interface SyncApiVersionResolver extends ApiVersionResolver { +public interface AsyncApiVersionResolver extends ApiVersionResolver { /** - * {@inheritDoc} - *

This method delegates to the synchronous - * {@link #resolveVersionValue} and wraps the result as {@code Mono}. - */ - @Override - default Mono resolveApiVersion(ServerWebExchange exchange) { - return Mono.justOrEmpty(resolveVersionValue(exchange)); - } - - /** - * Resolve the version for the given exchange imperatively without blocking. + * Resolve the version for the given exchange. * @param exchange the current exchange - * @return the version value, or {@code null} if not found + * @return {@code Mono} emitting the version value, or an empty {@code Mono} */ - @Nullable String resolveVersionValue(ServerWebExchange exchange); + Mono resolveVersionAsync(ServerWebExchange exchange); - @SuppressWarnings("removal") @Override default @Nullable String resolveVersion(ServerWebExchange exchange) { - return resolveVersionValue(exchange); + throw new UnsupportedOperationException( + "Async resolver does not support blocking resolution"); } } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/accept/DefaultApiVersionStrategy.java b/spring-webflux/src/main/java/org/springframework/web/reactive/accept/DefaultApiVersionStrategy.java index a6fd704c2e5..4dfdb26a088 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/accept/DefaultApiVersionStrategy.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/accept/DefaultApiVersionStrategy.java @@ -169,7 +169,9 @@ public class DefaultApiVersionStrategy implements ApiVersionStrategy { @Override public Mono resolveApiVersion(ServerWebExchange exchange) { return Flux.fromIterable(this.versionResolvers) - .flatMap(resolver -> resolver.resolveApiVersion(exchange)) + .flatMap(resolver -> resolver instanceof AsyncApiVersionResolver asyncResolver ? + asyncResolver.resolveVersionAsync(exchange) : + Mono.justOrEmpty(resolver.resolveVersion(exchange))) .next(); } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/accept/HeaderApiVersionResolver.java b/spring-webflux/src/main/java/org/springframework/web/reactive/accept/HeaderApiVersionResolver.java index 07863cefd91..4d7871dec63 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/accept/HeaderApiVersionResolver.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/accept/HeaderApiVersionResolver.java @@ -26,7 +26,7 @@ import org.springframework.web.server.ServerWebExchange; * @author Rossen Stoyanchev * @since 7.0 */ -public class HeaderApiVersionResolver implements SyncApiVersionResolver { +public class HeaderApiVersionResolver implements ApiVersionResolver { private final String headerName; @@ -37,7 +37,7 @@ public class HeaderApiVersionResolver implements SyncApiVersionResolver { @Override - public @Nullable String resolveVersionValue(ServerWebExchange exchange) { + public @Nullable String resolveVersion(ServerWebExchange exchange) { return exchange.getRequest().getHeaders().getFirst(this.headerName); } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/accept/MediaTypeParamApiVersionResolver.java b/spring-webflux/src/main/java/org/springframework/web/reactive/accept/MediaTypeParamApiVersionResolver.java index db9b9acd3b5..c9967091088 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/accept/MediaTypeParamApiVersionResolver.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/accept/MediaTypeParamApiVersionResolver.java @@ -29,7 +29,7 @@ import org.springframework.web.server.ServerWebExchange; * @author Rossen Stoyanchev * @since 7.0 */ -public class MediaTypeParamApiVersionResolver implements SyncApiVersionResolver { +public class MediaTypeParamApiVersionResolver implements ApiVersionResolver { private final MediaType compatibleMediaType; @@ -49,7 +49,7 @@ public class MediaTypeParamApiVersionResolver implements SyncApiVersionResolver @Override - public @Nullable String resolveVersionValue(ServerWebExchange exchange) { + public @Nullable String resolveVersion(ServerWebExchange exchange) { HttpHeaders headers = exchange.getRequest().getHeaders(); for (MediaType mediaType : headers.getAccept()) { if (this.compatibleMediaType.isCompatibleWith(mediaType)) { diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/accept/PathApiVersionResolver.java b/spring-webflux/src/main/java/org/springframework/web/reactive/accept/PathApiVersionResolver.java index 06de39d20be..2da6819498b 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/accept/PathApiVersionResolver.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/accept/PathApiVersionResolver.java @@ -32,7 +32,7 @@ import org.springframework.web.server.ServerWebExchange; * @author Rossen Stoyanchev * @since 7.0 */ -public class PathApiVersionResolver implements SyncApiVersionResolver { +public class PathApiVersionResolver implements ApiVersionResolver { private final int pathSegmentIndex; @@ -49,7 +49,7 @@ public class PathApiVersionResolver implements SyncApiVersionResolver { @Override - public String resolveVersionValue(ServerWebExchange exchange) { + public String resolveVersion(ServerWebExchange exchange) { int i = 0; for (PathContainer.Element e : exchange.getRequest().getPath().pathWithinApplication().elements()) { if (e instanceof PathContainer.PathSegment && i++ == this.pathSegmentIndex) { diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/accept/QueryApiVersionResolver.java b/spring-webflux/src/main/java/org/springframework/web/reactive/accept/QueryApiVersionResolver.java index f81f832bfea..16606c75cbc 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/accept/QueryApiVersionResolver.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/accept/QueryApiVersionResolver.java @@ -26,7 +26,7 @@ import org.springframework.web.server.ServerWebExchange; * @author Rossen Stoyanchev * @since 7.0 */ -public class QueryApiVersionResolver implements SyncApiVersionResolver { +public class QueryApiVersionResolver implements ApiVersionResolver { private final String queryParamName; @@ -37,7 +37,7 @@ public class QueryApiVersionResolver implements SyncApiVersionResolver { @Override - public @Nullable String resolveVersionValue(ServerWebExchange exchange) { + public @Nullable String resolveVersion(ServerWebExchange exchange) { return exchange.getRequest().getQueryParams().getFirst(this.queryParamName); } diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/function/server/RequestPredicatesTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/function/server/RequestPredicatesTests.java index 765a4e811e9..7a2fbc496ad 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/function/server/RequestPredicatesTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/function/server/RequestPredicatesTests.java @@ -22,7 +22,6 @@ import java.util.List; import java.util.function.Function; import org.junit.jupiter.api.Test; -import reactor.core.publisher.Mono; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; @@ -382,7 +381,7 @@ class RequestPredicatesTests { private static DefaultApiVersionStrategy apiVersionStrategy() { return new DefaultApiVersionStrategy( - List.of(exchange -> Mono.empty()), new SemanticApiVersionParser(), true, null, false, null, null); + List.of(exchange -> null), new SemanticApiVersionParser(), true, null, false, null, null); } }