我目前正在使用Spring Cloud Gateway,并将其用作我们其他内部应用程序的网关。
最初它是使用
application.yaml
文件来配置路由,但随着项目的扩展,网关的需求也随之扩展。
有些路由需要重写路径,有些路由需要身份验证、一些授权和discoveryservice的自定义实现。
我创建了一个名为
Route
最初已经足够了,我想迭代这些类,这取决于根据需要设置额外GatewayFilters的属性。然而,我只能找到使用fluent api的例子,它不符合我们的要求。
这是Fluent API方式的一个示例
@Bean
public RouteLocator routes(RouteLocatorBuilder builder, GoldenCustomerRoutePredicateFactory gf ) {
return builder.routes()
.route("golden_route", r -> r.path("/api/**")
.uri("https://fastserver")
.predicate(gf.apply(new Config(true, "customerId"))))
.route("common_route", r -> r.path("/api/**")
.uri("https://slowserver")
.predicate(gf.apply(new Config(false, "customerId"))))
.build();
}
我想做如下的事情,但在api中找不到支持。感觉好像我错过了一些明显的东西。
这是我想象中的一个例子。
public class CustomRouteLocator {
@Autowired
private ApplicationContext context;
@Bean
public RouteLocator customRouteLocator(final RouteLocatorBuilder builder) {
Map<String, Object> routeBeans = context.getBeansWithAnnotation(GatewayRoute.class);
return builder.routes(routeBeans.entrySet().stream().map((r) -> {
AbstractApplicationRoute route = (AbstractApplicationRoute) r.getValue();
List<GatewayFilter> filters = generateFilters(route); // generate a list of filters appleid to this route based on the available props in the class
return Route.builder().and(pathFilter(route.getInboundPaths())
.filters(filters)
.uri(route.getRedirectedHost()) // this field does not exist in the current api
.id(r.getKey()) // this field does not exist
.build();
}).collect(Collectors.toList()));
}
private List<GatewayFilter> generateFilters(final AbstractApplicationRoute route) {
//business logic to create route and determine what filters to apply
return List.of(removeRequestHeader("headerName"));
}
private GatewayFilter removeRequestHeader(final String headerName) {
AbstractGatewayFilterFactory.NameConfig config = new AbstractGatewayFilterFactory.NameConfig();
config.setName(headerName);
return new RemoveRequestHeaderGatewayFilterFactory().apply(config);
}
}