Search code examples
javascriptnode.jsexpress

Javascript - Express.js - send regularly status responses to the client


i want to implement a logic where my express backend regularly sends updates to the client on how far a process reached at the moment.

For this i've created an example backend:

import express from 'express';

const app = express();

app.delete('/long-operation', (req, res) => {
  // Placeholder for the long operation
  for (let i = 0; i < 30000; i++) {
    setTimeout(() => {}, 1000);
    if (i % 100 === 0) {
      // Send Status Update to Client
    }
  }

  res.end();
});

app.listen(3000, () => {
  console.log('Server is running on http://localhost:3000');
});

For the regular update i thought of this:

{
  "percentage": 0,
  "message": "1 / 84102 deleted"
}

For the frontend im using Vue2.7 with axios.

I already tried a couple of things like:

  • new EventSource() -> this sends a GET Request and not a DELETE
  • Axios onDownloadProgress -> i couldn't get it to work and this is intended for file downloads

I also researched a bit about WebSockets but this seems a bit overkill for the problem.

I would like to have some kind of recommendation, for how i could do this. Im also open for a better solution if there is any.


Solution

  • You can write to the network stream in chunks. Call Response.write() each time a packet is available.

    app.delete('/long-operation', (req, res) => {
      /* •••Rest of code••• */
      // Send Status Update to Client
      res.write(/*update*/)
      /* •••Rest of code••• */
      res.end()
    })

    If no header is set, a header will be chosen implicitly based on the content of the body of the stream. On a Web Client that implements the Web API fetch(), this will be available through the body property of the Response object the Promise resolves with which will be a ReadableStream.

    It is pretty simple, network data is sent as streams so that large and small packets can easily be parsed. You see such ideas in Server Sent Events, Bidirectional Streams (e.g., WebSocket), et cetera.

    An Express Response is an enhanced version of NodeJS HTTP Response and it supports all built-in fields and methods.


    You can use this to implement Server Sent Events (set the right headers), Web Notifications, et cetera. Just as long as this should be a one way stream, this is enough. But if this should be a two way stream? We are now looking at a fundamentally different architectural requirement. That is where WebSocket excel.