Receive Server-Sent Events in Node.js: An EventSource Alternative Using Fetch API
Real-time applications depend heavily on Server-Sent Events (SSE) to maintain seamless data exchange between the server and the client. Conventionally, developers leverage the EventSource
interface for receiving SSE. However, there are two main constraints with this method:
- It is not natively available in Node.js, requiring an additional package to function.
- It only supports GET requests, limiting its use cases.
In this post, we introduce an alternative, the Fetch API coupled with getReader()
, which can handle SSE from both GET and POST requests. As an added benefit, as of Node.js version 18, the Fetch API comes as an experimental feature enabled by default, requiring no extra packages.
Understanding EventSource's Limitations
The EventSource
API maintains a persistent connection from a client to a server, allowing real-time data updates from the server. A typical usage looks like this:
const source = new EventSource("/sse");
source.onmessage = (event) => {
console.log("Received", event.data);
};
The primary drawback of EventSource
is its exclusive reliance on GET requests. If the given API endpoint, such as /sse
, is set to POST instead of GET, it won't be compatible. Moreover, EventSource
isn't included in Node.js's standard library, so leveraging it necessitates adding an external package, which expands your project's dependency footprint.
The Fetch API and getReader(): A Versatile Alternative
The Fetch API in Node.js offers a compelling alternative for handling SSE with both GET and POST requests. Here's an example:
const response = await fetch("/sse", { method: "POST" });
const reader = response.body.getReader();
const decoder = new TextDecoder("utf-8");
while (true) {
const { value, done } = await reader.read();
if (done) break;
console.log("Received", decoder.decode(value));
}
In this snippet, a POST request is made to the server using the Fetch API. The response's body content is read through getReader()
, and a TextDecoder
object decodes the received data chunks into strings. This approach handles large data sets efficiently, processing the data in chunks as it arrives.
For more information about the
getReader()
method, have a look at the mdn documentation.
Importantly, the Fetch API comes as an experimental feature in Node.js. It's enabled by default starting from version 18, eliminating the need for an extra package and making it an attractive choice over EventSource
in Node.js.
Wrapping Up
While EventSource
remains a useful tool for handling SSE with GET requests, the Fetch API and getReader()
present an out-of-the-box alternative for Node.js users, enabling both GET and POST requests. The choice between the two would largely depend on your project's specific needs and architectural design. By understanding both methods, developers can make an informed choice, building more efficient and versatile real-time applications.
Bonus: ChatGPT Demo
If you want to stream the response from the ChatGPT API, have a look at the following blog post:
Stream Real-time Feedback with ChatGPT: SSE via Fetch in Node.js
Dive into real-time feedback with ChatGPT! Explore how to implement Server-Sent Events (SSE) via Fetch in Node.js, seamlessly streaming ChatGPT responses directly to your terminal. 🚀🔧