hocvietcode.com
  • Trang chủ
  • Học lập trình
    • Lập trình C/C++
    • Cấu trúc dữ liệu và giải thuật
    • Lập trình HTML
    • Lập trình Javascript
      • Javascript cơ bản
      • ReactJS framework
      • AngularJS framework
      • Typescript cơ bản
      • Angular
      • NodeJS
    • Lập trình Mobile
      • Lập Trình Dart Cơ Bản
        • Dart Flutter Framework
    • Cơ sở dữ liệu
      • MySQL – MariaDB
      • Micrsoft SQL Server
      • Extensible Markup Language (XML)
      • JSON
      • MongoDB
    • Lập trình PHP
      • Lập trình PHP cơ bản
      • Laravel Framework
    • Lập trình Java
      • Java Cơ bản
    • Lập trình C#
      • Lập Trình C# Cơ Bản
      • ASP.NET Core MVC
    • Machine Learning
    • Git và Github
  • WORDPRESS
    • WordPress cơ bản
    • WordPress nâng cao
    • Chia sẻ WordPress
  • Kiến thức hệ thống
    • Microsoft Azure
    • Docker
    • Linux
  • Chia sẻ IT
    • Tin học văn phòng
      • Microsoft Word
      • Microsoft Excel
    • Marketing
      • Google Adwords
      • Facebook Ads
      • Kiến thức khác
    • Chia sẻ phần mềm
    • Review công nghệ
    • Công cụ – tiện ích
      • Kiểm tra bàn phím online
      • Kiểm tra webcam online
Đăng nhập
  • Đăng nhập / Đăng ký

Please enter key search to display results.

Home
  • NodeJS
Xây dựng RESTful API với Express và HTTP trong nodejs

Xây dựng RESTful API với Express và HTTP trong nodejs

  • 22-07-2026
  • Toanngo92
  • 0 Comments

API là hợp đồng giúp hai phần mềm giao tiếp với nhau. Trong ứng dụng Node.js, HTTP API thường nhận request từ trình duyệt, ứng dụng di động hoặc dịch vụ khác, xử lý nghiệp vụ rồi trả response dưới dạng JSON. Bài này giải thích mối quan hệ giữa HTTP API và REST, sau đó xây dựng một CRUD API bằng Express.

Minh họa RESTful và HTTP API trong Node.js
Session 8: RESTful and HTTP APIs.

Mục lục

  • 1. API là gì?
  • 2. Các loại API thường gặp trong Node.js
  • 3. HTTP API và RESTful API
    • Các đặc điểm quan trọng
  • 4. Phương thức HTTP và CRUD
  • 5. Mã trạng thái HTTP cần dùng đúng
  • 6. Khởi tạo dự án Express
  • 7. Route GET
  • 8. Kiểm tra dữ liệu đầu vào
  • 9. Route POST tạo tài nguyên
  • 10. Route PATCH và DELETE
  • 11. Xử lý route không tồn tại và lỗi server
  • 12. Kiểm thử bằng curl
  • 13. JSON Schema và validation
  • 14. Thực hành tốt khi xây dựng API
  • Tổng kết

1. API là gì?

Application Programming Interface là tập hợp quy tắc cho phép một thành phần yêu cầu dữ liệu hoặc chức năng từ thành phần khác. Client chỉ cần biết cách gửi request và đọc response; nó không cần biết server lưu dữ liệu hay xử lý nội bộ như thế nào.

API kết nối các ứng dụng trong quy trình thanh toán
API đóng vai trò trung gian trong một quy trình thanh toán.

Trong ví dụ thanh toán, website gửi thông tin giao dịch đến dịch vụ thanh toán qua API. Dịch vụ trả kết quả để website thông báo cho người dùng. Cùng một API có thể phục vụ website, ứng dụng di động và hệ thống nội bộ.

2. Các loại API thường gặp trong Node.js

  • Core API: API tích hợp sẵn của Node.js như node:http, node:fs và node:path.
  • Third-party API: thư viện npm hoặc dịch vụ do bên khác cung cấp.
  • Custom API: API do nhóm phát triển tự xây dựng cho nghiệp vụ riêng.
  • Web/HTTP API: API được truy cập qua HTTP hoặc HTTPS.
Các loại API được sử dụng trong Node.js
Core API, third-party API, custom API và RESTful API.

3. HTTP API và RESTful API

