From bb9d3e16805d927fc3c67a5c55065a0c14965651 Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Tue, 14 Feb 2017 15:42:01 +0100 Subject: [PATCH] Renamed RouterFunction composition methods Renamed `RouterFunction.andSame()` to `and()`, and `and()` to `andOther()`. The reason for this change is that we can expect most RouterFunctions to be parameterized over ServerResponse, and thus it makes sense to use the shortest composition method (`and()`) for composing router functions of the same type. When a user composes different response types, such as composing a `RouterFunction` with an `RouterFunction`, the `andOther` method is to be used, but this is a less common scenario. --- .../function/server/RouterFunction.java | 21 +++++------ .../server/RouterFunctionExtensions.kt | 19 ++++++++-- .../function/server/RouterFunctionTests.java | 35 +++++++++---------- 3 files changed, 42 insertions(+), 33 deletions(-) diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RouterFunction.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RouterFunction.java index 210486c55a..8572b68a30 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RouterFunction.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RouterFunction.java @@ -16,8 +16,6 @@ package org.springframework.web.reactive.function.server; -import java.util.Optional; - import reactor.core.publisher.Mono; /** @@ -33,7 +31,7 @@ public interface RouterFunction { /** * Return the {@linkplain HandlerFunction handler function} that matches the given request. - * @param request the request to route to + * @param request the request to route * @return an {@code Mono} describing the {@code HandlerFunction} that matches this request, * or an empty {@code Mono} if there is no match */ @@ -41,25 +39,27 @@ public interface RouterFunction { /** * Return a composed routing function that first invokes this function, - * and then invokes the {@code other} function (of the same type {@code T}) + * and then invokes the {@code other} function (of the same response type {@code T}) * if this route had {@linkplain Mono#empty() no result}. * @param other the function of type {@code T} to apply when this function has no result * @return a composed function that first routes with this function and then the * {@code other} function if this function has no result + * @see #andOther(RouterFunction) */ - default RouterFunction andSame(RouterFunction other) { + default RouterFunction and(RouterFunction other) { return request -> this.route(request).otherwiseIfEmpty(other.route(request)); } /** * Return a composed routing function that first invokes this function, - * and then invokes the {@code other} function (of a different type) if this route had - * {@linkplain Optional#empty() no result}. + * and then invokes the {@code other} function (of a different response type) if this route had + * {@linkplain Mono#empty() no result}. * @param other the function to apply when this function has no result * @return a composed function that first routes with this function and then the * {@code other} function if this function has no result + * @see #and(RouterFunction) */ - default RouterFunction and(RouterFunction other) { + default RouterFunction andOther(RouterFunction other) { return request -> this.route(request) .map(RouterFunctions::cast) .otherwiseIfEmpty(other.route(request).map(RouterFunctions::cast)); @@ -70,16 +70,13 @@ public interface RouterFunction { * and then routes to the given handler function if the given request predicate applies. This * method is a convenient combination of {@link #and(RouterFunction)} and * {@link RouterFunctions#route(RequestPredicate, HandlerFunction)}. - * @param the handler function type * @param predicate the predicate to test * @param handlerFunction the handler function to route to * @return a composed function that first routes with this function and then the function * created from {@code predicate} and {@code handlerFunction} if this * function has no result */ - default RouterFunction andRoute(RequestPredicate predicate, - HandlerFunction handlerFunction) { - + default RouterFunction andRoute(RequestPredicate predicate, HandlerFunction handlerFunction) { return and(RouterFunctions.route(predicate, handlerFunction)); } diff --git a/spring-webflux/src/main/kotlin/org/springframework/web/reactive/function/server/RouterFunctionExtensions.kt b/spring-webflux/src/main/kotlin/org/springframework/web/reactive/function/server/RouterFunctionExtensions.kt index 102b165119..d84ec84f64 100644 --- a/spring-webflux/src/main/kotlin/org/springframework/web/reactive/function/server/RouterFunctionExtensions.kt +++ b/spring-webflux/src/main/kotlin/org/springframework/web/reactive/function/server/RouterFunctionExtensions.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.springframework.web.reactive.function.server import org.springframework.core.io.Resource @@ -137,9 +153,8 @@ class RouterDsl { routes += RouterFunctions.resources(lookupFunction) } - @Suppress("UNCHECKED_CAST") fun router(): RouterFunction { - return routes().reduce(RouterFunction<*>::and) as RouterFunction + return routes().reduce(RouterFunction::and) } operator fun invoke(request: ServerRequest): Mono> { diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/function/server/RouterFunctionTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/function/server/RouterFunctionTests.java index ef5f693d70..0c4d78aa44 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/function/server/RouterFunctionTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/function/server/RouterFunctionTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,12 +30,12 @@ import static org.springframework.web.reactive.function.BodyInserters.fromObject public class RouterFunctionTests { @Test - public void andSame() throws Exception { + public void and() throws Exception { HandlerFunction handlerFunction = request -> ServerResponse.ok().build(); RouterFunction routerFunction1 = request -> Mono.empty(); RouterFunction routerFunction2 = request -> Mono.just(handlerFunction); - RouterFunction result = routerFunction1.andSame(routerFunction2); + RouterFunction result = routerFunction1.and(routerFunction2); assertNotNull(result); MockServerRequest request = MockServerRequest.builder().build(); @@ -48,14 +48,14 @@ public class RouterFunctionTests { } @Test - public void and() throws Exception { + public void andOther() throws Exception { HandlerFunction handlerFunction = request -> ServerResponse.ok().body(fromObject("42")); RouterFunction routerFunction1 = request -> Mono.empty(); RouterFunction routerFunction2 = request -> Mono.just(handlerFunction); - RouterFunction result = routerFunction1.and(routerFunction2); + RouterFunction result = routerFunction1.andOther(routerFunction2); assertNotNull(result); MockServerRequest request = MockServerRequest.builder().build(); @@ -69,10 +69,10 @@ public class RouterFunctionTests { @Test public void andRoute() throws Exception { - RouterFunction routerFunction1 = request -> Mono.empty(); + RouterFunction routerFunction1 = request -> Mono.empty(); RequestPredicate requestPredicate = request -> true; - RouterFunction result = routerFunction1.andRoute(requestPredicate, this::handlerMethod); + RouterFunction result = routerFunction1.andRoute(requestPredicate, this::handlerMethod); assertNotNull(result); MockServerRequest request = MockServerRequest.builder().build(); @@ -88,32 +88,30 @@ public class RouterFunctionTests { return ServerResponse.ok().body(fromObject("42")); } - /* - TODO: enable when ServerEntityResponse is reintroduced - @Test public void filter() throws Exception { - HandlerFunction handlerFunction = request -> ServerResponse.ok().body(fromObject("42")); - RouterFunction routerFunction = request -> Mono.just(handlerFunction); + Mono stringMono = Mono.just("42"); + HandlerFunction>> handlerFunction = request -> EntityResponse.fromPublisher(stringMono, String.class).build(); + RouterFunction>> routerFunction = request -> Mono.just(handlerFunction); - HandlerFilterFunction filterFunction = + HandlerFilterFunction>, EntityResponse>> filterFunction = (request, next) -> next.handle(request).then( response -> { - Flux body = Flux.from(response.body()) + Mono intMono = response.entity() .map(Integer::parseInt); - return ServerResponse.ok().body(body, Integer.class); + return EntityResponse.fromPublisher(intMono, Integer.class).build(); }); - RouterFunction result = routerFunction.filter(filterFunction); + RouterFunction>> result = routerFunction.filter(filterFunction); assertNotNull(result); MockServerRequest request = MockServerRequest.builder().build(); - Mono> responseMono = + Mono>> responseMono = result.route(request).then(hf -> hf.handle(request)); StepVerifier.create(responseMono) .consumeNextWith( serverResponse -> { - StepVerifier.create(serverResponse.body()) + StepVerifier.create(serverResponse.entity()) .expectNext(42) .expectComplete() .verify(); @@ -121,6 +119,5 @@ public class RouterFunctionTests { .expectComplete() .verify(); } - */ } \ No newline at end of file