Validar la entrada
Parte de la sección API REST del Journey de Node.js de Coddy. Lección 6 de 25.
Un cliente puede enviar cualquier cosa en el cuerpo, y if (!name) solo detiene los valores vacíos. 123, true y ["x"] son valores truthy y pasan. Una cadena de espacios también pasa: contrólala con trim(), ya que ' '.trim() es ''. Comprueba el tipo de cada campo con typeof y, después, sus límites:
const { seats } = req.body ?? {};
if (typeof seats !== 'number' || !Number.isInteger(seats) || seats < 1) {
return res.status(400).json({ error: 'seats must be a whole number from 1' });
}Escribe el mensaje pensando en quien lee la respuesta: nombra el campo y di qué valor debe tener para que sepa qué corregir. Una solicitud PATCH comprueba solo los campos que se le enviaron, ya que los demás no están cambiando.
Desafío
FácilAhora mismo, if (!title) deja pasar títulos como 123 o " ". Comprueba el tipo y el tamaño de cada campo antes de guardarlo.
- En
routes/tasks.js, en la ruta POST, compruebatitle:- Debe ser una cadena.
- No debe estar vacío ni contener solo espacios.
- Debe tener como máximo 100 caracteres, incluidos los espacios.
Si no se cumple alguna de estas condiciones, responde con el estado 400 y una frase de
errorque contenga la palabratitle, por ejemplo:{ "error": "title must be a string of 1 to 100 characters" } - En la ruta PATCH, comprueba solo los campos que envía el cuerpo:
- Si envía
title, se aplica la misma regla y el mismo tipo de error. - Si envía
done, debe sertrueofalse. De lo contrario, responde con el estado 400 y un error que contenga la palabradone:
Si se rechaza un PATCH, no se cambia nada.{ "error": "done must be true or false" } - Si envía
- Los cuerpos válidos siguen funcionando: POST sigue devolviendo 201 y PATCH con
{ "done": true }sigue devolviendo 200. Deja PUT como está; Schemas también lo comprueba con zod.
Pruébalo: envía POST { "title": 123 } a /api/tasks: obtienes 400 con el error de title. Envía POST { "title": " " }: también obtienes 400. PATCH /api/tasks/2 con { "done": "yes" }: obtienes 400 con el error de done, y GET /api/tasks/2 sigue mostrando "done": false. PATCH /api/tasks/2 con { "done": true }: obtienes 200.
Pruébalo tú mismo
import { Router } from 'express';
import { nextId, tasks } from '../store.js';
const router = Router();
router.get('/', (req, res) => {
res.json(tasks);
});
router.get('/:id', (req, res) => {
const task = tasks.find((t) => t.id === Number(req.params.id));
if (!task) {
return res.status(404).json({ error: 'Task not found' });
}
res.json(task);
});
router.post('/', (req, res) => {
const { title } = req.body ?? {};
if (!title) {
return res.status(400).json({ error: 'title is required' });
}
const task = { id: nextId(), title, done: false, createdAt: new Date().toISOString() };
tasks.push(task);
res.status(201).location(`/api/tasks/${task.id}`).json(task);
});
router.patch('/:id', (req, res) => {
const task = tasks.find((t) => t.id === Number(req.params.id));
if (!task) {
return res.status(404).json({ error: 'Task not found' });
}
const { title, done } = req.body ?? {};
if (title !== undefined) task.title = title;
if (done !== undefined) task.done = done;
res.json(task);
});
router.put('/:id', (req, res) => {
const index = tasks.findIndex((t) => t.id === Number(req.params.id));
if (index === -1) {
return res.status(404).json({ error: 'Task not found' });
}
const { title, done } = req.body ?? {};
if (title === undefined || done === undefined) {
return res.status(400).json({ error: 'PUT needs every field: title and done' });
}
const { id, createdAt } = tasks[index];
tasks[index] = { id, title, done, createdAt };
res.json(tasks[index]);
});
router.delete('/:id', (req, res) => {
const index = tasks.findIndex((t) => t.id === Number(req.params.id));
if (index === -1) {
return res.status(404).json({ error: 'Task not found' });
}
tasks.splice(index, 1);
res.status(204).end();
});
export default router;
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de API REST
1Recursos y verbos
Recursos y URLCrear con POST4Navegadores, versiones y configuración
Qué es un origenPermitir otro origenCORSUna página que llama a la API2Validación y errores
Validar la entradaPractica por tu cuenta: Playground de Express