HTTP API là khái niệm rộng: bất kỳ API nào giao tiếp bằng HTTP đều thuộc nhóm này. REST là một kiểu kiến trúc. Một RESTful API dùng tài nguyên, URI, phương thức HTTP, biểu diễn dữ liệu và tính stateless theo cách nhất quán.

Vì vậy, mọi RESTful API chạy trên HTTP đều là HTTP API, nhưng không phải HTTP API nào cũng tuân thủ REST. Ví dụ POST /getStudent vẫn là HTTP API, nhưng thiết kế GET /students/10 thể hiện tài nguyên và ngữ nghĩa HTTP rõ hơn.

Các đặc điểm quan trọng

  • Client–server: giao diện client và xử lý dữ liệu server có thể phát triển độc lập.
  • Stateless: mỗi request mang đủ thông tin cần thiết; server không suy diễn người dùng chỉ từ kết nối mạng trước đó.
  • Uniform interface: tài nguyên có URI ổn định, thao tác thể hiện bằng phương thức HTTP.
  • Cacheable: response nói rõ có thể cache hay không.
  • Layered system: client có thể đi qua proxy, gateway hoặc load balancer.

4. Phương thức HTTP và CRUD

Các phương thức GET POST PUT DELETE PATCH
Các phương thức HTTP phổ biến trong API.
Nghiệp vụ Phương thức Endpoint
Lấy danh sách GET /students
Lấy một bản ghi GET /students/:id
Tạo mới POST /students
Thay thế toàn bộ PUT /students/:id
Cập nhật một phần PATCH /students/:id
Xóa DELETE /students/:id

GET là phương thức an toàn: request đọc dữ liệu không nên thay đổi trạng thái server. PUT và DELETE có tính idempotent theo ngữ nghĩa HTTP: gửi cùng yêu cầu nhiều lần có hiệu ứng dự kiến tương đương một lần. POST thường không idempotent.

5. Mã trạng thái HTTP cần dùng đúng

  • 200 OK: đọc hoặc cập nhật thành công và có response body.
  • 201 Created: tạo tài nguyên thành công.
  • 204 No Content: thành công nhưng không trả body, thường dùng khi xóa.
  • 400 Bad Request: request sai cú pháp hoặc dữ liệu đầu vào không hợp lệ.
  • 404 Not Found: không tìm thấy tài nguyên.
  • 409 Conflict: dữ liệu xung đột với trạng thái hiện tại.
  • 500 Internal Server Error: lỗi không mong đợi phía server.

Không nên luôn trả 200 rồi đặt lỗi trong JSON. Client, proxy và công cụ giám sát dựa vào status code để hiểu kết quả request.

6. Khởi tạo dự án Express

mkdir student-api
cd student-api
npm init -y
npm install express

Tạo tệp app.js:

const express = require('express');

const app = express();
const PORT = 3000;

app.use(express.json());

let nextId = 4;
const students = [
  { id: 1, name: 'David Miller', age: 12, grade: 'A' },
  { id: 2, name: 'Adam Smith', age: 13, grade: 'B' },
  { id: 3, name: 'John Williams', age: 12, grade: 'A' }
];

express.json() phân tích request có JSON body và gán kết quả vào req.body. Dữ liệu trong mảng chỉ phục vụ học tập; khi khởi động lại server, mọi thay đổi sẽ mất.

7. Route GET

app.get('/students', (req, res) => {
  res.json({ data: students });
});

app.get('/students/:id', (req, res) => {
  const id = Number(req.params.id);
  const student = students.find(item => item.id === id);

  if (!student) {
    return res.status(404).json({ error: 'Không tìm thấy sinh viên' });
  }

  res.json({ data: student });
});

req.params.id luôn bắt đầu dưới dạng chuỗi, nên cần chuyển sang số trước khi so sánh với ID dạng số.

8. Kiểm tra dữ liệu đầu vào

function validateStudent(body, { partial = false } = {}) {
  const errors = [];

  if (!partial || body.name !== undefined) {
    if (typeof body.name !== 'string' || body.name.trim().length < 2) {
      errors.push('name phải là chuỗi có ít nhất 2 ký tự');
    }
  }

  if (!partial || body.age !== undefined) {
    if (!Number.isInteger(body.age) || body.age < 6 || body.age > 100) {
      errors.push('age phải là số nguyên từ 6 đến 100');
    }
  }

  if (!partial || body.grade !== undefined) {
    if (typeof body.grade !== 'string' || !body.grade.trim()) {
      errors.push('grade là trường bắt buộc');
    }
  }

  return errors;
}

9. Route POST tạo tài nguyên

