Menu
CoddyTech

Memvalidasi input

Termasuk bagian REST API dalam perjalanan Node.js di Coddy. Pelajaran 6 dari 25.

Klien dapat mengirim apa saja di dalam body, dan if (!name) hanya menghentikan nilai kosong. 123, true, dan ["x"] bernilai truthy dan lolos. String yang berisi spasi juga lolos: tangani dengan trim(), karena ' '.trim() menghasilkan ''. Periksa tipe setiap field dengan typeof, lalu batas nilainya:

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' });
}

Tulis pesan untuk orang yang membaca respons: sebutkan nama field dan jelaskan nilainya harus seperti apa agar mereka tahu apa yang perlu diperbaiki. PATCH hanya memeriksa field yang dikirim, karena field lainnya tidak diubah.

challenge icon

Tantangan

Mudah

Saat ini, if (!title) membiarkan judul seperti 123 atau " " lolos. Periksa tipe dan ukuran setiap kolom sebelum menyimpannya.

  1. Di routes/tasks.js, pada rute POST, periksa title:
    • Nilainya harus berupa string.
    • Nilainya tidak boleh kosong atau hanya berisi spasi.
    • Panjangnya maksimal 100 karakter, termasuk spasi.

    Jika salah satu syarat ini tidak terpenuhi, kirim respons dengan status 400 dan kalimat error yang memuat kata title, misalnya:

    { "error": "title must be a string of 1 to 100 characters" }
  2. Di rute PATCH, periksa hanya kolom yang dikirim oleh body:
    • Jika body mengirim title, aturan dan jenis error yang sama berlaku.
    • Jika body mengirim done, nilainya harus true atau false. Jika tidak, kirim respons dengan status 400 dan error yang memuat kata done:
    { "error": "done must be true or false" }
    PATCH yang ditolak tidak mengubah apa pun.
  3. Body yang valid tetap berfungsi: POST tetap mengembalikan 201, dan PATCH dengan { "done": true } tetap mengembalikan 200. Biarkan PUT seperti semula; skema dengan zod juga memeriksanya.

Coba: Kirim POST { "title": 123 } ke /api/tasks: kamu mendapat 400 dengan error title. Kirim POST { "title": " " }: hasilnya juga 400. Kirim PATCH /api/tasks/2 dengan { "done": "yes" }: hasilnya 400 dengan error done, dan GET /api/tasks/2 tetap menampilkan "done": false. Kirim PATCH /api/tasks/2 dengan { "done": true }: hasilnya 200.

Coba sendiri

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;
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di REST API

Latihan sendiri: Playground Express