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

10 phút đọc

Khi thiết kế REST API, kích thước phản hồi và giới hạn ký tự của trường thường bị bỏ qua. Tuy nhiên, thiết kế độ dài hợp lý ảnh hưởng trực tiếp đến hiệu suất, trải nghiệm người dùng và tính nhất quán dữ liệu. Bài viết này đi sâu vào mối quan hệ giữa kích thước payload và độ trễ, đặc điểm truyền tải qua các phiên bản giao thức HTTP, so sánh phương pháp nén và hướng dẫn thực tiễn cho thiết kế phản hồi API. Để tìm hiểu kiến thức nền tảng, hãy tham khảo sách về thiết kế REST API.

Độ 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ựKhớp với giới hạn triển khai trình duyệt
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. Trên kết nối 4G điển hình (tốc độ hiệu dụng 10–30 Mbps), phản hồi 10KB truyền trong khoảng 3–8ms, nhưng 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 4G (ước tính)Số TCP RTTTrường hợp sử dụng
Dưới 14KB3–5ms1 RTTLấy tài nguyên đơn, kiểm tra trạng thái
14–50KB5–15ms2–3 RTTsXem chi tiết, dữ liệu hồ sơ
50–200KB15–60ms4–6 RTTsEndpoint danh sách (có phân trang)
200KB–1MB60–300ms7+ RTTsLấy hàng loạt, dữ liệu báo cáo

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.

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 tạo đầu ra nhỏ hơn 10–20% so với gzip, nhưng chỉ khả dụng qua kết nố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: fields=id,name,address(city,zip).

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.

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
AWS Lambda Response6MB (đồng bộ)Gọi bất đồng bộ giới hạn 256KB
Azure API Management2MB (mặc định)Có thể mở rộng đến 4GB qua policy
Google Cloud API Gateway32MBGiới hạn timeout backend cũng áp dụng

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. Đố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-ages-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 minLengthmaxLength 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. Để tìm hiểu toàn diện, hãy tham khảo sách hướng dẫn kiến trúc ứng dụng web.

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.