Menu
CoddyTech

קריאת גוף הבקשה

חלק מהיחידה יסודות Express במסלול ה-Node.js של Coddy. שיעור 13 מתוך 20.

בקשת 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" } מוסיף מתכון עם מזהה חדש ומשיב 201 יחד איתו.
  • ללא title: מתקבל 400 עם { "error": "A recipe needs a title" }.

שלחו בקשת POST עם גוף, ואז GET /api/recipes, ואז בקשת 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