Menu
CoddyTech

Phản hồi JSON

Thuộc phần Kiến thức cơ bản về Express trong hành trình Node.js của Coddy. Bài học 6 trên 23.

Một chương trình gọi máy chủ của bạn cần dữ liệu mà nó có thể đọc, chứ không phải một câu văn.

app.get('/api/weather', (req, res) => {
    res.json({ city: 'Oslo', temp: 4, rain: true });
});

JSON là định dạng văn bản dành cho đối tượng và mảng. res.json(value) chuyển giá trị thành JSON và đặt tiêu đề Content-Type thành application/json; tiêu đề là một dòng có tên được gửi kèm phản hồi, và tiêu đề này cho biết nội dung theo sau thuộc loại nào. Máy khách nhận {"city":"Oslo","temp":4,"rain":true} và đọc temp dưới dạng số.

res.send với một chuỗi sẽ gửi text/html, khiến chương trình phải phân tích nội dung đó. Các route dành cho chương trình thường bắt đầu bằng /api, nên trang và dữ liệu không bao giờ dùng chung đường dẫn.

challenge icon

Thử thách

Dễ

Các chương trình, như ứng dụng điện thoại, cần dữ liệu của Recipe Box ở định dạng chúng có thể đọc. Thêm một API JSON bên cạnh các trang.

  1. Trong server.js, thêm một tuyến cho /api/recipes. Tuyến này gửi toàn bộ mảng recipes dưới dạng JSON.
  2. Thêm một tuyến cho /api/recipes/:id. Tuyến này tìm công thức như /recipes/:id, rồi gửi toàn bộ đối tượng công thức dưới dạng JSON, không chỉ riêng tiêu đề. Với công thức số 2, đó là đối tượng có "id": 2, "title": "Pancakes", "tags": ["breakfast", "sweet"] cùng số khẩu phần.
  3. Khi không có công thức nào có id đó, hãy phản hồi với trạng thái 404. Bạn có thể gửi văn bản No such recipe, như trang đó vẫn làm.

Thử nhé: Nhấn Chạy và gửi /api/recipes. Bạn sẽ thấy danh sách bốn công thức, bắt đầu bằng Tomato Soup. Gửi /api/recipes/2: đối tượng Pancakes. Gửi /api/recipes/99: trạng thái 404. Trong tab Headers, /api/recipes có Content-Type là application/json. Sau đó gửi /about: Content-Type của tuyến này là text/html, vì res.send gửi một trang khi nhận chuỗi.

Tự làm thử

import express from 'express';
import { recipes } from './data.js';

const app = express();

app.get('/', (req, res) => {
    res.send('Welcome to Recipe Box');
});

// type('text') gửi văn bản thuần túy, nên mỗi tiêu đề hiển thị trên một dòng riêng.
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('/about', (req, res) => {
    res.send('Recipe Box collects family recipes.');
});

app.listen(3000, () => {
    console.log('Recipe Box is running on port 3000');
});
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Kiến thức cơ bản về Express

Tự luyện tập: Playground Express