Menu
CoddyTech

Trang gọi API

Thuộc phần REST API trong hành trình Node.js của Coddy. Bài học 21 trên 25.

Một trang gọi API của bạn bằng fetch. Một yêu cầu POST cần ba tùy chọn: phương thức, tiêu đề và nội dung. Chuyển đối tượng JavaScript thành văn bản JSON để làm nội dung, rồi gắn nhãn văn bản đó là application/json.

const response = await fetch('/api/books', {
    method: 'POST',
    headers: {'Content-Type': 'application/json'},
    body: JSON.stringify({title: title}),
});
const data = await response.json();

Lần await đầu tiên nhận phản hồi HTTP. Lần thứ hai đọc nội dung JSON của phản hồi. response.ok cho bạn biết trạng thái có nằm trong phạm vi thành công hay không. Trạng thái như 400 hoặc 409 không khiến promise của fetch bị từ chối; nó trả về một phản hồi có ok là false. Code của biểu mẫu và danh sách đã được cung cấp; hãy tập trung vào việc gửi yêu cầu và xử lý kết quả.

Biến message đã được cung cấp, tham chiếu đến đoạn văn hiển thị thông báo trên trang. Gán văn bản hiển thị cho textContent, hoặc gán chuỗi rỗng để xóa thông báo:

message.textContent = data.error.message;
// Xóa thông báo sau khi thành công:
message.textContent = '';

Trang và API dùng chung một origin, nên lời gọi này không cần quyền CORS. FormData mã hóa biểu mẫu theo cách khác với JSON; hãy dùng văn bản JSON vì API này dùng express.json().

challenge icon

Thử thách

Dễ

API của bạn chưa có giao diện. Hãy tạo một trang nhỏ do cùng máy chủ cung cấp, trong đó biểu mẫu thêm tác vụ thông qua API.

  1. Trong server.js, cung cấp thư mục public bằng express.static, để GET / trả về public/index.html.
  2. Trong public/index.html, trình nghe sự kiện submit đã đọc tiêu đề. Hãy để nó gửi tác vụ mới đến API:
    • Dùng biến title được cung cấp, biến này chứa văn bản đầu vào.
    • Gửi tác vụ bằng fetch('/api/tasks', ...) với phương thức POST.
    • Nội dung phần thân là văn bản JSON được tạo bằng JSON.stringify, chẳng hạn như {"title":"Water the plants"}.
    • Yêu cầu cần có tiêu đề 'Content-Type': 'application/json' trong tùy chọn headers của fetch, nếu không express.json() sẽ không đọc phần thân.
  3. Nếu phản hồi OK (thuộc tính ok có giá trị true với mọi trạng thái từ 200 đến 299), hãy xóa biểu mẫu bằng form.reset(), xóa nội dung #message và gọi load() để danh sách hiển thị tác vụ mới.
  4. Nếu không, phần thân phản hồi có cấu trúc lỗi như ở phần trước, ví dụ:
    { "error": { "code": "conflict", "message": "A task with this title already exists" } }
    Hiển thị message của lỗi trong đoạn văn #message.

Các bước kiểm tra chạy tập lệnh trang được cung cấp này với một biểu mẫu mô phỏng nhỏ và API thực của bài học. Chúng gửi một tác vụ và một tác vụ trùng lặp, sau đó kiểm tra danh sách, biểu mẫu và thông báo. Bạn cũng có thể thử trang thực bên cạnh trình soạn thảo.

Thử ngay: gửi GET /. Trang sẽ mở trong chế độ xem trang với 3 tác vụ ban đầu. Nhập "Water the plants" rồi nhấn Add: ô nhập liệu sẽ trống và tác vụ xuất hiện ở cuối danh sách. Nhập lại "Water the plants" rồi nhấn Add: danh sách giữ nguyên và "A task with this title already exists" xuất hiện bên dưới biểu mẫu.

Tự làm thử

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Tasks</title>
</head>
<body>
    <h1>Tasks</h1>
    <ul id="list"></ul>
    <form id="add">
        <input name="title" placeholder="New task" required>
        <button>Add</button>
    </form>
    <p id="message"></p>
    <script>
        const list = document.querySelector('#list');
        const form = document.querySelector('#add');
        const message = document.querySelector('#message');

        async function load() {
            const response = await fetch('/api/tasks?limit=50');
            const page = await response.json();
            list.replaceChildren(...page.items.map((task) => {
                const item = document.createElement('li');
                item.textContent = (task.done ? '[x] ' : '[ ] ') + task.title;
                return item;
            }));
        }

        form.addEventListener('submit', async (event) => {
            event.preventDefault();
            const title = form.elements.title.value;
            // Send the title to POST /api/tasks as JSON. On success clear
            // the form and load() again; on an error show its message.
        });

        load();
    </script>
</body>
</html>

Tất cả bài học trong REST API

Tự luyện tập: Playground Express