Menu
CoddyTech

Lendo o corpo

Parte da seção Fundamentos de Express do Journey de Node.js da Coddy. Lição 15 de 23.

Uma requisição POST envia dados no corpo, e o Express não lê o corpo a menos que você peça.

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 solicita algo; POST envia algo para ser criado. express.json() é um middleware que lê todos os corpos JSON em req.body. Sem ele, req.body é undefined. Uma rota que cria algo responde com o código 201 e aquilo que criou.

Verifique o corpo antes de salvá-lo. A ausência de um campo é um erro do cliente, então responda com o código 400 e não salve nada.

challenge icon

Desafio

Fácil

Os visitantes podem adicionar as próprias receitas. Um programa envia a nova receita como JSON no corpo de uma solicitação POST, e sua API a salva.

  1. Em server.js, adicione express.json() junto com as outras linhas app.use, acima das rotas, para que um corpo JSON chegue em req.body.
  2. Adicione uma rota para solicitações POST a /api/recipes. Ela lê title e tags do corpo, por exemplo {"title": "Miso Soup", "tags": ["vegan", "soup"]}.
  3. Ela cria a nova receita com o próximo número de id: as quatro receitas têm ids de 1 a 4, então a primeira nova receita recebe 5. Ela mantém o título e as tags recebidos. Se não vier tags, use uma lista vazia, [].
  4. Ela adiciona a receita ao array recipes, para que GET /api/recipes a liste. Em seguida, responde com o status 201 e a nova receita como JSON: {"id": 5, "title": "Miso Soup", "tags": ["vegan", "soup"]}
  5. Quando o corpo não tem title, ela não salva nada e responde com o status 400 e este JSON: {"error": "A recipe needs a title"}

Experimente: Pressione Executar. Escolha POST no seletor de método, digite /api/recipes como caminho e coloque {"title": "Miso Soup", "tags": ["vegan", "soup"]} na caixa do corpo. Você deverá ver o status 201 e a receita com "id": 5. Escolha GET e envie /api/recipes: cinco receitas, com Miso Soup por último. Depois, envie POST {"tags": ["dinner"]} para /api/recipes: status 400 e {"error":"A recipe needs a title"}. GET /api/recipes ainda lista cinco receitas.

Experimente você mesmo

import { escapeHtml } from './html.js';
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'));

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') envia texto simples, então cada título aparece em sua própria linha.
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 iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Fundamentos de Express

Pratique por conta própria: Playground de Express