When building scalable and maintainable APIs using Node.js and Express.js, adhering to a structured project setup and consistent naming conventions is essential. In enterprise-level projects, following best practices for naming ensures clarity, reduces bugs, and makes the application easier to maintain as it grows.
In this blog, we’ll explore the standard naming conventions used by large companies when managing API versioning in Node.js applications.
General Naming Guidelines (Best Practices)
When working on a large project, consistency is key. Below are some general naming conventions to follow across your entire Node.js codebase:
Entity | Convention | Example |
---|---|---|
Files & Folders | kebab-case | user.routes.js , auth.service.js |
Variables | camelCase | const userName = 'John'; |
Constants | UPPER_SNAKE_CASE | const MAX_USERS = 100; |
Classes | PascalCase | class UserService {} |
Functions | camelCase | getUserById() |
Routes | Plural nouns | /api/v1/users |
Route Parameters | camelCase in code, snake_case in URLs | req.params.userId , /users/:user_id |
Database Tables | snake_case | user_profiles |
Environment Vars | UPPER_SNAKE_CASE | DB_HOST=localhost |
Project Structure Naming Convention
Organizing your project structure in a scalable way is crucial for maintainability. Here’s a standard folder structure used in large companies:
project-root/
│
├── src/
│ ├── routes/
│ │ ├── v1/
│ │ │ ├── index.js
│ │ │ ├── user.routes.js
│ │ │ └── auth.routes.js
│ │ └── v2/
│ │ ├── index.js
│ │ ├── user.routes.js
│ │ └── auth.routes.js
│ ├── controllers/
│ │ ├── v1/
│ │ │ ├── userController.js
│ │ │ └── authController.js
│ │ └── v2/
│ │ ├── userController.js
│ │ └── authController.js
│ ├── middlewares/
│ ├── models/
│ ├── services/
│ ├── utils/
│ └── app.js
│
├── config/
│ └── db.js
│
├── tests/
│ ├── integration/
│ └── unit/
│
├── .env
├── .gitignore
├── package.json
└── server.js
Key Naming Rules:
- Use kebab-case for files and folders.
- Name routes after the resource they manage (e.g.,
user.routes.js
). - Group routes and controllers by version (e.g.,
v1
,v2
).
Route Naming Convention
Routes should be plural nouns to represent collections. Use HTTP methods to define operations and snake_case for URL parameters.
Example Routes:
Endpoint | HTTP Method | Description |
/api/v1/users | GET | Get all users |
/api/v1/users | POST | Create a new user |
/api/v1/users/:user_id | GET | Get a user by ID |
/api/v1/users/:user_id | PUT | Update a user by ID |
/api/v1/users/:user_id | DELETE | Delete a user by ID |
Controller Naming Convention
Controllers should be named after the resource they manage and placed in a versioned folder.
Example:
src/controllers/v1/userController.js
src/controllers/v2/userController.js
Controller File:
// src/controllers/v1/userController.js
exports.getAllUsers = (req, res) => {
res.status(200).json({ version: 'v1', users: [] });
};
exports.getUserById = (req, res) => {
res.status(200).json({ version: 'v1', user: { id: req.params.user_id } });
};
Service Naming Convention
Service files handle business logic and should be named in kebab-case with a .service.js
suffix.
Example:
src/services/user.service.js
Service File:
class UserService {
async getAllUsers() {
return [{ id: 1, name: 'John Doe' }];
}
async getUserById(userId) {
return { id: userId, name: 'John Doe' };
}
}
module.exports = new UserService();
Middleware Naming Convention
Middleware files should be named in kebab-case with a .middleware.js
suffix.
Example:
src/middlewares/auth.middleware.js
Middleware File:
module.exports = (req, res, next) => {
if (!req.headers.authorization) {
return res.status(401).json({ message: 'Unauthorized' });
}
next();
};
Model Naming Convention
Database models should be named in singular PascalCase in the code but snake_case in the database.
Example:
src/models/User.js
Database Table Name:
user_profiles
Model File:
const mongoose = require('mongoose');
const UserSchema = new mongoose.Schema({
name: {
type: String,
required: true,
},
email: {
type: String,
required: true,
unique: true,
},
});
module.exports = mongoose.model('User', UserSchema);
Environment Variable Naming Convention
Environment variables should use UPPER_SNAKE_CASE.
Example:
PORT=3000
MONGO_URI=mongodb://localhost:27017/myapp
JWT_SECRET=mysecretkey
In your code:
const dbHost = process.env.DB_HOST;
const jwtSecret = process.env.JWT_SECRET;
Summary of Key Practices
Type | Convention | Example |
Folder & Files | kebab-case | user.controller.js |
Variables | camelCase | const userName = 'John'; |
Constants | UPPER_SNAKE_CASE | const JWT_SECRET = 'xyz'; |
Classes | PascalCase | class UserService {} |
Functions | camelCase | getUserById() |
Routes | Plural nouns | /api/v1/users |
Params | snake_case in URLs | /users/:user_id |
By following these conventions, you can ensure that your Node.js project remains maintainable, scalable, and easy to understand for both current and future team members.
Comments