Cập nhật lần cuối:

Hướng dẫn thiết kế độ dài phản hồi API

13 phút đọc

Độ dài trường khuyến nghị

TrườngTối đa khuyến nghịCân nhắc thiết kế
Tên người dùng50 ký tựCân nhắc chiều rộng hiển thị UI và ràng buộc duy nhất
Địa chỉ email254 ký tựTheo đặc tả RFC 5321
Tên hiển thị100 ký tựCho phép không gian cho tên đa ngôn ngữ
Mô tả ngắn200 ký tựThiết kế cho chế độ xem danh sách
Mô tả đầy đủ2.000–5.000 ký tựTính cả thẻ HTML trong rich text
Thông báo lỗi200 ký tựNgắn gọn và cụ thể cho người dùng cuối
URL2.048 ký tựGiá trị quy ước được dùng rộng rãi trong thực tế. Giới hạn thực tế của trình duyệt và máy chủ khác nhau tùy sản phẩm
Thẻ/Nhãn50 ký tựCân bằng khả năng tìm kiếm và đọc

Các giá trị khuyến nghị này phải được đặt với sự hiểu biết về sự khác biệt giữa số ký tự và số byte. Ví dụ, giới hạn "50 ký tự" tương đương 50 byte cho nội dung chỉ ASCII, nhưng có thể mở rộng lên đến 200 byte cho văn bản tiếng Nhật trong UTF-8. Việc API xác thực theo số ký tự hay số byte nên được quyết định phù hợp với định nghĩa cột cơ sở dữ liệu của bạn.

Mối quan hệ kích thước Payload và độ trễ

Kích thước phản hồi API ảnh hưởng trực tiếp đến độ trễ mạng. Giả định kết nối di động (tốc độ hiệu dụng khoảng 10–30 Mbps), phản hồi 10KB mất khoảng 3–8ms nếu chỉ tính riêng thời gian truyền theo băng thông, còn phản hồi 500KB mất 130–400ms. Đối với API hướng di động, giữ phản hồi dưới 50KB mỗi yêu cầu đảm bảo trải nghiệm mượt mà.

Tác động của kích thước payload lên độ trễ không phải tuyến tính. Do TCP slow start, cửa sổ tắc nghẽn nhỏ trên kết nối ban đầu, nên ~14KB đầu tiên có thể truyền trong một RTT duy nhất (Round Trip Time). Vượt quá ngưỡng đó, cần thêm các RTT khi cửa sổ mở rộng. Nói cách khác, giữ phản hồi dưới 14KB tránh các round trip bổ sung ở cấp TCP, cải thiện đáng kể tốc độ cảm nhận.

Kích thước PayloadThời gian truyền ước tính (hiệu dụng 10–30 Mbps)Số RTT cần thiết (xấp xỉ)Trường hợp sử dụng
Dưới 14KB4–11ms1 RTTLấy tài nguyên đơn, kiểm tra trạng thái
14–50KB11–40ms2–3 RTTsXem chi tiết, dữ liệu hồ sơ
50–200KB40–160ms3–4 RTTsEndpoint danh sách (có phân trang)
200KB–1MB160–800ms4–7 RTTsLấy hàng loạt, dữ liệu báo cáo

Cột thời gian truyền chỉ là kích thước payload chia cho băng thông và không bao gồm bản thân độ trễ round trip. Số RTT là giá trị xấp xỉ với giả định cửa sổ tắc nghẽn tăng gấp đôi sau mỗi round trip (lũy tiến 14KB, 43KB, 100KB, 214KB, 442KB). Cái bẫy thực tế ở đây là một RTT trên kết nối di động có thể lên tới hàng chục ms, khiến số round trip trở thành số hạng chi phối. Giảm phản hồi 200KB xuống 150KB gần như không cải thiện tốc độ cảm nhận nếu số RTT không đổi, trong khi đưa phản hồi 20KB xuống dưới 14KB loại bỏ trọn một round trip. Khi cắt payload, hãy cắt với con mắt hướng vào việc có vượt qua ranh giới round trip hay không.

So sánh nén: gzip vs Brotli

Phản hồi JSON là dữ liệu văn bản có khả năng nén cao với các mẫu lặp lại. Dưới đây là so sánh hai phương pháp nén chính, gzip và Brotli. Lưu ý rằng tỷ lệ nén phụ thuộc nhiều vào mức độ lặp lại của dữ liệu gốc, nên hãy xem các số liệu dưới đây là xu hướng điển hình với phản hồi JSON chứ không phải giá trị cố định.

