Set up an Express server, define routes for all HTTP methods, write middleware, and understand the request/response cycle.
mkdir my-api && cd my-api
npm init -y
npm install express
npm install -D nodemonconst express = require('express');
const app = express();
const PORT = process.env.PORT || 3000;
// Built-in middleware: parse JSON bodies
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// Routes
app.get('/', (req, res) => {
res.json({ message: 'API is running' });
});
app.get('/users/:id', (req, res) => {
const { id } = req.params; // route params
const { page = 1 } = req.query; // query string
res.json({ id, page });
});
app.post('/users', (req, res) => {
const { name, email } = req.body; // JSON body
// save to DB...
res.status(201).json({ name, email });
});
app.listen(PORT, () => console.log(`Server on port ${PORT}`));// Middleware: runs before route handlers
// Must call next() or the request hangs
// Request logger
app.use((req, res, next) => {
console.log(`${req.method} ${req.path} ${new Date().toISOString()}`);
next();
});
// Route-specific middleware
function requireApiKey(req, res, next) {
const key = req.headers['x-api-key'];
if (key !== process.env.API_KEY) {
return res.status(401).json({ error: 'Unauthorized' });
}
next();
}
app.get('/secure', requireApiKey, (req, res) => {
res.json({ secret: 'data' });
});app.use() runs in order for every request. Put your logger first, auth middleware before protected routes, error handlers last.app.use() adds middleware. app.get/post/put/delete() adds routes.(req, res, next). Call next() to pass to the next handler.req.params = route params. req.query = query string. req.body = parsed body (needs middleware).res.json(data) sends JSON. res.status(201).json(data) sets the status code.