Skip to content

Commit 1efcf26

Browse files
committed
Defer evaluation of right-hand route in composed route
1 parent 9ab8bd0 commit 1efcf26

File tree

2 files changed

+92
-2
lines changed

2 files changed

+92
-2
lines changed

spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RouterFunction.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ public interface RouterFunction<T extends ServerResponse> {
4747
* @see #andOther(RouterFunction)
4848
*/
4949
default RouterFunction<T> and(RouterFunction<T> other) {
50-
return request -> this.route(request).otherwiseIfEmpty(other.route(request));
50+
return request -> this.route(request)
51+
.otherwiseIfEmpty(Mono.defer(() -> other.route(request)));
5152
}
5253

5354
/**
@@ -62,7 +63,8 @@ default RouterFunction<T> and(RouterFunction<T> other) {
6263
default RouterFunction<?> andOther(RouterFunction<?> other) {
6364
return request -> this.route(request)
6465
.map(RouterFunctions::cast)
65-
.otherwiseIfEmpty(other.route(request).map(RouterFunctions::cast));
66+
.otherwiseIfEmpty(
67+
Mono.defer(() -> other.route(request).map(RouterFunctions::cast)));
6668
}
6769

6870
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
* Copyright 2002-2017 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.web.reactive.function.server;
18+
19+
import org.junit.Before;
20+
import org.junit.Ignore;
21+
import org.junit.Test;
22+
import reactor.core.publisher.Mono;
23+
24+
import org.springframework.http.HttpStatus;
25+
import org.springframework.http.ResponseEntity;
26+
import org.springframework.web.client.RestTemplate;
27+
28+
import static org.junit.Assert.assertEquals;
29+
import static org.springframework.web.reactive.function.BodyInserters.fromObject;
30+
import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
31+
import static org.springframework.web.reactive.function.server.RequestPredicates.pathPrefix;
32+
import static org.springframework.web.reactive.function.server.RouterFunctions.nest;
33+
import static org.springframework.web.reactive.function.server.RouterFunctions.route;
34+
35+
/**
36+
* @author Arjen Poutsma
37+
*/
38+
public class NestedRouteIntegrationTests
39+
extends AbstractRouterFunctionIntegrationTests {
40+
41+
private RestTemplate restTemplate;
42+
43+
@Before
44+
public void createRestTemplate() {
45+
this.restTemplate = new RestTemplate();
46+
}
47+
48+
@Override
49+
protected RouterFunction<?> routerFunction() {
50+
NestedHandler nestedHandler = new NestedHandler();
51+
return nest(pathPrefix("/foo"),
52+
route(GET("/bar"), nestedHandler::bar)
53+
.andRoute(GET("/baz"), nestedHandler::baz));
54+
}
55+
56+
57+
@Test
58+
public void bar() throws Exception {
59+
ResponseEntity<String> result =
60+
restTemplate.getForEntity("http://localhost:" + port + "/foo/bar", String.class);
61+
62+
assertEquals(HttpStatus.OK, result.getStatusCode());
63+
assertEquals("bar", result.getBody());
64+
}
65+
66+
@Test
67+
@Ignore
68+
public void baz() throws Exception {
69+
ResponseEntity<String> result =
70+
restTemplate.getForEntity("http://localhost:" + port + "/foo/baz", String.class);
71+
72+
assertEquals(HttpStatus.OK, result.getStatusCode());
73+
assertEquals("baz", result.getBody());
74+
}
75+
76+
private static class NestedHandler {
77+
78+
public Mono<ServerResponse> bar(ServerRequest request) {
79+
return ServerResponse.ok().body(fromObject("bar"));
80+
}
81+
82+
public Mono<ServerResponse> baz(ServerRequest request) {
83+
return ServerResponse.ok().body(fromObject("baz"));
84+
}
85+
86+
}
87+
88+
}

0 commit comments

Comments
 (0)