为Spring ReactiveFeignClient使用动态URL

问题描述 投票:0回答:2

我正在使用 Playtika 的 ReactiveFeignClient 我需要使用动态 URL,特别是对于主机部分,因为我想对具有相同请求和响应格式但主机不同的多个服务使用相同的接口。每个服务上的 URL 可以具有不同的主机名和前缀,但都具有相同的后缀。 例如:

  • http://localhost:3001/games/purchase
  • http://localhost:3002/gadgets/phone/purchase

实际上我不知道它是否与非反应式假客户端具有相同的行为。我遵循 How can I change the feign URL during the runtime?.

的建议

这是客户端界面。

@ReactiveFeignClient(
    name = "dummy",
    configuration = TransactionClient.Configuration.class
)
public interface TransactionClient {

//  @PostMapping("/purchase") // Using @PostMapping and @RequestLine both don't work
  @RequestLine("POST /purchase")
  Mono<PurchaseResponseDto> doPurchase(
      URI baseUrl,
      @Valid @RequestBody PurchaseRequestDto requestDTO
  );

  @RequiredArgsConstructor
  class Configuration {

    @Bean
    public ReactiveStatusHandler reactiveStatusHandler() {
      return new CustomStatusHandler();
    }
  }
}

这是自动配置

@Configuration
public class TransactionClientServiceAutoConfiguration {

  @Bean
  public Contract useFeignAnnotations() {
    return new Contract.Default();
  }

  @Bean
  @LoadBalanced
  public TransactionClient botRemoteClient() {
    return Feign.builder().target(Target.EmptyTarget.create(TransactionClient.class));
  }
}

但是,我收到错误消息,表明没有名为 dummy 的服务。这确实只是一个虚拟名称,因为 @ReactiveFeignClient 注解需要 name 参数,并且我想将该接口用于多个服务。

如何使@ReactiveFeignClient 可以使用动态url

spring-cloud-feign feign reactive-feign-client
2个回答
1
投票

从reactive feign github我找到了这个片段:

IcecreamServiceApi client = 
         WebReactiveFeign  //WebClient based reactive feign  
        .<IcecreamServiceApi>builder()
        .target(IcecreamServiceApi.class, "http://www.myUrl.com")

您可以通过创建客户端的新实例来更改 url。没找到其他办法。另外,我将 @PostMapping 和 @RequestLine("POST") 添加到 feign 接口中,因为我无法使合同选项起作用。 为后代分享此内容或直到出现更好的版本。


0
投票

使用

ReactiveHttpRequestInterceptor
@RequestHeader
的解决方法:

@ReactiveFeignClient(name = "ReactiveDynamicUrlApi", url = BASE_URL, path = "v1/api/product", configuration = ReactiveDynamicUrlApi.RequestInterceptor.class)
interface ReactiveDynamicUrlApi {

    String BASE_URL = "base-url";

    @PostMapping(path = "{id}", headers = "Content-Type=application/json")
    Mono<String> post(@RequestHeader(BASE_URL) String baseUrl, @PathVariable String id, @RequestHeader String token, @RequestBody Map requestBody);


    class RequestInterceptor implements ReactiveHttpRequestInterceptor {

        @Override
        public Mono<ReactiveHttpRequest> apply(final ReactiveHttpRequest request) {
            var uri = URI.create(request.headers().get(BASE_URL).getFirst() + request.uri().getPath());
            request.headers().remove(BASE_URL);
            return Mono.just(new ReactiveHttpRequest(request, uri));
        }

    }

}
© www.soinside.com 2019 - 2024. All rights reserved.