Menu
CoddyTech

요청 본문 읽기

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

POST 요청은 본문에 데이터를 보내며, Express는 요청하지 않으면 본문을 읽지 않습니다.

app.use(express.json());

app.post('/api/loans', (req, res) => {
    const { bookId, member } = req.body;
    res.status(201).json({ bookId, member, due: '2026-11-08' });
});

GET은 무언가를 요청하고, POST는 생성할 무언가를 보냅니다. express.json()은 모든 JSON 본문을 req.body로 읽어 들이는 미들웨어입니다. 이 미들웨어가 없으면 req.body는 undefined입니다. 무언가를 생성하는 경로는 생성한 항목과 함께 201 상태 코드로 응답합니다.

저장하기 전에 본문을 확인하세요. 필수 필드가 누락된 것은 클라이언트의 실수이므로 400 상태 코드로 응답하고 아무것도 저장하지 마세요.

challenge icon

챌린지

쉬움
  • POST /api/recipes에 { "title", "tags" }를 보내면 새 id가 포함된 레시피가 추가되고 201로 응답합니다.
  • title이 없으면 { "error": "A recipe needs a title" }와 함께 400으로 응답합니다.

본문을 포함해 POST를 보낸 다음 GET /api/recipes를 보내고, 이어서 title 없이 POST를 보내세요.

직접 해보기

import express from 'express';
import { randomUUID } from 'node:crypto';
import { recipes } from './data.js';

const app = express();

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

app.use((req, res, next) => {
    res.set('X-Request-Id', randomUUID());
    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');
});
quiz icon실력 점검

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

Express 기초의 모든 레슨