[2026] Express.js Complete Guide: Node.js Web Framework and REST APIs

[2026] Express.js Complete Guide: Node.js Web Framework and REST APIs

이 글의 핵심

Express.js tutorial: routing, middleware, JSON APIs, CRUD, Multer uploads, JWT auth basics, EJS, security (Helmet, CORS, rate limit), and production tips—ideal for Node.js backend learners.

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

아래 코드는 javascript를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

// 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

다음은 javascript를 활용한 상세한 구현 코드입니다. 에러 처리를 통해 안정성을 확보합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

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

다음은 javascript를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

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

아래 코드는 javascript를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

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

아래 코드는 javascript를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

// 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

아래 코드는 javascript를 사용한 구현 예제입니다. 함수를 통해 로직을 구현합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

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

다음은 간단한 javascript 코드 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(express.static('public'));
app.use('/static', express.static('public'));
npm install cors morgan helmet compression

아래 코드는 javascript를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

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)

아래 코드는 javascript를 사용한 구현 예제입니다. 함수를 통해 로직을 구현합니다, 비동기 처리를 통해 효율적으로 작업을 수행합니다, 에러 처리를 통해 안정성을 확보합니다, 조건문으로 분기 처리를 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

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)

다음은 javascript를 활용한 상세한 구현 코드입니다. 에러 처리를 통해 안정성을 확보합니다, 조건문으로 분기 처리를 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

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

CodeMeaningTypical use
200OKSuccessful GET/PUT
201CreatedPOST created a resource
204No ContentDELETE success
400Bad RequestValidation failed
401UnauthorizedMissing/invalid auth
403ForbiddenAuthenticated but not allowed
404Not FoundUnknown route or id
500Server ErrorUnhandled 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

다음은 javascript를 활용한 상세한 구현 코드입니다. 함수를 통해 로직을 구현합니다, 비동기 처리를 통해 효율적으로 작업을 수행합니다, 에러 처리를 통해 안정성을 확보합니다, 조건문으로 분기 처리를 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

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. Additional Express examples

  • Blog API — posts CRUD with query filters
  • Multer — disk storage, file filter, size limits, error handling
  • JWT + bcrypt — register/login sketch, Bearer middleware
  • EJSapp.set('view engine','ejs'), res.render
  • Security — Helmet, CORS allowlist, express-rate-limit, payload size limits
  • Productiontrust 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: 아래 코드는 javascript를 사용한 구현 예제입니다. 에러 처리를 통해 안정성을 확보합니다, 조건문으로 분기 처리를 수행합니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

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


... 996 lines not shown ... Token usage: 63706/1000000; 936294 remaining Start-Sleep -Seconds 3