Menu
CoddyTech

첫 번째 미들웨어

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

로그에 한 줄을 기록하는 것처럼 모든 요청마다 필요한 작업도 있습니다. 그 작업을 각 라우트에 복사하는 일은 끝이 없을 것입니다.

let visits = 0;

app.use((req, res, next) => {
    visits++;
    next();
});

app.use에 전달하는 함수는 미들웨어입니다. Express는 미들웨어가 추가된 순서대로, 그 아래에 있는 라우트보다 먼저 모든 요청에 대해 이를 실행합니다. 미들웨어는 세 번째 인자인 next를 받습니다. next()를 호출하면 요청이 다음 단계로 넘어갑니다. 응답도 하지 않고 next()도 호출하지 않는 미들웨어가 있으면 요청은 영원히 대기 상태로 남습니다.

지난 장의 express.static도 미들웨어입니다. 파일을 찾으면 응답하고, 찾지 못하면 next()를 호출합니다.

challenge icon

챌린지

쉬움

모든 요청의 메서드와 경로를 GET /recipes/2처럼 출력하는 미들웨어를 추가하세요.

GET /recipes/2와 GET /nope를 전송한 다음 Console을 확인하세요.

직접 해보기

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

const app = express();

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');
});
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

Express 기초의 모든 레슨