0

I am going to publish my first rest api soon. My question is, once I publish it, how can I update the code of the server? I already added versioning, but I still don't understand exactly what will happen when I push the new code. Doesn't the server need to restart if I push a new code? Or is it keeping old version of code unless new one is uploaded and ready to run and then it instantly replaces old code with new one. Can someone explain how exactly that process works? Because versioning is only applied to the routes, but what if I change something in the server.js file?

I haven't tried anything yet, don't have experience with this.

  • Some ideas on this: https://stackoverflow.com/a/72328806/16462950. But there are certainly other ways that do not require two ports. – Heiko Theißen Oct 28 '22 at 12:57

1 Answers1

0

Here is an example that illustrates how you can exchange an app in a running express server. It serves as an illustration, not as production-grade code!

Run node with the following code:

var app = express().use(function(req, res, next) {
  setTimeout(function() {
    res.end("App version 1");
  }, 5000);
});
express().use(function(req, res, next) {
  app(req, res, next);
}).listen(80);
readline.createInterface(process.stdin).on("line", function(line) {
  line = line.split(" ");
  if (line[0] === "upgrade") app = require("./" + line[1]);
});

and have a newer version of the app ready in a separate file (appv2.js, say):

module.exports = express().use(function(req, res, next) {
  res.end("App version 2");
});

Now if you type upgrade appv2 (plus ENTER) in the console of your running node process, it will replace app with the newer version, while the long-running (5 seconds) requests from the app version 1 still finish. Only requests received after the upgrade will be executed in app version 2.

If app version 2 needs an asynchronous initialization step, this should be completed before the switch from version 1 to version 2. This makes the upgrade command asynchronous. The file appv2.js would then look like

var app = express().use(function(req, res, next) {
  ...
});
module.exports = async function init() {
  // Initialization of app
  return app;
};

and the upgrade command becomes

readline.createInterface(process.stdin).on("line", async function(line) {
  line = line.split(" ");
  if (line[0] === "upgrade") app = await require("./" + line[1])();
});

With this approach, there is no server downtime: Requests that were received before the app = ... statement finishes behave according to version 1, requests after that behave according to version 2. Of course, this assumes that everything the app needs to know is contained in the appv2.js file. In the likely case that the app uses a database, and this database has to be upgraded as well, things become more complicated.

Heiko Theißen
  • 12,807
  • 2
  • 7
  • 31
  • Hi Heiko! Thank you for your answer. Does that mean that server shouldn't return some kind of "server not working" error while updating? – Freds Gallery Oct 30 '22 at 13:02
  • Just exchanging `app` does not require a server downtime. If you have a database as well, things are different. – Heiko Theißen Oct 30 '22 at 15:39