Menu
CoddyTech

순서가 중요합니다

Coddy Node.js 여정의 Express 기초 섹션에 포함된 레슨. 20개 중 12번째.

Express는 코드에서 추가한 순서대로 미들웨어와 라우트를 실행하며, 응답을 보내는 라우트에 도달하면 그곳에서 요청 처리가 끝납니다.

app.get('/bikes', (req, res) => {
    res.json(bikes);
});

app.use((req, res, next) => {
    res.set('Cache-Control', 'no-store');
    next();
});

res.set(name, value)는 응답에 헤더를 추가하며, 응답을 보내기 전에 실행되어야 합니다. 여기서는 미들웨어에 도달하기 전에 GET /bikes가 응답하므로, 해당 응답에는 헤더가 추가되지 않습니다. 미들웨어는 위에 있는 라우트에서 응답하지 않은 요청만 처리합니다. 모든 응답에 적용되어야 하는 미들웨어는 라우트와 express.static보다 위에 배치하세요.

challenge icon

챌린지

쉬움

페이지와 파일을 포함한 모든 응답에는 새로운 randomUUID()를 담은 node:crypto의 X-Request-Id 헤더가 포함됩니다.

GET /api/recipes를 두 번 전송하고 헤더를 비교한 다음, GET /style.css를 전송하세요.

직접 해보기

import express from 'express';
import { recipes } from './data.js';

const app = express();

app.use((req, res, next) => {
    console.log(`${req.method} ${req.url}`);
    next();
});

app.use(express.static('public'));

const escapeHtml = (text) =>
    text
        .replaceAll('&', '&')
        .replaceAll('<', '&lt;')
        .replaceAll('>', '&gt;')
        .replaceAll('"', '&quot;');

app.get('/', (req, res) => {
    const items = recipes.map((r) => `<li><a href="/recipes/${r.id}">${escapeHtml(r.title)}</a></li>`);
    res.send(`<link rel="stylesheet" href="/style.css"><h1>Recipe Box</h1><ul>${items.join('')}</ul>`);
});

// type('text')는 일반 텍스트를 전송하므로 각 제목이 한 줄씩 표시됩니다.
app.get('/recipes', (req, res) => {
    const { tag } = req.query;
    const list = tag ? recipes.filter((recipe) => recipe.tags.includes(tag)) : recipes;
    res.type('text').send(list.map((recipe) => recipe.title).join('\n'));
});

app.get('/recipes/:id', (req, res) => {
    const recipe = recipes.find((r) => r.id === Number(req.params.id));
    if (!recipe) {
        res.status(404).send('No such recipe');
        return;
    }
    res.send(recipe.title);
});

app.get('/api/recipes', (req, res) => {
    res.json(recipes);
});

app.get('/api/recipes/:id', (req, res) => {
    const recipe = recipes.find((r) => r.id === Number(req.params.id));
    if (!recipe) {
        res.status(404).json({ error: 'No such recipe' });
        return;
    }
    res.json(recipe);
});

app.get('/about', (req, res) => {
    res.send('Recipe Box collects family recipes.');
});

app.get('/menu', (req, res) => {
    res.redirect(301, '/recipes');
});

app.get('/menu/:id', (req, res) => {
    res.redirect(301, `/recipes/${req.params.id}`);
});

app.listen(3000, () => {
    console.log('Recipe Box is running on port 3000');
});

Express 기초의 모든 레슨