Imagine you’re on the final leg of a project, everything is set to go live, and boom! The app crashes because an environment variable is missing or misconfigured. Sound familiar? If you’ve been there, you know the frustration. But fear not, because Joi is here to save the day!
In this blog post, we’ll explore how we can use Joi to validate environment variables and set default values, ensuring your application runs smoothly across all environments.
The Problem
Environment variables are like the unsung heroes of our applications. They hold the keys to sensitive information, database connections, and various configuration settings. But with great power comes great responsibility:
- Missing Variables: “Why isn’t my app connecting to the database?” Oops, forgot to set DATABASE_URL.
- Incorrect Data Types: “Why is my server listening on port ‘three thousand’?” Typo in the PORT variable.
- Inconsistent Configuration: Development works fine, but production is a nightmare.
- Lack of Defaults: The app fails if certain variables aren’t set.
These issues can lead to sleepless nights and frantic debugging sessions. But what if you could avoid them altogether?
Enter Joi
Joi is a powerful schema description and data validation library for JavaScript. With Joi, you can define a schema for your environment variables, ensuring they meet specific criteria and setting default values where necessary.
Steps to Validate and Set Defaults with Joi
1. Install Joi & dotenv
First, you need to install Joi. Open your terminal and run:
npm install joi dotenv
# dotenv if you are reading env variables from .env file
2. Create a Configuration File
Create a file called config.js. This is where we'll define our schema and validate the environment variables.
const Joi = require('joi');
const dotenv = require('dotenv');
// Load environment variables from .env file
dotenv.config();
// Define the schema
const envSchema = Joi.object({
NODE_ENV: Joi.string().valid('development', 'production', 'test')
.default('development'),
PORT: Joi.number().default(3000),
DATABASE_URL: Joi.string().uri().required(),
API_KEY: Joi.string().required(),
// Add more variables as needed
}).unknown(); // Allow unknown keys
// Validate the environment variables
const { error, value: envVars } = envSchema.validate(process.env,
{ abortEarly: false }
);
if (error) {
console.error('Config validation error(s):');
error.details.forEach(detail => {
console.error(`- ${detail.message}`);
});
throw new Error('Environment variables validation failed.');
}
// Export the validated and normalized environment variables
module.exports = {
nodeEnv: envVars.NODE_ENV,
port: envVars.PORT,
databaseUrl: envVars.DATABASE_URL,
apiKey: envVars.API_KEY,
// Add more variables as needed
};
3. Use the Configuration in Your Application
const config = require('./config');
console.log(`Server is running on port ${config.port}`);
// Use config.databaseUrl, config.apiKey, etc.
Example with Errors
Let’s say we have the following .env file:
NODE_ENV=development
PORT=not_a_number
DATABASE_URL=
API_KEY=my_api_key
When we run our application, Joi will validate these variables. Here’s what happens:
- PORT is set to not_a_number, which is not a valid number.
- DATABASE_URL is empty, which is invalid since it’s a required field.
When Joi validates these variables, it will throw errors.
jaimin:~/joi-validate-env$ node index.js
Config validation error(s):
- "PORT" must be a number
- "DATABASE_URL" is not allowed to be empty
/home/jaimin/joi-validate-env/config.js:27
throw new Error('Environment variables validation failed.');
^
Error: Environment variables validation failed.
at Object.<anonymous> (/home/jaimin/joi-validate-env/config.js:27:9)
at Module._compile (node:internal/modules/cjs/loader:1376:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1435:10)
at Module.load (node:internal/modules/cjs/loader:1207:32)
at Module._load (node:internal/modules/cjs/loader:1023:12)
at Module.require (node:internal/modules/cjs/loader:1235:19)
at require (node:internal/modules/helpers:176:18)
at Object.<anonymous> (/home/jaimin/joi-validate-env/index.js:1:16)
at Module._compile (node:internal/modules/cjs/loader:1376:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1435:10)
This detailed error report helps quickly identify and fix issues in the environment configuration.
Why Use Joi?
1. Consistency
No more “works on my machine” moments. Joi ensures all necessary environment variables are set and have correct types across different environments.
2. Default Values
Set default values for variables, reducing the risk of runtime errors due to missing settings.
3. Early Error Detection
Catch configuration errors early in the startup phase, preventing the application from running with invalid settings.
4. Schema Documentation
Acts as a self-documenting schema for environment variables, making it easier for new developers to understand the required configuration.
5. Flexibility
Allows for complex validation logic, such as value ranges, specific formats, and custom validation functions.
Conclusion
Using Joi to validate environment variables and set default values is like having a safety net for your application. It ensures your app runs smoothly across all environments, sparing you from unexpected crashes and hours of debugging.
By adopting this approach, you can avoid common pitfalls related to environment variables and focus on building features that add value to your users. So go ahead, integrate Joi into your project, and sleep soundly knowing your environment variables are in good hands.
Happy coding!
Top comments (0)