app.post('/students', (req, res) => {
  const errors = validateStudent(req.body);
  if (errors.length) {
    return res.status(400).json({ errors });
  }

  const student = {
    id: nextId++,
    name: req.body.name.trim(),
    age: req.body.age,
    grade: req.body.grade.trim()
  };

  students.push(student);
  res.status(201)
    .location(`/students/${student.id}`)
    .json({ data: student });
});

Response 201 Created kèm header Location giúp client biết URI của tài nguyên mới.

10. Route PATCH và DELETE

app.patch('/students/:id', (req, res) => {
  const student = students.find(item => item.id === Number(req.params.id));
  if (!student) {
    return res.status(404).json({ error: 'Không tìm thấy sinh viên' });
  }

  const errors = validateStudent(req.body, { partial: true });
  if (errors.length) {
    return res.status(400).json({ errors });
  }

  if (req.body.name !== undefined) student.name = req.body.name.trim();
  if (req.body.age !== undefined) student.age = req.body.age;
  if (req.body.grade !== undefined) student.grade = req.body.grade.trim();

  res.json({ data: student });
});

app.delete('/students/:id', (req, res) => {
  const index = students.findIndex(item => item.id === Number(req.params.id));
  if (index === -1) {
    return res.status(404).json({ error: 'Không tìm thấy sinh viên' });
  }

  students.splice(index, 1);
  res.status(204).end();
});
Các thao tác CRUD của REST API sinh viên
API hỗ trợ lấy danh sách, lấy theo ID, tạo, cập nhật và xóa sinh viên.

11. Xử lý route không tồn tại và lỗi server

app.use((req, res) => {
  res.status(404).json({ error: 'Endpoint không tồn tại' });
});

app.use((error, req, res, next) => {
  console.error(error);
  res.status(500).json({ error: 'Lỗi máy chủ' });
});

app.listen(PORT, () => {
  console.log(`API chạy tại http://localhost:${PORT}`);
});

Hai middleware này phải đặt sau các route hợp lệ. Trong môi trường production, không trả stack trace hoặc thông tin nội bộ cho client.

12. Kiểm thử bằng curl

curl http://localhost:3000/students

curl http://localhost:3000/students/1

curl -X POST http://localhost:3000/students \
  -H "Content-Type: application/json" \
  -d '{"name":"Michael Faraday","age":11,"grade":"A"}'

curl -X PATCH http://localhost:3000/students/1 \
  -H "Content-Type: application/json" \
  -d '{"grade":"A+"}'

curl -i -X DELETE http://localhost:3000/students/2
Thông báo lỗi khi REST API nhận dữ liệu không hợp lệ
API từ chối tuổi không hợp lệ và trường bắt buộc bị thiếu.

13. JSON Schema và validation

Khi cấu trúc request lớn hơn, có thể mô tả dữ liệu bằng JSON Schema và dùng thư viện như Ajv để kiểm tra. Schema nên khai báo phiên bản cụ thể, kiểu dữ liệu, thuộc tính bắt buộc và giới hạn. Validation không thay thế việc kiểm tra quyền truy cập hay quy tắc nghiệp vụ.

14. Thực hành tốt khi xây dựng API

  • Dùng danh từ số nhiều cho collection: /students, không dùng động từ như /getStudents.
  • Trả status code và JSON lỗi nhất quán.
  • Giới hạn kích thước body, kiểm tra dữ liệu và không tin input từ client.
  • Dùng HTTPS, xác thực và phân quyền cho dữ liệu nhạy cảm.
  • Thêm phân trang cho danh sách lớn và versioning khi có thay đổi phá vỡ tương thích.
  • Đưa logic nghiệp vụ, truy cập dữ liệu và route sang các lớp riêng khi dự án lớn hơn.

Tổng kết

HTTP cung cấp phương thức, URI, header và status code; REST dùng các thành phần đó theo một kiểu kiến trúc hướng tài nguyên. Với Express, chúng ta đã xây dựng đủ route CRUD, kiểm tra dữ liệu, xử lý 404/500 và thử API bằng curl. Bước tiếp theo là thay mảng trong bộ nhớ bằng MongoDB để dữ liệu được lưu bền vững.

Bài tập

Bài 2: Website bán hàng Node.js + MongoDB

Yêu cầu chung — 20 điểm

Xây dựng website bán hàng sử dụng:
Node.js
Express.js
MongoDB
Express API + React

Phần 1: Thiết kế cơ sở dữ liệu — 4 điểm

