在YAML中将多个路径路由到同一路由

时间:2018-08-24 18:39:00

标签: routing spring-cloud-gateway

我正在尝试将大量路由配置转换为Spring Cloud Gateway Yaml DSL。

我遇到的一个问题是(非常常见的情况)多条路径应映射到同一条路线。也就是说,任何匹配/abc/**/def/**/ghi/**的传入URL应该被路由到一些uri http://example.org(并应用相同的过滤器集等)。

在基于Fluent的Java路由方法中,可以通过.or().方法来实现,例如:r.path("/abc/**").or().path("/def/**").or().path("/fhi/**")...

如何通过基于YAML的路由配置实现相同的功能?

编辑:我在文档中看到:https://cloud.spring.io/spring-cloud-gateway/single/spring-cloud-gateway.html#gateway-request-predicates-factories

  

“多个路由谓词工厂可以组合并且可以组合   通过逻辑and

是否有另一种方法可以通过Yaml来实现路径谓词的OR-ing,而无需声明多个路由?可以重写某些东西来支持这一点吗?

2 个答案:

答案 0 :(得分:1)

您可能已经找到答案了。但为了记录,我可以说可以为谓词添加多个路径,如下所示:

spring:
  cloud:
    gateway:
      routes:
        - id: instructors_route
          uri: lb://INSTRUCTOR-SERVICE/
          predicates:
            - Path=/api/v1/instructors**,/api/v1/countries**

答案 1 :(得分:0)

我发现了处理谓词组合的方法:

RouteDefinitionRouteLocator.java: combinePredicates

private AsyncPredicate<ServerWebExchange> combinePredicates(RouteDefinition routeDefinition) {
    List<PredicateDefinition> predicates = routeDefinition.getPredicates();
    AsyncPredicate<ServerWebExchange> predicate = lookup(routeDefinition, predicates.get(0));

    for (PredicateDefinition andPredicate : predicates.subList(1, predicates.size())) {
        AsyncPredicate<ServerWebExchange> found = lookup(routeDefinition, andPredicate);
        predicate = predicate.and(found);
    }

    return predicate;
}

由于它是私有方法,为了用执行Path谓词的逻辑析取(“ OR-ing”)的谓词组合逻辑覆盖此逻辑,扩展了{{1} }必须重新定义所有导致最终调用RouteDefinitionRouteLocator的方法(这不是采用最灵活的路由)。但是,通过重新实现如下方法,我能够实现所需的功能:

combinePredicates

然后,使用这个新类覆盖private AsyncPredicate<ServerWebExchange> combinePredicates(RouteDefinition routeDefinition) { //filter out "Path" predicates and place in separate list List<PredicateDefinition> predicates = routeDefinition.getPredicates(); List<PredicateDefinition> pathPredicates = new ArrayList(); for(PredicateDefinition predicate : predicates){ if (PATH_PREDICATE_NAME.equals(predicate.getName())) { pathPredicates.add(predicate); } } predicates.removeAll(pathPredicates); //create an uber predicate out of the "Path" predicates by combining them w/ `or` AsyncPredicate<ServerWebExchange> pathPredicate = null; if(pathPredicates.size()>0){ pathPredicate = lookup(routeDefinition, pathPredicates.get(0)); for (PredicateDefinition andPredicate : pathPredicates.subList(1, pathPredicates.size())) { AsyncPredicate<ServerWebExchange> found = lookup(routeDefinition, andPredicate); pathPredicate = pathPredicate.or(found); } } //"AND" together the uber path predicate and the rest of the predicates for the route AsyncPredicate<ServerWebExchange> predicate; List<PredicateDefinition> predicateSubList; if(pathPredicate != null) { predicate = pathPredicate; predicateSubList = predicates; } else { predicate = lookup(routeDefinition, predicates.get(0)); predicateSubList = predicates.subList(1, predicates.size()); } for (PredicateDefinition andPredicate : predicateSubList) { AsyncPredicate<ServerWebExchange> found = lookup(routeDefinition, andPredicate); predicate = predicate.and(found); } return predicate; } 中声明的routeDefinitionRouteLocator RouteLocator @Bean配置,可以使用新逻辑。