Convention over Configuration vs Configuration over Convention: Tailoring API Calls Across Environments in React

Balancing Flexibility and Simplicity in API Management for React Applications

Rakesh Kumar
Nerd For Tech
7 min readMar 11, 2024

--

Convention over Configuration vs Configuration over Convention: Tailoring API Calls Across Environments in React — Balancing Flexibility and Simplicity in API Management for React Applications
Convention over Configuration vs Configuration over Convention: Tailoring API Calls Across Environments in React — Balancing Flexibility and Simplicity in API Management for React Applications

In software development, there are two main approaches to setting up applications: Convention over Configuration and Configuration over Convention.

Each has its own advantages and works better in different situations.

In this article, we’ll look at how these approaches can be used to tailor API calls for different environments in a React application.

We’ll also wrap up by discussing the methodology I use for my projects.

Convention over Configuration

Convention over Configuration (CoC) is a design paradigm that aims to decrease the number of decisions developers need to make by providing sensible defaults and standard conventions.

The system follows these conventions unless configured otherwise, reducing the complexity of configuration.

In a React application, for example, a convention could be that all API endpoints are the same across environments, except for the base URL, which changes based on the environment.

This can be set up using environment variables, and the application would know which base URL to use based on the current environment.

Implementing Convention over Configuration in React

To implement this in a React application, we can use the built-in process.env object, which gives us access to environment variables.

First, create a .env , .env.development and .env.production files in your project root and define your API endpoints for the each environments:

// .env.development or .env
REACT_APP_API_URL=https://dev.myapi.com

// .env.production
REACT_APP_API_URL=https://prod.myapi.com

Then, in your React code, you can access the API URL like this:

const API_URL = process.env.REACT_APP_API_URL;

Now, when you run your React app in development mode with npm start, it will use the development API URL.

When you build your app for production with npm run build, it will use the production API URL.

The main advantages are:

  • Simplicity: There’s less configuration to manage, which can make the codebase simpler and easier to understand.
  • Speed: It can be faster to get up and running with a new project or feature, as you don’t have to spend as much time on configuration.

The main disadvantages are:

  • Less flexibility: While Convention over Configuration provides sensible defaults, there might be cases where you need to deviate from the convention, which can be more difficult.
  • Hidden complexity: The conventions can sometimes hide complexity, making it harder to understand how to change things when you need to.

Configuration over Convention

Configuration over Convention (CoC), is a design paradigm that is opposite to Convention over Configuration.

In this approach, developers have full control over the application settings and can specify their own conventions.

This approach is more flexible and can be more suitable for complex applications with unique requirements.

In the context of tailoring API calls across environments in a React application, Configuration over Convention would mean specifying the API endpoints manually for each environment.

Here’s an example of how you might implement this:

Step 1:

Create a config.js file in your project:

let API_URL;

if (process.env.NODE_ENV === 'development') {
API_URL = 'http://localhost:3000';
} else if (process.env.NODE_ENV === 'production') {
API_URL = 'https://myapi.com';
} else if (process.env.NODE_ENV === 'test') {
API_URL = 'http://localhost:3001';
}

export { API_URL };

Step 2:

In your React code, you can import the API_URL like this:

import { API_URL } from './config';

In this example, you’re configuring the API URL based on the NODE_ENV environment variable, which is typically set to development, production, or test depending on the environment.

The main advantages are:

  • Flexibility: You have full control over the configuration, so you can handle any special cases or unique requirements.
  • Explicitness: Because everything is configured explicitly, it can be easier to understand how things are set up and how to change them.

The main disadvantages are:

  • Complexity: There’s more configuration to manage, which can make the codebase more complex and harder to understand.
  • Slower to start: It can take longer to get up and running with a new project or feature, as you have to spend more time on configuration.

Remember, environment variables should not be used to store sensitive information in a client-side application, as this information can be easily exposed. Make sure your environment files are not included in your version control system by adding them to your .gitignore file.

The Methodology I Adopt for My Projects.

In the practical world of software development, we often find ourselves juggling a plethora of information that varies across different environments.

It’s not just about the base API URL. We might need to manage default locale, AEM endpoints, CMS endpoints, feature flags, logging levels, database endpoints, and more.

Moreover, we often work across multiple environments, not just development and production. We may have staging, UAT, pre-prod, and other environments to consider.

