1

I am using node.js in the server side. I have a RESTful service like;

app.get('/getAndroidVersion', function(req,res){res.json({version: config.androidVerion});});

This service must return version value from the config file. Although I am changing the androidVerion value in the config file node.js returns different value from the config value. For example in the config file version value is 2, but node.js returns 3.

After changing the version value in the config file I wrote a console.log statement before service call like that

app.get('/getAndroidVersion', function(req,res){console.log(config.androidVerion)    
   res.json({version: config.androidVerion});
});

It also writes different value from the config file to the console. What is the problem? Is node.js caches or return random values for the version number.

How can I handle this problem? Thank you.

Ivan Vasiljevic
  • 5,478
  • 2
  • 30
  • 35
mhendek
  • 273
  • 2
  • 5
  • 16

1 Answers1

3

Calls to require are cached.

From Node.js: Modules docs:

Modules are cached after the first time they are loaded. This means (among other things) that every call to require('foo') will get exactly the same object returned, if it would resolve to the same file.

You got a lot of options here:

Use fs.readFile for each request to read from disk

You can use readFile instead of require, to read your config file from disk for every request. This ensures you always get the most up-to-date version of the file.

Store config in a database

If this is a high-traffic app you might want to keep those config settings in a database instead of a file. DB engines usually avoid touching the disk for frequently executed queries.

Write your own persisted object mechanism

Going a step further, you can just write your own mechanism for storing K/V pairs; This mechanism should persist to disk any changes to the object when setting a value whilst avoiding touching the disk when attempting to get a value.

Here's an (untested) example:

const fs = require('fs')
const path = require('path')

class PersistedObject {
  constructor(path) {
    this.path = path
    this.obj = {}
  }

  load() {
    const json = fs.readFileSync(this.path, 'utf8')

    this.obj = json ? JSON.parse(json) : {}
  }

  set(key, value, cb) {
    this.obj[key] = value

    fs.writeFile(this.path, JSON.stringify(this.obj), cb)
  }

  get(key) {
    return this.obj[key]
  }
}

// Construct with a path to your config.json.
const config = new PersistedObject(path.resolve(__dirname, './config.json'))

// Load data from disk. Run this once on startup.
config.load()

// Calling `.set` sets the in-memory `obj`,
// and also persists the obj on disk.
config.set('firstName', 'Mary', (err, result) => {
  // Calls to `.get` use the in-memory `obj` and do not touch the disk.
  console.log(config.get('firstName')) // logs 'Mary'
})
nicholaswmin
  • 21,686
  • 15
  • 91
  • 167