Still Soft
Trang chủ › Công Nghệ Mới

Cách xây dựng hệ thống API RESTful chuẩn cho ứng dụng mobile

Ban biên tập Still Soft · · Cập nhật
Cách xây dựng hệ thống API RESTful chuẩn cho ứng dụng mobile

Một API RESTful chuẩn cho ứng dụng mobile là API tổ chức dữ liệu thành các tài nguyên có URL rõ ràng, dùng đúng phương thức và mã trạng thái HTTP, trả về dữ liệu nhất quán, có phiên bản để ứng dụng cũ không bị hỏng khi backend thay đổi, và được thiết kế cho đặc thù di động: mạng chập chờn, pin và dữ liệu giới hạn, người dùng không cập nhật ứng dụng ngay. Bài viết tổng hợp các nguyên tắc thiết kế, bảo mật và vận hành mà đội backend nên thống nhất trước khi viết endpoint đầu tiên.

Nguyên tắc REST cốt lõi

REST (Representational State Transfer) là phong cách kiến trúc do Roy Fielding mô tả trong luận án năm 2000. Trong thực tế, một API "RESTful" thường tuân theo:

  • Tài nguyên là danh từ: /orders, /orders/123, /users/45/addresses. Không dùng động từ kiểu /getOrders.
  • Phương thức HTTP thể hiện hành động: GET đọc, POST tạo, PUT thay thế toàn bộ, PATCH sửa một phần, DELETE xóa.
  • Phi trạng thái: mỗi request mang đủ thông tin (token xác thực), máy chủ không dựa vào phiên lưu trong bộ nhớ.
  • Biểu diễn thống nhất: JSON với quy ước đặt tên nhất quán (camelCase hoặc snake_case, chọn một).

Mã trạng thái HTTP dùng đúng

MãÝ nghĩaKhi nào dùng
200 OKThành côngGET, PATCH, PUT trả về dữ liệu
201 CreatedĐã tạoPOST tạo tài nguyên mới
204 No ContentThành công, không có nội dungDELETE
400 Bad RequestDữ liệu gửi lên saiThiếu trường, sai định dạng
401 UnauthorizedChưa xác thựcThiếu hoặc hết hạn token
403 ForbiddenKhông có quyềnĐã đăng nhập nhưng không được phép
404 Not FoundKhông tồn tạiTài nguyên không có (hoặc không muốn lộ là có)
409 ConflictXung độtTrùng dữ liệu, xung đột phiên bản
422 Unprocessable ContentHợp lệ cú pháp nhưng sai nghiệp vụSố lượng vượt tồn kho
429 Too Many RequestsVượt giới hạn tần suấtKèm header Retry-After
500, 503Lỗi máy chủ, tạm không khả dụngKhông lộ chi tiết nội bộ

Định dạng lỗi nên thống nhất, ví dụ theo chuẩn Problem Details (RFC 9457): mã lỗi máy đọc được, thông điệp cho người, chi tiết từng trường sai. Ứng dụng mobile dựa vào mã lỗi để hiển thị thông báo phù hợp, không phải phân tích chuỗi văn bản.

Thiết kế cho đặc thù mobile

Giảm số lần gọi và dung lượng

  • Cho phép chọn trường (fields) hoặc nhúng tài nguyên liên quan (include) để một màn hình không cần năm request.
  • Bật nén gzip hoặc Brotli.
  • Cân nhắc lớp BFF (Backend for Frontend) gom dữ liệu theo màn hình cho app.
  • Ảnh trả về nhiều kích thước để app chọn theo màn hình.

Phân trang

Danh sách dài phải phân trang. Với feed cuộn vô hạn, phân trang theo con trỏ (cursor) ổn định hơn offset: không bị trùng hoặc sót khi có bản ghi mới chèn vào. Trả về con trỏ trang tiếp theo trong phản hồi.

Mạng chập chờn và retry an toàn

Request trên mạng di động có thể bị cắt giữa chừng; app sẽ thử lại. Với thao tác tạo (đặt hàng, thanh toán), dùng idempotency key: app gửi một khóa duy nhất trong header, máy chủ nhận cùng khóa lần hai thì trả lại kết quả cũ thay vì tạo bản ghi mới.

Cache và đồng bộ

Dùng ETag và Cache-Control để app không tải lại dữ liệu không đổi. Với app cần làm việc ngoại tuyến, thiết kế endpoint đồng bộ thay đổi từ một mốc thời gian và chiến lược xử lý xung đột.

Phiên bản API

