mirror of
https://github.com/spring-projects/spring-framework.git
synced 2026-09-17 16:39:29 +00:00
Restore ApiVersionResolver contract
Instead of making it async and having a sync subinterface variant, this restores ApiVersionResolver to be as it was with an async subinterface variant. ApiVersionStrategy, and the infrastructure invoking it, remains async first, but also accommodates sync resolvers. This should provide a better balance with backwards compatibility while also accommodating async version resolution as the less common scenario. See gh-36084
This commit is contained in:
+4
-15
@@ -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<String> resolveApiVersion(ServerWebExchange exchange);
|
||||
|
||||
/**
|
||||
* Resolve the version for the given exchange.
|
||||
* <p>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);
|
||||
|
||||
}
|
||||
|
||||
+8
-17
@@ -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}
|
||||
* <p>This method delegates to the synchronous
|
||||
* {@link #resolveVersionValue} and wraps the result as {@code Mono}.
|
||||
*/
|
||||
@Override
|
||||
default Mono<String> 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<String> 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");
|
||||
}
|
||||
|
||||
}
|
||||
+3
-1
@@ -169,7 +169,9 @@ public class DefaultApiVersionStrategy implements ApiVersionStrategy {
|
||||
@Override
|
||||
public Mono<String> 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();
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -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)) {
|
||||
|
||||
+2
-2
@@ -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) {
|
||||
|
||||
+2
-2
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
+1
-2
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user