Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

186
Vistas
How to safely modify globals / write files in express POST request?

I am writing my first very simple express server for data a collection purpose. This seems like a beginner question but I failed to find an answer so far. The data is very small (less than 500 integers) and will never grow, but it should be able to be changed through POST requests.

I essentially (slightly simplified) want to:

  • Have the data in a .json file that is loaded when the server starts.
  • On a POST request, modify the data and update the .json file.
  • On a GET request, simply send the .json containing the data.

I don't want to use a database for this as the data is just a single small array that will never grow in size. My unclarities are mainly how to handle modifying the global data and file reading / writing safely, i.e. concurrency and how exactly does Node run the code.

I have the following

const express = require('express');
const fs = require('fs');

let data = JSON.parse(fs.readFileSync('./data.json'));

const app = express();
app.listen(3000);
app.use(express.json());

app.get("/", (req, res) => {
  res.sendFile('./data.json', { root: __dirname });
});

app.post("/", (req, res) => {
  const client_data = req.body;
  // modify global data
  fs.writeFileSync("./data.json", JSON.stringify(data), "utf8");
});

Now I have no idea if or why this is safe to do. For example, modifying the global data variable and writing to file. I first assumed that requests cannot run concurrently without explicitly using async functions, but that seems to not be the case: I inserted this:

const t = new Date(new Date().getTime() + 5000);
while(t > new Date()){}

into the app.post(.. call to try and understand how this works. I then made simultaneous POST requests and they finished at the same time, which I did not expect.

Clearly, the callback I pass to app.post(.. is not executed all at once before other POST requests are handled. But then I have a callback running concurrently for all POST requests, and modifying the global data and writing to file is unsafe / a race condition. Yet all code I could find online did it in this manner.

Am I correct here? If so, how do I safely modify the data and write it to file? If not, I don't understand how this code is safe at all?

about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

Code like that actually opens up your system to race conditions. Node actually runs that code in a single-threaded kind of way, but when you start opening files and all that stuff, it gets processed by multiple threads (opening files are not Node processes, they are delegated to the OS).

If you really, really want to use files as your global data, then I guess you can use an operating system concept called Mutual Exclusions. Basically, its a 'lock' used to prevent race conditions by forcing processes to wait while something is currently accessing the shared resource (or if the shared resource is busy). In Node, this can be implemented in many ways, but one recommendation is to use async-mutex library to handle concurrent connections and concurrent data modifications. You can do something like:

const express = require('express');
const fs = require('fs');
const Mutex = require('async-mutex').Mutex;

// Initializes shared mutual exclusion instance.
const mutex = new Mutex()

let data = JSON.parse(fs.readFileSync('./data.json'));

const app = express();
app.listen(3000);
app.use(express.json());

app.get("/", (req, res) => {
  res.sendFile('./data.json', { root: __dirname });
});

// Turn this into asynchronous function.
app.post("/", async (req, res) => {
  const client_data = req.body;

  const release = await mutex.acquire();
  try {
    fs.writeFileSync('./data.json', JSON.stringify(data), 'utf8');
    res.status(200).json({ status: 'success' });
  } catch (err) {
    res.status(500).json({ err });
  finally {
    release();
  }
});

You can also use Promise.resolve() in order to achieve similar results with the async-mutex library.

Note that I recommend you to use a database instead, as it is much better and abstracts a lot of things for you.

References:

  • Node.js Race Conditions
about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda