In real-world applications, integrating Spring Boot with external APIs is a common scenario. Particularly, when working with chatbot APIs or real-time services, streaming responses to clients efficiently is essential.
This post explains how to use OkHttp3 to call an external API and stream its response using Server-Sent Events (SSE).
1. What is SSE (Server-Sent Events)?
Server-Sent Events (SSE) is a technology that enables servers to push real-time updates to clients over HTTP. Unlike WebSockets, SSE is a unidirectional communication channel where the server continuously sends data to the client. SSE is widely used for real-time data streaming applications, such as stock prices, chat messages, and notifications.
2. Implementing SSE in Spring Boot
Spring Boot allows easy implementation of SSE using Flux<String>
.
To enable SSE support, we need to add the WebFlux dependency:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
3. Using OkHttp3 for API Calls and SSE Streaming
In a real-world scenario, we often need to call an external API using OkHttp3 and transform its response into an SSE stream.
Below is a sample implementation that processes an already available okhttp3.Response
object and streams it to the client using SSE.
@RestController
public class ChatController {
@GetMapping(value = "/chat-stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> streamChatResponse(@RequestParam String message) {
Sinks.Many<String> sink = Sinks.many().unicast().onBackpressureBuffer();
Response response = callChatApi(message); // API call logic
processResponse(response, sink);
return sink.asFlux();
}
private Response callChatApi(String message) {
return ChatApiClient.callApi(message); // Pre-implemented API call method
}
private void processResponse(Response response, Sinks.Many<String> sink) {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(response.body().byteStream()))) {
String line;
while ((line = reader.readLine()) != null) {
sink.tryEmitNext("data: " + line + "\n");
}
} catch (Exception e) {
sink.tryEmitNext("Error reading response: " + e.getMessage());
} finally {
sink.tryEmitComplete();
}
}
}
4. Receiving SSE Data on the Client Side
Clients can receive SSE data using the EventSource
API.
const eventSource = new EventSource("http://localhost:8080/chat-stream?message=Hello");
eventSource.onmessage = (event) => {
console.log("Received:", event.data);
};
eventSource.onerror = (error) => {
console.error("SSE Error:", error);
eventSource.close();
};
5. Summary
- SSE is an efficient way to push real-time data from the server to clients.
- OkHttp3 can be used to call external APIs and stream responses as SSE.
- Spring Boot allows easy SSE implementation using Flux<String>
.
- Clients can use EventSource
to receive streamed data.
6. Additional Considerations
- If streaming is unnecessary, consider returning a JSON response instead.
- Network issues may cause SSE connections to drop, so implementing a reconnection mechanism on the client side is advisable.
- WebFlux provides more efficient non-blocking processing than traditional Spring MVC.
Comments
Post a Comment