It is possible on Express.js to send a response in chunk of data? I have tried (online demo):
const express = require('express');
const app = express();
const port = 3111;
const sleep = (ms) => {
return new Promise((resolve) => setTimeout(resolve, ms));
};
app.get('/', async (req, res) => {
res.setHeader('Content-Type', 'application/json');
// flush to enable stream
res.flushHeaders();
res.write('[');
for (let i = 1; i <= 1000; i++) {
res.write(JSON.stringify(`data ${i}`));
if (i + 1 <= 1000) {
res.write(',');
}
await sleep(1);
}
res.write(']');
res.end();
});
app.listen(port, () => {
console.log(`App is live at http://localhost:${port}`);
});
But both on Google Chrome and Postman, the response is showed only when res.end() is called
>Solution :
There are some considerations
- You should add a correct
Content-Typefor streams such asapplication/stream+json - Keep in mind that browsers and some HTTP clients may buffer the respond (they will not display the chunks as they arrive but instead wait until they receive the entire response), so you may need to consider using javascript to handle the response.
- You don’t need
res.flushHeaders()asExpressautomatically handle it when you start writing the response body
import express from "express";
const app = express();
const sleep = (ms) => {
return new Promise((resolve) => setTimeout(resolve, ms));
};
app.get('/stream', async (_req, res) => {
res.setHeader('Content-Type', 'application/stream+json');
res.write('[');
for (let i = 1; i <= 1000; i++) {
res.write(JSON.stringify(`data ${i}`));
if (i < 1000) {
res.write(",");
}
await sleep(1); // Simulates a delay
}
res.write(']');
res.end();
});
const port = 3000;
app.listen(port, () => {
console.log(`Server running on http://localhost:${port}`);
});