Skip to content

Commit 8202052

Browse files
committed
Introduce RouterFunction builder
This commit introduces RouterFunctions.Builder, a new way to build router functions that does not require static imports, thus being more discoverable and convenient. Issue: SPR-16953
1 parent a89e716 commit 8202052

File tree

3 files changed

+705
-0
lines changed

3 files changed

+705
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
/*
2+
* Copyright 2002-2018 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 java.util.ArrayList;
20+
import java.util.List;
21+
import java.util.function.BiFunction;
22+
import java.util.function.Consumer;
23+
import java.util.function.Function;
24+
import java.util.function.Supplier;
25+
26+
import reactor.core.publisher.Mono;
27+
28+
import org.springframework.http.HttpMethod;
29+
import org.springframework.util.Assert;
30+
31+
/**
32+
* Default implementation of {@link RouterFunctions.Builder}.
33+
* @author Arjen Poutsma
34+
* @since 5.1
35+
*/
36+
class RouterFunctionBuilder implements RouterFunctions.Builder {
37+
38+
private List<RouterFunction<ServerResponse>> routerFunctions = new ArrayList<>();
39+
40+
private List<HandlerFilterFunction<ServerResponse, ServerResponse>> filterFunctions = new ArrayList<>();
41+
42+
43+
@Override
44+
public RouterFunctions.Builder route(RequestPredicate predicate,
45+
HandlerFunction<ServerResponse> handlerFunction) {
46+
this.routerFunctions.add(RouterFunctions.route(predicate, handlerFunction));
47+
return this;
48+
}
49+
50+
@Override
51+
public RouterFunctions.Builder routeGet(HandlerFunction<ServerResponse> handlerFunction) {
52+
return route(RequestPredicates.method(HttpMethod.GET), handlerFunction);
53+
}
54+
55+
@Override
56+
public RouterFunctions.Builder routeGet(String pattern, HandlerFunction<ServerResponse> handlerFunction) {
57+
return route(RequestPredicates.GET(pattern), handlerFunction);
58+
}
59+
60+
@Override
61+
public RouterFunctions.Builder routeHead(HandlerFunction<ServerResponse> handlerFunction) {
62+
return route(RequestPredicates.method(HttpMethod.HEAD), handlerFunction);
63+
}
64+
65+
@Override
66+
public RouterFunctions.Builder routeHead(String pattern, HandlerFunction<ServerResponse> handlerFunction) {
67+
return route(RequestPredicates.HEAD(pattern), handlerFunction);
68+
}
69+
70+
@Override
71+
public RouterFunctions.Builder routePost(HandlerFunction<ServerResponse> handlerFunction) {
72+
return route(RequestPredicates.method(HttpMethod.POST), handlerFunction);
73+
}
74+
75+
@Override
76+
public RouterFunctions.Builder routePost(String pattern, HandlerFunction<ServerResponse> handlerFunction) {
77+
return route(RequestPredicates.POST(pattern), handlerFunction);
78+
}
79+
80+
@Override
81+
public RouterFunctions.Builder routePut(HandlerFunction<ServerResponse> handlerFunction) {
82+
return route(RequestPredicates.method(HttpMethod.PUT), handlerFunction);
83+
}
84+
85+
@Override
86+
public RouterFunctions.Builder routePut(String pattern, HandlerFunction<ServerResponse> handlerFunction) {
87+
return route(RequestPredicates.PUT(pattern), handlerFunction);
88+
}
89+
90+
@Override
91+
public RouterFunctions.Builder routePatch(HandlerFunction<ServerResponse> handlerFunction) {
92+
return route(RequestPredicates.method(HttpMethod.PATCH), handlerFunction);
93+
}
94+
95+
@Override
96+
public RouterFunctions.Builder routePatch(String pattern, HandlerFunction<ServerResponse> handlerFunction) {
97+
return route(RequestPredicates.PATCH(pattern), handlerFunction);
98+
}
99+
100+
@Override
101+
public RouterFunctions.Builder routeDelete(HandlerFunction<ServerResponse> handlerFunction) {
102+
return route(RequestPredicates.method(HttpMethod.DELETE), handlerFunction);
103+
}
104+
105+
@Override
106+
public RouterFunctions.Builder routeDelete(String pattern, HandlerFunction<ServerResponse> handlerFunction) {
107+
return route(RequestPredicates.DELETE(pattern), handlerFunction);
108+
}
109+
110+
@Override
111+
public RouterFunctions.Builder routeOptions(HandlerFunction<ServerResponse> handlerFunction) {
112+
return route(RequestPredicates.method(HttpMethod.OPTIONS), handlerFunction);
113+
}
114+
115+
@Override
116+
public RouterFunctions.Builder routeOptions(String pattern, HandlerFunction<ServerResponse> handlerFunction) {
117+
return route(RequestPredicates.OPTIONS(pattern), handlerFunction);
118+
}
119+
120+
@Override
121+
public RouterFunctions.Builder nest(RequestPredicate predicate,
122+
Consumer<RouterFunctions.Builder> builderConsumer) {
123+
124+
Assert.notNull(builderConsumer, "'builderConsumer' must not be null");
125+
126+
RouterFunctionBuilder nestedBuilder = new RouterFunctionBuilder();
127+
builderConsumer.accept(nestedBuilder);
128+
RouterFunction<ServerResponse> nestedRoute = nestedBuilder.build();
129+
130+
this.routerFunctions.add(RouterFunctions.nest(predicate, nestedRoute));
131+
return this;
132+
}
133+
134+
@Override
135+
public RouterFunctions.Builder nest(RequestPredicate predicate,
136+
Supplier<RouterFunction<ServerResponse>> routerFunctionSupplier) {
137+
138+
Assert.notNull(routerFunctionSupplier, "'routerFunctionSupplier' must not be null");
139+
140+
RouterFunction<ServerResponse> nestedRoute = routerFunctionSupplier.get();
141+
142+
this.routerFunctions.add(RouterFunctions.nest(predicate, nestedRoute));
143+
return this;
144+
}
145+
146+
@Override
147+
public RouterFunctions.Builder nestPath(String pattern,
148+
Consumer<RouterFunctions.Builder> builderConsumer) {
149+
return nest(RequestPredicates.path(pattern), builderConsumer);
150+
}
151+
152+
@Override
153+
public RouterFunctions.Builder nestPath(String pattern,
154+
Supplier<RouterFunction<ServerResponse>> routerFunctionSupplier) {
155+
return nest(RequestPredicates.path(pattern), routerFunctionSupplier);
156+
}
157+
158+
@Override
159+
public RouterFunctions.Builder filter(HandlerFilterFunction<ServerResponse, ServerResponse> filterFunction) {
160+
Assert.notNull(filterFunction, "'filterFunction' must not be null");
161+
162+
this.filterFunctions.add(filterFunction);
163+
return this;
164+
}
165+
166+
@Override
167+
public RouterFunctions.Builder before(
168+
Function<ServerRequest, Mono<ServerRequest>> requestProcessor) {
169+
170+
Assert.notNull(requestProcessor, "Function must not be null");
171+
return filter((request, next) -> requestProcessor.apply(request).flatMap(next::handle));
172+
}
173+
174+
@Override
175+
public RouterFunctions.Builder after(
176+
BiFunction<ServerRequest, ServerResponse, Mono<ServerResponse>> responseProcessor) {
177+
return filter((request, next) -> next.handle(request)
178+
.flatMap(serverResponse -> responseProcessor.apply(request, serverResponse)));
179+
}
180+
181+
@Override
182+
public <T extends Throwable> RouterFunctions.Builder exception(
183+
Class<T> exceptionType,
184+
BiFunction<T, ServerRequest, Mono<ServerResponse>> fallback) {
185+
Assert.notNull(exceptionType, "'exceptionType' must not be null");
186+
Assert.notNull(fallback, "'fallback' must not be null");
187+
188+
return filter((request, next) -> next.handle(request)
189+
.onErrorResume(exceptionType, t -> fallback.apply(t, request)));
190+
}
191+
192+
@Override
193+
public RouterFunction<ServerResponse> build() {
194+
195+
RouterFunction<ServerResponse> result = this.routerFunctions.stream()
196+
.reduce(RouterFunction::and)
197+
.orElseThrow(IllegalStateException::new);
198+
199+
if (this.filterFunctions.isEmpty()) {
200+
return result;
201+
}
202+
else {
203+
HandlerFilterFunction<ServerResponse, ServerResponse> filter =
204+
this.filterFunctions.stream()
205+
.reduce(HandlerFilterFunction::andThen)
206+
.orElseThrow(IllegalStateException::new);
207+
208+
return result.filter(filter);
209+
}
210+
}
211+
212+
}

0 commit comments

Comments
 (0)