Phương phápTỷ lệ nén (JSON)Tốc độ nénTốc độ giải nénHỗ trợ trình duyệt
gzip60–75%NhanhNhanhGần như tất cả trình duyệt
Brotli (quality 4)65–80%Tương đương gzipNhanhTrình duyệt chính (chỉ HTTPS)
Brotli (quality 11)75–85%Chậm (phù hợp phân phối tĩnh)NhanhTrình duyệt chính (chỉ HTTPS)

Đối với phản hồi JSON 100KB điển hình, gzip nén xuống khoảng 25–40KB, trong khi Brotli (quality 4) đạt 20–35KB. Brotli có xu hướng cho kết quả nhỏ hơn gzip một bậc, nhưng các trình duyệt chính chỉ khai báo br trong Accept-Encoding khi kết nối qua HTTPS, nên trên thực tế đây là phương pháp chỉ dùng được với HTTPS. Đối với phản hồi API động, Brotli quality 4 cung cấp sự cân bằng tốt nhất giữa tốc độ nén và tỷ lệ nén. Quality 11 quá chậm cho nén thời gian thực nhưng hoạt động tốt cho phản hồi tĩnh được cache tại tầng CDN.

Một anti-pattern phổ biến là rút ngắn tên key JSON (ví dụ: "username" thành "u") để giảm kích thước. Điều này ảnh hưởng nghiêm trọng đến khả năng debug. Thuật toán nén xử lý các mẫu lặp lại hiệu quả, nên việc giảm kích thước từ key ngắn hơn là không đáng kể. Sự đánh đổi về khả năng đọc không đáng.

Xử lý Payload trong HTTP/2 và HTTP/3

Phiên bản giao thức HTTP ảnh hưởng đáng kể đến cách payload phản hồi được truyền tải.

Trong HTTP/1.1, máy chủ khai báo tổng số byte qua header Content-Length, hoặc sử dụng Transfer-Encoding: chunked để gửi dữ liệu theo phân đoạn. Mã hóa truyền tải chunked được sử dụng khi tổng kích thước phản hồi không biết trước (ví dụ: streaming từ cơ sở dữ liệu). Mỗi chunk được gửi dưới dạng kích thước (thập lục phân) + CRLF + dữ liệu + CRLF, với chunk có độ dài bằng không đánh dấu kết thúc.

HTTP/2 giới thiệu binary framing, nơi payload được truyền trong DATA frame. Header Content-Length trở thành tùy chọn, và cờ END_STREAM báo hiệu hoàn thành stream. Nén header (HPACK) giảm đáng kể overhead cho các header gửi lặp lại (Content-Type, Cache-Control, v.v.). Vì nhiều yêu cầu có thể được ghép kênh qua một kết nối duy nhất, HTTP/2 phù hợp tốt với thiết kế API trả về nhiều phản hồi nhỏ.

HTTP/3 (QUIC) sử dụng truyền tải dựa trên UDP, loại bỏ head-of-line blocking của TCP. Khi mất gói tin trên một stream, các stream khác tiếp tục không bị ảnh hưởng. Trong mạng di động không ổn định, việc chia payload lớn qua nhiều stream song song có thể là chiến lược thiết kế hiệu quả.

Thiết kế thông báo lỗi

API thiết kế thông báo lỗi là quyết định quan trọng ảnh hưởng đến cả trải nghiệm lập trình viên và trải nghiệm người dùng. Sử dụng trường hướng lập trình viên detail (tối đa 500 ký tự với thông tin kỹ thuật) và trường hướng người dùng message (dưới 100 ký tự bằng ngôn ngữ dễ hiểu).

Đối với lỗi xác thực, trả về thông báo theo từng trường dưới 80 ký tự mỗi thông báo để tránh vấn đề bố cục UI. Kết hợp mã lỗi với thông báo giúp client dễ dàng thay thế bằng văn bản đã bản địa hóa. Áp dụng cấu trúc RFC 9457 (Problem Details for HTTP APIs) chuẩn hóa định dạng phản hồi lỗi, giúp triển khai xử lý lỗi chung trong thư viện client dễ dàng hơn.

Thực tiễn tốt nhất thiết kế phân trang

Phân trang là cơ chế hiệu quả nhất để kiểm soát kích thước phản hồi endpoint danh sách. Mỗi cách tiếp cận chính có đặc điểm riêng biệt.

