I'm finding this question incomplete without proper usage example of how things should be set up.
Since op did not mention target language I'm feeling like to share Kotlin setup that works in my case:
build.gradle.kts
implementation("org.springframework.boot:spring-boot-starter-webflux")
implementation("com.playtika.reactivefeign:feign-reactor-core:3.2.1")
implementation("com.playtika.reactivefeign:feign-reactor-spring-configuration:3.2.1")
implementation("com.playtika.reactivefeign:feign-reactor-webclient:3.2.1")
Config.kt
@Configuration
@EnableWebFlux
@EnableReactiveFeignClients
class Config {
}
MyFeignClient.kt
@Component
@ReactiveFeignClient(
url = "\${package.service.my-service-url}",
name = "client"
)
interface MyFeignClient {
@GetMapping(value = ["/my/url?my_param={my_value}"], consumes = ["application/json"])
fun getValues(
@PathVariable(name = "my_value") myValue: String?,
): Mono<MyEntity?>?
}
Then here goes code in some service class:
val myClient: MyFeignClient = WebReactiveFeign.builder<MyFeignClient>()
.contract(ReactiveContract(SpringMvcContract()))
.target(MyFeignClient::class.java, "http://example.com")
// feel free to add .block() to get unpacked value or just chain your logic further
val response = myClient.getValues(param)
Answer from im_infamous on Stack OverflowI'm finding this question incomplete without proper usage example of how things should be set up.
Since op did not mention target language I'm feeling like to share Kotlin setup that works in my case:
build.gradle.kts
implementation("org.springframework.boot:spring-boot-starter-webflux")
implementation("com.playtika.reactivefeign:feign-reactor-core:3.2.1")
implementation("com.playtika.reactivefeign:feign-reactor-spring-configuration:3.2.1")
implementation("com.playtika.reactivefeign:feign-reactor-webclient:3.2.1")
Config.kt
@Configuration
@EnableWebFlux
@EnableReactiveFeignClients
class Config {
}
MyFeignClient.kt
@Component
@ReactiveFeignClient(
url = "\${package.service.my-service-url}",
name = "client"
)
interface MyFeignClient {
@GetMapping(value = ["/my/url?my_param={my_value}"], consumes = ["application/json"])
fun getValues(
@PathVariable(name = "my_value") myValue: String?,
): Mono<MyEntity?>?
}
Then here goes code in some service class:
val myClient: MyFeignClient = WebReactiveFeign.builder<MyFeignClient>()
.contract(ReactiveContract(SpringMvcContract()))
.target(MyFeignClient::class.java, "http://example.com")
// feel free to add .block() to get unpacked value or just chain your logic further
val response = myClient.getValues(param)
You can check this library: https://github.com/Playtika/feign-reactive
implementation of Feign on Spring WebClient. Brings you the best of two worlds together: concise syntax of Feign to write client-side API on fast, asynchronous and non-blocking HTTP client of Spring WebClient
Looks like you are trying to use feign-reactive (https://github.com/Playtika/feign-reactive) to implement your REST clients. I am also using it for one of my projects and it looks like this library does not have an out-of-the-box way to specify basic auth credentials. At least no way to do this declaratively. So I didn't find a better way to do this than to abandon the auto-configuration via @ReactiveFeignClient and start configuring reactive feign clients manually. This way you can manually add "Authorization" header to all outgoing requests. So, provided this client definition:
public interface FeingClient {
@PostMapping("/api/students/special")
public Flux<Student> getAllStudents(@RequestBody Flux<SubjectStudent> lista);
}
Add the following configuration class to your Spring context, replacing username, password and service-url with your own data:
@Configuration
public class FeignClientConfiguration {
@Bean
FeignClient feignClient() {
WebReactiveFeign
.<FeignClient>builder()
.addRequestInterceptor(request -> {
request.headers().put(
"Authorization",
Collections.singletonList(
"Basic " + Base64.getEncoder().encodeToString(
"username:password".getBytes(StandardCharsets.ISO_8859_1))));
return request;
})
.target(FeignClient.class, "service-url");
}
}
Note, that this API for manual configurftion of reactive feign clients can differ between different versions of the reactive-feign library. Also note that this approach has a major drawback - if you start creating beans for your feign clients manually you lose the main advantage of Feign - ability to write REST-clients declaratively with just a few lines of code. E.g. if you want to use the above client with some sort of client-side load-balancing mechanism, like Ribbon/Eureka or Ribbon/Kubernetes, you will also need to configure that manually.
You can use a direct interceptor:
@Configuration
class FeignClientConfiguration {
@Bean
fun reactiveHttpRequestInterceptor(): ReactiveHttpRequestInterceptor {
return ReactiveHttpRequestInterceptor { request: ReactiveHttpRequest ->
request.headers()["Authorization"] = //insert data from SecurityContextHolder;
Mono.just(request)
}
}
}