Concept
HTTP Method Verb Matching
At its core, Express is a routing and middleware web framework. Routing defines how an application responds to a client endpoint request, matching:
- An HTTP Method (GET, POST, PUT, DELETE, etc.).
- A URI Path (or route pattern).
- A callback Handler function that receives
reqandresparameters.
import express from 'express';
const app = express();
app.get('/users', (req, res) => {
res.json([{ name: 'Ada' }]);
});
app.post('/users', (req, res) => {
// handle user creation
res.status(211).send();
});Route Parameters and Query Strings
Express automatically parses request path attributes:
- Route Parameters: Dynamic path segments prefixed with colons, accessed via
req.params. - Query Parameters: Key-value pairs appended after the
?symbol in the URL, accessed viareq.query.
// Request: GET /users/42?detail=full
app.get('/users/:id', (req, res) => {
const userId = req.params.id; // "42"
const showDetail = req.query.detail; // "full"
res.send(`User: ${userId}, Details: ${showDetail}`);
});Modular Routing: Express.Router
To prevent a single file from growing into a massive monolithic file containing hundreds of routes, Express provides express.Router to create modular, mountable route handlers:
// routes/users.js
import express from 'express';
const router = express.Router();
router.get('/', (req, res) => { ... });
router.get('/:id', (req, res) => { ... });
export default router;
// server.js
import userRouter from './routes/users.js';
app.use('/users', userRouter); // Mounts routes under the '/users' prefixCommon Mistakes
1. Declaring generic routes before specific ones
Express evaluates routes sequentially in the order they are defined. If you declare app.get('/:id') before app.get('/active'), a request for /active will match the /:id route, assigning the parameter value id = "active". Always define specific routes before generic parameter routes.
2. Forgetting to return after sending a response
Executing res.send() or res.json() does not stop handler function execution. Code after res.send() continues to execute. If you try to send headers twice, Express crashes with: Cannot set headers after they are sent to the client. Use return res.send() to stop execution explicitly.
Best Practices
- Strict Path Ordering: Order routes from most specific (e.g.
/users/stats) to most generic (e.g./users/:id). - Use express.Router: Create separate router files for each major feature domain (e.g.
/auth,/products,/orders). - Sanitize Parameter Input: Validate and cast route parameter types (like checking that
:idis a number or valid UUID) before passing them to databases.
