How to validate environment file in NodeJS

How to validate environment file in NodeJS:

 I’ll show you how to validate .env file with Joi validation. I’m currently using almost all of my ExpressJS apps. So let’s go..

1. Creating A Project

First let’s create a project. We’ll use npm for creating project. Open your terminal and go to location where you wanna create project folder. Then run the following commands in order.

mkdir project-folder-name
cd project-folder-name/
npm init -y
npm install joi dotenv

After all commands are executed open your project with your favourite IDE or text editor.

2. Creating Config File

In your terminal or IDE create a folder named config. Then inside config folder create a file named config.js.

Terminal command:

mkdir config
cd config/
touch config.js

After all commands are executed, our project folder structure will look like this:

3. Writing Config Code

Open config.js file in your IDE or text editor.

First we’ll import our required packages.

const dotenv = require('dotenv');
const joi = require('joi');
const path = require('path');

Why are we using these packages?

  1. dotenv : Dotenv is a zero-dependency module that loads environment variables from a .env file into process.env.
  2. joi : The most powerful schema description language and data validator for JavaScript.
  3. path : The path module provides utilities for working with file and directory paths.

After importing packages, we’re passing .env file location as an option to dotenv package. At the moment we don’t have a .env file yet. We’ll create later.

dotenv.config({ path: path.join(__dirname, '../.env') });

Creating Environment File Schema
const envVarsSchema = joi
  .object()
  .keys({
    NODE_ENV: joi
      .string()
      .valid("production", "development", "test")
      .required(),
    PORT: joi.number().postive().required(),
    API_SECRET: joi.string().required().description("My api secret"),
  })
  .unknown();

What Did We Do?

We created joi object type validation with our environment variable names and determined our rules.

  1. NODE_ENV: This key is a string and only accepts ‘production’, ‘development’ and ‘test’. If we give a different value it’ll throw an error. And it’s required.
  2. PORT: This key is a number and positive. If we give a negative value it’ll throw an error. And it’s required.
  3. API_SECRET: This key is a string and it’s required.
IMPORTANT NOTE

There’s a method named unknown at the end of the code. It’s overrides the handling of unknown keys for the scope of the current object only. (does not apply to children)

We’re using this method because; there are dozens of environment variables in process.env used by our operation system or other programs. So if we don’t use this method joi will throw an error.

Validating Our Schema

const { value: envVars, error } = envVarsSchema
  .prefs({ errors: { label: 'key' } })
  .validate(process.env);

We validated joi schema and we got destructured ‘value’ and ‘error’ variables from joi validation and we give an alias to ‘value’ variable named ‘envVars’.

Checking There’s An Error

if (error) {
  throw new Error(`Config validation error: ${error.message}`);
}

If there’s an error in schema we will throw an error.

Exporting Our Values

module.exports = {
  env: envVars.NODE_ENV,
  port: envVars.PORT,
  apiSecret: envVars.API_SECRET,
};

We exported our values as object.

Full Code Of config.js File

const dotenv = require("dotenv");
const joi = require("joi");
const path = require("path");

dotenv.config({ path: path.join(__dirname, "../.env") });

const envVarsSchema = joi
  .object()
  .keys({
    NODE_ENV: joi
      .string()
      .valid("production", "development", "test")
      .required(),
    PORT: joi.number().positive().required(),
    API_SECRET: joi.string().required().description("My api secret"),
  })
  .unknown();

const { value: envVars, error } = envVarsSchema
  .prefs({ errors: { label: "key" } })
  .validate(process.env);

if (error) {
  throw new Error(`Config validation error: ${error.message}`);
}

module.exports = {
  env: envVars.NODE_ENV,
  port: envVars.PORT,
  apiSecret: envVars.API_SECRET,
};

4. Creating .Env File

Go to project root directory and create a file named .env. Then write your environment variables to this file.

Your .env file should look like this:

NODE_ENV="development"
PORT=3000
API_SECRET="secret"
Enter fullscreen mode Exit fullscreen mode

5. Package.Json “Start” Script

Open your ‘package.json’ file and write your ‘start’ script.

"start": "node ."

My package.json file:

{
  "name": "project-folder-name",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "node .",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "dotenv": "^8.2.0",
    "joi": "^17.3.0"
  }
}

6. Creating Index.Js File

Go to project root directory and create a file named index.js. Then write your code.

I’ll print my config file to console. Every time i use the config file it’ll check my .env file is valid. So using before the application is useful because if there’s an error my application will not start.

My index.js File:

const config = require("./config/config");

console.log(config);
process.exit(0);

Run the start command from your terminal.

npm run start or npm start

My Output:

7. Let’s Check Is Validation Working?

I’ll remove ‘PORT’ variable from ’.env’ file and will start my application again.

Result:

And it’s working as expected. It’s throwing an error and saying; “PORT” is required.

Thanks to everyone who reads. I hope it was useful.

from Tumblr https://generouspiratequeen.tumblr.com/post/639809368235376640

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s