Cách tiếp cậnCơ chếƯu điểmNhược điểm
Dựa trên offset?offset=20&limit=10Đơn giản triển khai, hỗ trợ truy cập trang ngẫu nhiênLệch khi thêm/xóa dữ liệu, hiệu suất giảm với offset lớn
Dựa trên cursor?cursor=abc123&limit=10Bền vững với thay đổi dữ liệu, hiệu suất ổn định ở quy mô lớnKhông truy cập trang ngẫu nhiên, tổng số cần truy vấn riêng
Dựa trên keyset?after_id=100&limit=10Truy vấn nhanh tận dụng indexTiêu chí sắp xếp bị ràng buộc

Phân trang dựa trên offset buộc cơ sở dữ liệu quét tất cả các hàng đến offset (ví dụ: OFFSET 10000), khiến hiệu suất giảm tỷ lệ thuận với khối lượng dữ liệu. Đối với API xử lý hàng chục nghìn bản ghi trở lên, nên áp dụng phân trang dựa trên cursor hoặc keyset. Kích thước trang 20–50 mục là phổ biến, nhưng hãy điều chỉnh dựa trên kích thước từng bản ghi để giữ tổng payload phản hồi dưới 50KB.

Mẫu lọc trường phản hồi

Cho phép client yêu cầu chỉ các trường cần thiết giúp giảm trực tiếp kích thước phản hồi. Dưới đây là các mẫu được sử dụng rộng rãi trong REST API.

Cách tiếp cận tham số fields, được Google APIs và Facebook Graph API áp dụng, cho phép client chỉ định tên trường dưới dạng danh sách phân cách bằng dấu phẩy: GET /users/123?fields=id,name,email. Các trường lồng nhau có thể biểu diễn bằng dấu ngoặc đơn, như fields=id,name,address(city,zip), nhưng việc một dịch vụ dùng dấu ngoặc đơn hay dấu ngoặc nhọn lại khác nhau tùy dịch vụ, nên hãy ghi rõ ký pháp này trong đặc tả API của chính bạn. Nếu bạn cho phép lồng nhau, hãy quyết định luôn cả độ sâu tối đa. Không có giới hạn đó, client có thể làm số truy vấn ở backend tăng lên gấp nhiều lần chỉ bằng cách yêu cầu mở rộng sâu.

Khi triển khai mẫu này, cân nhắc bảo mật là thiết yếu. Nếu client chỉ định các trường nhạy cảm như password_hash hoặc internal_id trong tham số fields, API không được trả về chúng. Sử dụng cách tiếp cận whitelist cho việc lọc. Cách tiếp cận blacklist (loại trừ các trường cụ thể) tạo rủi ro rò rỉ mỗi khi thêm trường nhạy cảm mới.

Thực tiễn tốt nhất thiết kế Payload

Giữ lồng phản hồi JSON ở ba cấp hoặc ít hơn để đơn giản hóa xử lý phía client. Khi lồng sâu hơn không thể tránh, hãy cân nhắc tách tài nguyên liên quan thành các endpoint riêng biệt liên kết bằng tham chiếu ID.

Định dạng ngày và số cũng ảnh hưởng đến số ký tự. Chuẩn hóa ngày theo định dạng ISO 8601 (ví dụ: 2025-07-15T09:00:00Z), chiếm khoảng 20 ký tự. Trả về giá trị tiền tệ dưới dạng kiểu số và để client xử lý định dạng theo locale - đây là cách tiếp cận chuẩn cho quốc tế hóa.

Khi sử dụng mẫu envelope ({"data": ..., "meta": ...}), đối tượng meta thường bao gồm thông tin phân trang, số lượt gọi API còn lại và ID yêu cầu. Kích thước của metadata này cũng nên được tính vào thiết kế - thông thường 200–500 byte là hợp lý.

Giới hạn Payload API Gateway

API gateway đám mây áp dụng giới hạn kích thước phản hồi nghiêm ngặt. Vượt quá các giới hạn này gây ra lỗi yêu cầu, nên chúng phải được tính vào thiết kế API. Các số liệu dưới đây là giá trị được từng nhà cung cấp ghi trong tài liệu tại thời điểm tháng 8 năm 2026. Các giới hạn này vẫn được điều chỉnh theo thời gian, nên hãy đối chiếu với tài liệu hiện hành khi thiết kế.

Dịch vụGiới hạn PayloadGhi chú
AWS API Gateway (REST)10MBBao gồm binary. Tích hợp Lambda bị giới hạn bởi giới hạn 6MB của Lambda trước
AWS API Gateway (HTTP)10MBGiống REST API
Payload lời gọi AWS Lambda6MB (đồng bộ, riêng cho yêu cầu và cho phản hồi)Lời gọi bất đồng bộ giới hạn 1MB. Các đường gọi hỗ trợ phản hồi dạng streaming cho phép đến 200MB
Azure API Management2MiB (bậc V2 và bậc tiêu thụ, khi có buffer)Giới hạn buffer của các bậc classic là 500MiB. Giới hạn kích thước của bản thân yêu cầu là 1GiB hoặc không giới hạn, tùy theo bậc
Google Cloud API Gateway32MB32MB áp dụng cho cả yêu cầu và phản hồi. Không hỗ trợ streaming