Tạo các collection sau:
products
users
orders
Collection products cần có tối thiểu các trường:
name: String
price: Number
image: String
description: String
stock: Number
Collection users cần có tối thiểu:
username: String
password_hash: String
phone: String
role: String
Collection orders cần lưu:
user_id
items
total
created_at
Yêu cầu dữ liệu mẫu:
Tạo ít nhất 10 sản phẩm mẫu
Tạo ít nhất 1 tài khoản admin

Phần 2: Trang chủ hiển thị sản phẩm — 4 điểm

Xây dựng trang chủ có giao diện bán hàng. Yêu cầu:
  1. Hiển thị danh sách sản phẩm từ MongoDB.
  2. Mỗi sản phẩm cần hiển thị:
Ảnh sản phẩm
Tên sản phẩm
Giá
Mô tả ngắn
Nút thêm vào giỏ hàng
  1. Giao diện bố cục rõ ràng, dễ sử dụng.
  2. Có menu điều hướng:
Trang chủ
Giỏ hàng
Đăng nhập / Đăng xuất
Admin nếu là tài khoản quản trị

Phần 3: Trang quản trị sản phẩm — 5 điểm

Xây dựng trang admin quản lý sản phẩm. Chỉ user có role:
admin
mới được truy cập. Yêu cầu chức năng:
Thêm sản phẩm
Sửa sản phẩm
Xóa sản phẩm
Xem danh sách sản phẩm
Khi thêm/sửa sản phẩm cần nhập:
Tên sản phẩm
Giá
Ảnh
Mô tả
Số lượng tồn kho

Phần 4: Giỏ hàng — 4 điểm

Xây dựng chức năng giỏ hàng. Yêu cầu:
  1. Người dùng có thể thêm sản phẩm vào giỏ hàng.
  2. Giỏ hàng lưu trong session.
  3. Trang giỏ hàng hiển thị:
Tên sản phẩm
Giá
Số lượng
Tạm tính
Tổng tiền
  1. Có chức năng:
Xóa sản phẩm khỏi giỏ hàng
Cập nhật số lượng sản phẩm

Phần 5: Mua hàng / đặt hàng — 3 điểm

Xây dựng chức năng đặt hàng. Yêu cầu:
  1. Người dùng phải đăng nhập mới được đặt hàng.
  2. Khi đặt hàng, dữ liệu đơn hàng được lưu vào collection orders.
  3. Sau khi đặt hàng thành công:
Xóa giỏ hàng
Hiển thị thông báo đặt hàng thành công
 

Bài viết liên quan:

Node.js Essentials: kiến trúc, Event Loop, REPL, npm và Global Objects
Node.js là gì? Kiến trúc client-server và cách cài đặt Node.js
Tìm Hiểu Express.js và Lập Trình Đồng Bộ – Bất Đồng Bộ Trong Node.js
Tìm hiểu Modules, Packages và Built-in Modules trong Node.js
Giới thiệu tổng quan về ứng dụng Server Side
Cài đặt NodeJS trên môi trường windows

THÊM BÌNH LUẬN Cancel reply

Dịch vụ thiết kế Wesbite

NỘI DUNG MỚI CẬP NHẬT

Node.js Essentials: kiến trúc, Event Loop, REPL, npm và Global Objects

Xây dựng RESTful API với Express và HTTP trong nodejs

Node.js là gì? Kiến trúc client-server và cách cài đặt Node.js

Ứng dụng AI với MongoDB: truy vấn tự nhiên, Colab và RAG

Kết nối MongoDB với Python bằng PyMongo và thực hiện CRUD

Giới thiệu

hocvietcode.com là website chia sẻ và cập nhật tin tức công nghệ, chia sẻ kiến thức, kỹ năng. Chúng tôi rất cảm ơn và mong muốn nhận được nhiều phản hồi để có thể phục vụ quý bạn đọc tốt hơn !

Liên hệ quảng cáo: [email protected]

Kết nối với HỌC VIẾT CODE

© hocvietcode.com - Tech888 Co .Ltd since 2019

Đăng nhập

Trở thành một phần của cộng đồng của chúng tôi!
Registration complete. Please check your email.
Đăng nhập bằng google
Đăng kýBạn quên mật khẩu?

Create an account

Welcome! Register for an account
The user name or email address is not correct.
Registration confirmation will be emailed to you.
Log in Lost your password?

Reset password

Recover your password
Password reset email has been sent.
The email could not be sent. Possible reason: your host may have disabled the mail function.
A password will be e-mailed to you.
Log in Register
×