Spring Cloud Gateway - 如何传递动态 YAML 过滤器参数

Spring Cloud Gateway - how to pass dynamic YAML filter arguments

我有一个配置了 YML 的 Spring 云网关应用程序。我想创建一个自定义过滤器,基本上将两个端点的响应组合成一个全新的 object,然后返回给客户端。但是,在很多情况下,我想组合这样的 API 调用,并且为了避免在我的 YML 配置中为每个调用创建一个全新的路由,我想以某种方式动态传递过滤器参数它们是由对该路由的初始请求设置的一种方式。配置如下:

        - id: claims-composite-call-test-1
          uri: http://1.2.3.4:1234
          predicates:
            - Path=/claims/**
          filters:
            - name: CompositeClaimAndRequestFilter
              args:
                uris: http://1.2.3.4:1234/claims/v1/2000, http://1.2.3.4:1234/claims/v1/2000/requests/1

基本上过滤器所做的是当我点击上面的路由时(不管我使用什么路径),它向过滤器参数 uris 中指定的两个 URI 发出两个单独的 GET 请求。然后它将这些端点的两个响应组合成一个全新的 object 和 returns 给客户端。

但是,在这种情况下,我对我提出请求的两个 object 的 ID 进行了硬编码 - 它是两个参数的 2000 部分。所以现在,如果我想进行相同的复合调用,但对 ID 3000 的 object,我需要在我的配置中创建一个全新的路由,由于显而易见的原因,这是一个很大的不便。

有没有一种方法可以定义配置,使其通过发出的初始请求动态获取 object 的 ID,并在过滤器启动之前将其插入过滤器参数?

例如,我向 http://1.2.3.4:1234/claims/composite/5000 发出请求,然后配置将类似于:

        - id: claims-composite-call-test-1
          uri: http://1.2.3.4:1234
          predicates:
            - Path='/claims/composite/' + objectId
          filters:
            - name: CompositeClaimAndRequestFilter
              args:
                uris: 'http://1.2.3.4:1234/claims/v1/' + objectId, 'http://1.2.3.4:1234/claims/v1/' + objectId + '/requests/1'

因此生成的参数将分别为 http://1.2.3.4:1234/claims/v1/5000http://1.2.3.4:1234/claims/v1/5000/requests/1

当通过 YAML 配置网关时,这甚至可能吗?我知道我可以将 ID 作为 header 或 cookie 传递,但我不想修改默认的初始请求。提前致谢!

我找到了一种方法来做到这一点。基本上在配置中,我将所谓的 template variable 传递给 Path 谓词,如下所示:

        - id: claims-composite-call-test-1
          uri: http://1.2.3.4:1234
          predicates:
            - Path=/claims/v1/{claimId}
          filters:
            - name: CompositeClaimAndRequestFilter
              args:
                secondCallUri: http://1.2.3.4:1234/claims/v1/$$$claimId$$$/requests/1

通过用花括号传递它,我可以通过服务器交换访问它,并且可以像这样将它提取为字符串:

exchange    
    .getAttributes()
    .get(URI_TEMPLATE_VARIABLES_ATTRIBUTE)
    .toString()

官方 Spring 云网关在 host route predicate factory 部分对此进行了解释。

现在在过滤器 body 中,我可以获得 secondCallUri 参数并将其中的 $$$claimId$$$ 部分替换为我随请求传入的模板变量。

我的问题是是否有办法做同样的事情,而不是在 Path 谓词中传递变量,而是在过滤器的参数中进行。因此,例如,我可以用可以以某种方式动态设置的变量替换 secondCallUri 中的硬编码 1 吗?我知道我可以通过自定义 header 来做到这一点,但我希望有一种方法可以做到这一点而不必添加 header.