What to do:
-
Initialize project and install dependencies:
npm init -y
npm install express body-parser cors
npm install --save-dev nodemon
-
Create basic server:
const express = require('express');
const app = express();
app.use(express.json());
app.get('/', (req, res) => {
res.json({ message: 'API is running' });
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
Example:
Folder structure for scalability:
project/
├── src/
│ ├── controllers/
│ ├── routes/
│ ├── models/
│ ├── middleware/
│ └── app.js
├── .env
└── package.json
What to do:
-
Create modular routes:
const express = require('express');
const router = express.Router();
const { getUsers, createUser } = require('../controllers/users');
router.route('/')
.get(getUsers)
.post(createUser);
module.exports = router;
-
Implement controller logic:
const getUsers = async (req, res) => {
try {
const users = await User.find({});
res.status(200).json(users);
} catch (error) {
res.status(500).json({ message: error.message });
}
};
Example:
Registering routes in main app:
const userRoutes = require('./routes/users');
app.use('/api/users', userRoutes);
What to do:
-
Implement error middleware:
const errorHandler = (err, req, res, next) => {
const statusCode = err.statusCode || 500;
res.status(statusCode).json({
message: err.message,
stack: process.env.NODE_ENV === 'production' ? '🥞' : err.stack
});
};
-
Add security middleware:
app.use(helmet());
app.use(cors({
origin: process.env.CLIENT_URL
}));
app.use(rateLimit({
windowMs: 15 * 60 * 1000,
max: 100
}));
Example:
Custom error class for consistent errors:
class ErrorResponse extends Error {
constructor(message, statusCode) {
super(message);
this.statusCode = statusCode;
}
}
throw new ErrorResponse('User not found', 404);