Điều kiện kèm theo giới hạn của Azure rất đáng lưu ý: nó chỉ áp dụng khi gateway có buffer. Ngay khi bạn chèn xử lý kiểm tra hay viết lại phần thân, gateway buộc phải đọc toàn bộ phản hồi vào bộ nhớ, và một kích thước vốn đi qua suôn sẻ khi được cho đi thẳng lại bắt đầu chạm giới hạn. Với các API mang payload lớn, thiết kế an toàn hơn là bỏ các policy có chạm vào phần thân ra khỏi gateway.

Trong kiến trúc AWS Lambda + API Gateway, giới hạn 6MB cho lời gọi đồng bộ của Lambda là nút thắt cổ chai. Tệ hơn, phần vượt quá chỉ bị phát hiện tại thời điểm hàm trả về phản hồi, nên lỗi chỉ đến sau khi bạn đã trả đủ toàn bộ thời gian thực thi và chi phí. Đối với phản hồi lớn, trả về URL pre-signed S3 và để client tải trực tiếp. Điều này bỏ qua giới hạn payload của API Gateway trong khi tận dụng throughput cao của S3.

CDN Caching và kích thước phản hồi

Khi đặt CDN (CloudFront, Fastly, v.v.) trước API, kích thước phản hồi ảnh hưởng trực tiếp đến hiệu quả cache.

Để tối đa tỷ lệ cache hit, chuẩn hóa phản hồi là chìa khóa. Nếu có nhiều tổ hợp tham số fields khác nhau cho cùng một tài nguyên, cache key bị phân mảnh và tỷ lệ hit giảm. Định nghĩa các tổ hợp trường thường truy cập dưới dạng "view" (?view=summary, ?view=detail) giới hạn số biến thể cache key và là thiết kế hiệu quả hơn.

Lưu trữ cache CDN cũng phát sinh chi phí, nên việc cache phản hồi lớn không cần thiết làm tăng chi phí. Đặt header Cache-Control với giá trị max-age và s-maxage phù hợp - TTL ngắn cho dữ liệu thay đổi thường xuyên, TTL dài hơn cho dữ liệu master tĩnh.

Mẫu triển khai giới hạn ký tự

Xác định rõ ràng ràng buộc minLength và maxLength cho mỗi trường trong xác thực yêu cầu. Ghi lại các ràng buộc này trong đặc tả OpenAPI (Swagger) đảm bảo tính nhất quán giữa tài liệu và xác thực runtime.

Theo nguyên tắc, giới hạn trường API nên phù hợp với ràng buộc cơ sở dữ liệu. Xem bài viết thực tiễn tốt nhất thiết kế độ dài VARCHAR để biết chi tiết. Cho phép 1.000 ký tự ở cấp API cho cột VARCHAR(255) sẽ gây lỗi khi lưu. Quản lý định nghĩa schema như một nguồn sự thật duy nhất để ngăn sự lệch giữa đặc tả API và định nghĩa cơ sở dữ liệu.

Một chi tiết triển khai quan trọng: phương pháp đếm ký tự có thể khác nhau giữa frontend và backend. String.length của JavaScript trả về số đơn vị mã UTF-16, nên emoji (cặp surrogate) được đếm là 2. Trong khi đó, len() của Python và utf8.RuneCountInString() của Go trả về số code point Unicode. Hãy định nghĩa rõ ràng "số ký tự" có nghĩa gì trong đặc tả API và đảm bảo đếm nhất quán giữa client và server.

Lỗi phản hồi API phổ biến

Kỹ thuật chuyên nghiệp cho thiết kế API

Kết luận

Thiết kế độ dài phản hồi API là quyết định quan trọng ảnh hưởng đến cả hiệu suất và chất lượng dữ liệu. Từ cửa sổ ban đầu 14KB của TCP slow start, đến đặc điểm nén gzip và Brotli, ghép kênh HTTP/2 và giới hạn payload API Gateway - thiết kế đòi hỏi cân nhắc từ tầng truyền tải đến tầng ứng dụng. Xác định giới hạn rõ ràng cho từng trường, kiểm soát kích thước phản hồi bằng phân trang và lọc trường, và sử dụng Bộ đếm ký tự để xác minh độ dài trường trong quá trình thiết kế API.

Chia sẻ bài viết này