Express REST API Tutorial for Node.js | Routing
이 글의 핵심
Express REST API tutorial: routes, JSON body parsing, middleware pipeline, CRUD APIs, error handling, and security basics—learn to build production-style Node.js backends step by step.
Introduction
What is Express.js?
Express.js is a fast, unopinionated web framework for Node.js. Highlights:
- Small API surface for HTTP servers
- Middleware pipeline for cross-cutting concerns
- Flexible routing (paths, verbs, parameters)
- Template engines (EJS, Pug, etc.)
- Huge middleware ecosystem Typical uses: REST APIs, server-rendered sites, microservices, proxies.
1. Install and hello server
npm init -y
npm install express
npm install --save-dev nodemon
// app.js
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.send('Hello, Express!');
});
const PORT = 3000;
app.listen(PORT, () => {
console.log(`Server: http://localhost:${PORT}`);
});
Basic skeleton
const express = require('express');
const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.get('/', (req, res) => res.send('Home'));
app.get('/about', (req, res) => res.send('About'));
app.use((req, res) => {
res.status(404).send('Not found');
});
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).send('Server error');
});
app.listen(3000, () => console.log('Listening on :3000'));
2. Routing
HTTP verbs
app.get('/users', (req, res) => res.json({ users: ['Alice', 'Bob'] }));
app.post('/users', (req, res) => {
const user = req.body;
res.status(201).json({ message: 'created', user });
});
app.put('/users/:id', (req, res) => {
const { id } = req.params;
res.json({ message: `updated ${id}`, body: req.body });
});
app.patch('/users/:id', (req, res) => {
const { id } = req.params;
res.json({ message: `patched ${id}`, body: req.body });
});
app.delete('/users/:id', (req, res) => {
const { id } = req.params;
res.json({ message: `deleted ${id}` });
});
app.all('/secret', (req, res) => res.send('Secret'));
Route parameters & query
app.get('/users/:id', (req, res) => {
res.send(`User id: ${req.params.id}`);
});
app.get('/users/:userId/posts/:postId', (req, res) => {
res.json(req.params);
});
app.get('/search', (req, res) => {
const { q, page = 1, limit = 10 } = req.query;
res.json({ q, page: parseInt(page, 10), limit: parseInt(limit, 10) });
});
Routers
// routes/users.js
const express = require('express');
const router = express.Router();
router.get('/', (req, res) => res.json({ users: [] }));
router.get('/:id', (req, res) => res.json({ id: req.params.id }));
router.post('/', (req, res) => res.status(201).json({ ok: true }));
module.exports = router;
const usersRouter = require('./routes/users');
app.use('/api/users', usersRouter);
3. Middleware
function logger(req, res, next) {
console.log(`${req.method} ${req.url}`);
next();
}
app.use(logger);
app.use('/api', (req, res, next) => {
console.log('API prefix');
next();
});
Built-in
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(express.static('public'));
app.use('/static', express.static('public'));
Popular packages
npm install cors morgan helmet compression
const cors = require('cors');
const morgan = require('morgan');
const helmet = require('helmet');
const compression = require('compression');
app.use(cors());
app.use(morgan('dev'));
app.use(helmet());
app.use(compression());
Auth-style middleware (sketch)
function authenticate(req, res, next) {
const token = req.headers.authorization;
if (!token) {
return res.status(401).json({ error: 'Token required' });
}
try {
// Replace with your JWT/session verification
req.user = verifyToken(token);
next();
} catch {
res.status(401).json({ error: 'Invalid token' });
}
}
4. REST API (in-memory CRUD)
const express = require('express');
const app = express();
app.use(express.json());
let users = [
{ id: 1, name: 'Alice', email: 'alice@example.com' },
{ id: 2, name: 'Bob', email: 'bob@example.com' }
];
let nextId = 3;
app.post('/api/users', (req, res) => {
const { name, email } = req.body;
if (!name || !email) {
return res.status(400).json({ error: 'name and email required' });
}
const user = { id: nextId++, name, email };
users.push(user);
res.status(201).json(user);
});
app.get('/api/users', (req, res) => {
const page = parseInt(req.query.page, 10) || 1;
const limit = parseInt(req.query.limit, 10) || 10;
const start = (page - 1) * limit;
const slice = users.slice(start, start + limit);
res.json({
users: slice,
total: users.length,
page,
totalPages: Math.ceil(users.length / limit)
});
});
app.get('/api/users/:id', (req, res) => {
const id = parseInt(req.params.id, 10);
const user = users.find((u) => u.id === id);
if (!user) return res.status(404).json({ error: 'User not found' });
res.json(user);
});
app.put('/api/users/:id', (req, res) => {
const id = parseInt(req.params.id, 10);
const { name, email } = req.body;
const idx = users.findIndex((u) => u.id === id);
if (idx === -1) return res.status(404).json({ error: 'User not found' });
users[idx] = { id, name, email };
res.json(users[idx]);
});
app.delete('/api/users/:id', (req, res) => {
const id = parseInt(req.params.id, 10);
const idx = users.findIndex((u) => u.id === id);
if (idx === -1) return res.status(404).json({ error: 'User not found' });
users.splice(idx, 1);
res.status(204).send();
});
app.listen(3000);
HTTP status reference
| Code | Meaning | Typical use |
|---|---|---|
| 200 | OK | Successful GET/PUT |
| 201 | Created | POST created a resource |
| 204 | No Content | DELETE success |
| 400 | Bad Request | Validation failed |
| 401 | Unauthorized | Missing/invalid auth |
| 403 | Forbidden | Authenticated but not allowed |
| 404 | Not Found | Unknown route or id |
| 500 | Server Error | Unhandled exception |
5. Request and response
req.params, req.query, req.body (after parsers), req.headers, req.ip, res.send, res.json, res.status, res.redirect, res.cookie, res.render—see Express API.
6. Error handling
function asyncHandler(fn) {
return (req, res, next) => {
Promise.resolve(fn(req, res, next)).catch(next);
};
}
app.get('/users/:id', asyncHandler(async (req, res) => {
const user = await User.findById(req.params.id);
if (!user) throw new Error('Not found');
res.json(user);
}));
app.use((err, req, res, next) => {
const status = err.statusCode || 500;
res.status(status).json({
error: {
message: err.message,
...(process.env.NODE_ENV === 'development' && { stack: err.stack })
}
});
});
7. Examples in the Korean article
- Blog API — posts CRUD with query filters
- Multer — disk storage, file filter, size limits, error handling
- JWT + bcrypt — register/login sketch,
Bearermiddleware - EJS —
app.set('view engine','ejs'),res.render - Security — Helmet, CORS allowlist,
express-rate-limit, payload size limits - Production —
trust proxy, compression, morgan formats, PM2, Nginx reverse proxy
Code blocks match the original post; translate user-visible strings to English in your app.
8. Common issues
Headers already sent
Always return after sending an error response:
app.get('/users/:id', (req, res) => {
const user = users.find((u) => u.id === +req.params.id);
if (!user) return res.status(404).json({ error: 'Not found' });
res.json(user);
});
Middleware order
Register express.json() before routes that read req.body.
Missing next()
If a middleware does not end the response, it must call next().
Summary
Express gives you routing, middleware, and a thin layer over Node’s HTTP server—pair it with solid validation, auth, and error handling for production.
Next steps
Resources
Related posts
Frequently Asked Questions (FAQ)
Q. When would I use this in practice?
A. Express REST API tutorial: routes, JSON body parsing, middleware pipeline, CRUD APIs, error handling, and security basic…
Q. What should I read before this?
A. Follow the previous article or related articles links at the bottom of each post to learn in sequence.
Q. Where can I study this more deeply?
A. Check cppreference and the relevant library’s official documentation. The reference links at the end of the article are also worth using.
Related Articles (Internal Links)
Other articles related to this topic.
- Node.js 비동기 프로그래밍 | Callback, Promise, Async/Await
- Node.js 데이터베이스 연동 | MongoDB, PostgreSQL, MySQL
- Node.js JWT Authentication Complete Guide | bcrypt
Keywords Covered in This Article (Related Search Terms)
This article covers Node.js, Express, REST API, Middleware, Backend, Tutorial.