Proper way to parse environment variables

nflaig picture nflaig · Jan 5, 2020 · Viewed 9.2k times · Source

I am using node-config in basically all my projects and most of the time I come across the problem of parsing booleans and numbers which are set as environment variables.

E.g.

default.js

module.exports = { 
    myNumber = 10,
    myBool = true
}

custom-environment-variables.js

module.exports = { 
    myNumber = "MY_NUMBER",
    myBool = "MY_BOOL"
}

Now, the obvious problem is that if I override the default values with custom values set as environment variables they will be a string value instead of a number or boolean value. So now, to make sure in my code that the types are correct. I always have to do type conversion and for booleans use a proper library e.g. yn. The problem is I have to do this conversion every time I use config.get() for example +config.get("myNumber") or yn(config.get("myBool")).

Is there a better and more elegant way to do this?

One solution I see would be to add a type property to an environment variable as it is done here with format. This would allow to do something like this...

custom-environment-variables.js

module.exports = { 
    myNumber = {
        name: "MY_NUMBER",
        type: "number"
    },
    myBool = {
        name: "MY_BOOL",
        type: "boolean"
    }
}

node-config would handle the type conversions and there would be no need to do it all the time in the code when getting it. Of course there would be the requirement to implement a proper parser for booleans but those already exist and could be used here.

Answer

Sairam Krish picture Sairam Krish · Jun 9, 2020

By default, environment variables will be parsed as string. In node-config, we could override this behaviour with __format as shown below.

We don't need any additional libraries. Normal json datatypes like boolean, number, nested json etc., should work well.

Taking an easy to relate example.

config/default.json

{
  "service": {
    "autostart": false
  }
}

custom-environment-variables.json

{
  "service": {
    "autostart": {
      "__name": "AUTOSTART",
      "__format": "json"
    }
  }
}

Now we can pass environment variables when we like to override and no type conversation should be needed for basic types.