In such scenarios, the Configuration over Convention approach can be a real game-changer.

It offers the flexibility and manageability we need to handle these varying pieces of information across different environments.

So, how do we go about creating different environment files and managing this information?

Let’s dive in and explore!

Step 1:

Setup new React project by running this command:

npx create-react-app my-app

Replace my-app with the name you want for your project. This command will create a new directory with the specified name, and it will set up a new React project in that directory.

Check below screenshot for the same.

Initial folder structure of react app using create-react-app command

Step 2:

Next, we’ll create an environment folder within the src folder, containing various environment-specific files.

These files will provide different information based on the specific environment.

// Define the default configuration
// these config will override by other environment files.
let environment = {
name: 'local', // Name of the environment
production: false, // Flag indicating whether this is a production environment
apiUrl: 'http://localhost:3000', // Base URL for the API
defaultLocale: 'en-us', // Default locale for the application
supportedLocales: 'es,jp', // Supported locales for the application
dbBaseUrl: 'http://localhost:1433', // Base URL for the database
loggingLevels: 'info,error,warn', // Logging levels for the application
showHeader: false // Flag indicating whether to show the header
};

// Start with the default configuration
let envConfig = { ...environment };

try {
// If the REACT_APP_ENV environment variable is set,
// then try to load the corresponding configuration file
// if REACT_APP_ENV=uat then "environment.uat.js" file will load
// and it will override values define in "environment.ts" file
const configs = process.env.REACT_APP_ENV
? require(`./environment.${process.env.REACT_APP_ENV}.js`).default
: {};

// Merge the default configuration with the environment-specific configuration
envConfig = {
...environment,
...configs
};
} catch (e) {
// If an error occurs (e.g., the configuration file doesn't exist)
// continue with the default configuration
envConfig = environment;
}

// Export the configuration so it can be used in other parts of the application
module.exports = envConfig;

Above code allows you to have different configurations for different environments (like development, testing, UAT, and production) and to easily switch between them by setting the REACT_APP_ENV environment variable.

The envConfig will then utilize these files to adjust the application's settings accordingly.

Step 3:

Next, we need to set up various scripts to run the app, each with a different REACT_APP_ENV value.

{
"name": "my-app",
"version": "0.1.0",
"private": true,
"dependencies": {...},
"scripts": {
"start": "REACT_APP_ENV=dev react-scripts start",
"start:staging": "REACT_APP_ENV=staging react-scripts start",
"start:uat": "REACT_APP_ENV=uat react-scripts start",
"build": "REACT_APP_ENV=prod react-scripts build",
"test": "REACT_APP_ENV=testing react-scripts test",
"eject": "react-scripts eject"
}
...
}

Step 4:

That’s it! You can now use these commands to launch your app with different environment variables.

// start app with REACT_APP_ENV=dev value and pick "environment.dev.ts" file
npm run start

// start app with REACT_APP_ENV=staging value and pick "environment.staging.ts" file
npm run start:staging

// start app with REACT_APP_ENV=uat value and pick "environment.uat.ts" file
npm run start:uat

// build app with REACT_APP_ENV=prod value and pick "environment.prod.ts" file
npm run build

And there you have it!

I trust this guide has been helpful in setting up your project with different configurations for various environments.

Remember, there’s more than one way to set up environment variables.

Why not give env-cmd or cross-env a whirl?

Keep exploring and happy coding!

Conclusion

Convention over Configuration and Configuration over Convention represent two ends of a spectrum.

The best choice depends on the specific needs of your project and your personal preference as a developer.

Some projects might benefit from the simplicity of Convention over Configuration, while others might require the flexibility of Configuration over Convention.

Understanding both paradigms allows you to make an informed decision on which approach to take when tailoring API calls across different environments in a React application.

Thank you so much for taking the time to read my article all the way through!

If you found it helpful or interesting, why not give it a round of applause by clicking those clap buttons?

And hey, don’t miss out on more insightful content — hit that follow button to stay updated!

Get email alerts for my latest Medium posts! Click here.

Let’s learn and grow together. Happy Coding! 👏

--

--

Rakesh Kumar
Nerd For Tech

Skilled in frontend and backend development, I create robust solutions following best practices, ensuring compliance, and considering future perspectives.