Khác web, người dùng mobile có thể dùng bản app cũ hàng tháng. Vì vậy:

  • Đặt phiên bản ngay từ đầu, phổ biến nhất là trong URL (/v1/...).
  • Thay đổi tương thích ngược (thêm trường mới, thêm endpoint) không cần tăng phiên bản; app phải bỏ qua trường lạ.
  • Thay đổi phá vỡ (đổi tên, xóa trường, đổi kiểu) chỉ ra ở phiên bản mới, giữ bản cũ trong thời gian chuyển đổi.
  • Có cơ chế yêu cầu cập nhật app bắt buộc khi phiên bản quá cũ không còn được hỗ trợ.

Xác thực và bảo mật

  • Chuẩn OAuth 2.0 / OpenID Connect với luồng Authorization Code và PKCE cho app mobile; không nhúng khóa bí mật vào app vì có thể bị dịch ngược.
  • Access token ngắn hạn, refresh token lưu trong vùng an toàn của hệ điều hành (Keychain trên iOS, Keystore trên Android).
  • Kiểm tra quyền trên từng tài nguyên ở máy chủ: người dùng chỉ đọc được đơn hàng của mình. Đây là lỗi hàng đầu trong OWASP API Security Top 10.
  • Giới hạn tần suất theo người dùng và theo IP; trả 429.
  • HTTPS bắt buộc, kiểm tra đầu vào nghiêm ngặt, không trả thông tin thừa.

Các rủi ro bảo mật web khác được trình bày trong bài bảo mật ứng dụng web theo OWASP Top 10.

Tài liệu và hợp đồng API

Mô tả API bằng OpenAPI Specification giúp đội mobile và backend thống nhất hợp đồng trước khi code, sinh tài liệu tương tác, sinh code client và kiểm tra tự động request/response. Cách tiếp cận "thiết kế trước" (design-first) giảm nhiều vòng sửa đổi qua lại.

Kiểm thử và vận hành

  • Kiểm thử thủ công và tự động từng endpoint với Postman hoặc công cụ tương tự; xem bài cách sử dụng Postman kiểm thử API.
  • Kiểm thử hợp đồng để đảm bảo backend không phá vỡ phiên bản đang dùng.
  • Giám sát độ trễ, tỷ lệ lỗi theo endpoint và theo phiên bản app.
  • Log có mã request để truy vết khi người dùng báo lỗi.
  • Deploy tự động qua pipeline; xem bài thiết lập CI/CD pipeline.

REST có phải lựa chọn duy nhất?

GraphQL cho phép client yêu cầu chính xác dữ liệu cần, hữu ích khi nhiều màn hình cần tổ hợp dữ liệu khác nhau; đổi lại cần kiểm soát truy vấn phức tạp và cache khó hơn. gRPC hiệu quả cho giao tiếp giữa các service nội bộ. Với phần lớn app mobile, REST được thiết kế tốt kèm vài endpoint tổng hợp vẫn là lựa chọn đơn giản và đủ dùng.

Câu hỏi thường gặp

Nên dùng PUT hay PATCH để cập nhật?

PUT thay thế toàn bộ tài nguyên, client phải gửi đủ trường. PATCH cập nhật một phần, phù hợp hơn với app mobile vì chỉ gửi trường thay đổi, tiết kiệm dữ liệu và tránh ghi đè trường không muốn đổi.

Có nên trả mã 200 kèm trường lỗi trong body cho mọi request không?

Không nên. Dùng đúng mã trạng thái HTTP giúp client, proxy, công cụ giám sát hiểu kết quả. Body chỉ bổ sung chi tiết lỗi theo định dạng thống nhất.

Lưu token trên app mobile ở đâu an toàn?

Dùng kho lưu trữ an toàn của hệ điều hành: Keychain trên iOS và Android Keystore (hoặc EncryptedSharedPreferences). Không lưu token trong bộ nhớ thường hoặc file văn bản.

API cho app mobile có cần CORS không?

Ứng dụng mobile gốc không bị chính sách CORS của trình duyệt áp dụng. CORS chỉ cần khi API được gọi từ trình duyệt, ví dụ phiên bản web của sản phẩm; khi đó chỉ cho phép đúng các nguồn cần thiết.

Bài liên quan

Cách bảo mật ứng dụng web theo OWASP Top 10
Công Nghệ Mới

Cách bảo mật ứng dụng web theo OWASP Top 10

Giải thích 10 nhóm rủi ro trong OWASP Top 10 và cách phòng thủ cụ thể cho lập trình viên web: phân quyền, mã hóa, chống injection, cấu hình an toàn, giám sát.