0

My question is related to Feign and whether or not Feign calls to SSE interfaces are blocking.

I have prepared a test API with SSE, the code as flow.

Feign Client calls it take 10 seconds to display the results.

But with WebClient, I can immediately see the output: 'data:1 d..' even in the first second of start calling. Over time, the remaining text will also be gradually printed out.

 @GetMapping(value = "/mockChatSteam", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> stream() {
        return Flux.just(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
                .map(seq -> "SSE - " + seq)
                .delayElements(Duration.ofSeconds(1));
    }

How can I achieve this effect like WebClient by using the Feign client?

=============================================

I have been trying to use Feign to call OpenAi's conversation API, which uses Server-sent Events (SSE).

To accomplish this, I have included the feign-reactive-wrappers dependency in my project:

<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-reactive-wrappers</artifactId>
    <version>12.3</version>
</dependency>

After that, I defined a FeignClient and wrote the following code in the controller:

@GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> stream() {
    return feignClient.getSSEStream(...);
}

@Bean
public FeignClient feignClient(){
 return ReactorFeign.builder().target(FeignClient.class);
}

 //https://platform.openai.com/docs/api-reference/completions/create
public interface FeignClient{

    @RequestLine("POST /v1/chat/completions")
    @Headers({
            "Authorization: Bearer {apiKey}",
    })
    Flux<String> getSSEStream(@Param("apiKey")String apiKey, ChatRequest request);

}

However, I noticed that Feign does not display each piece of data as it arrives, like "The Typewriter print text one by one." ,but instead waits until all the data has been received before returning it.

In contrast, the Spring WebClient (using Spring 6 HTTP Interface ) correctly handles SSE data and returns the text one by one to the page.

public interface ChatGptService {
    @PostExchange("/v1/chat/completions")
    Flux<String> completionsSteam(@RequestHeader MultiValueMap<String, String> multiValue, @RequestBody ChatRequest request);
}

How should I handle this feign client issue?

I appreciate any help you could provide. Thank you in advance!

zy_sun
  • 175
  • 1
  • 11
  • I don't fully understand the question, but reactive implementation is built on async mechanism. (For example: when callback can run to handle the response, it can emit data into mono or flux) In other words, the reactive approach is able to react to incoming data without thread block. If you doubt that the thread will be blocked there is solution in reactor project's documentation. – Numichi May 18 '23 at 14:25
  • @Numichi Sorry, I didn't explain it very clearly. I have prepared a test interface with SSE. Feign Client calls it take 10 seconds to display the results. But with WebClient, I can immediately see the output: 'data:1 d..' even in the first second of start calling. Over time, the remaining text will also be gradually printed out. – zy_sun May 18 '23 at 14:53
  • Is it not OK? `return feignClient.getSSEStream(...).delayElements(Duration.ofSeconds(1));` – Numichi May 18 '23 at 18:39
  • getSSEStream(...).delayElements(Duration.ofSeconds(1)) not working – zy_sun May 19 '23 at 02:07

0 Answers0