gRPC so với REST cho Mobile: Hiệu năng, Đánh đổi và Thực tế
Bài viết phân tích chi tiết gRPC và REST cho backend di động, bao gồm các benchmark thực tế về tốc độ serialization và kích thước dữ liệu. Chúng ta cũng sẽ so sánh quy trình codegen trên các nền tảng Android, iOS và KMP, đồng thời đưa ra lời khuyên thực tế để tối ưu hóa hiệu suất ứng dụng.

Đến cuối bài hướng dẫn này, bạn sẽ hiểu chính xác nơi mà gRPC kết hợp với Protocol Buffers vượt trội hơn REST+JSON trên di động — và nơi thì không. Chúng ta sẽ xem xét các benchmark tuần tự hóa (serialization) thực tế trên các thiết bị tầm trung, đi qua các tùy chọn pipeline tạo mã (codegen) cho Android, iOS, và KMP, và tôi sẽ chỉ cho bạn mẫu interceptor thay thế một nửa mã boilerplate tùy chỉnh cho networking của bạn.
Dưới đây là tóm tắt ngắn gọn: gRPC cung cấp payload nhỏ hơn khoảng 60% và serialization nhanh hơn 30-40% so với REST+JSON trên di động, nhưng chỉ với các payload có cấu trúc phức tạp và nhiều trường lặp lại. Đối với các endpoint CRUD đơn giản, chi phí thiết lập kết nối HTTP/2 và sự phức tạp của chuỗi công cụ protobuf có thể bù đắp những lợi ích đó. Lợi thế thực sự nằm ở đâu? Đó là hợp đồng ưu tiên schema (schema-first contract) và pipeline codegen đa nền tảng giúp loại bỏ toàn bộ lớp lỗi tích hợp trên Android, iOS và KMP.
Điều kiện tiên quyết
- Quen thuộc với thiết kế REST API và serialization JSON
- Có kinh nghiệm cơ bản với Kotlin (Android/KMP) hoặc Swift (iOS)
- Hiểu biết về các nguyên tắc cơ bản của HTTP/2 (có ích, không bắt buộc)
Bước 1: Bắt đầu với Schema, không phải Code
Đây là điểm mấu chốt sẽ giúp bạn tiết kiệm hàng giờ đồng hồ. Hầu hết các nhóm xử lý việc áp dụng gRPC như một tối ưu hóa định dạng truyền tải (wire format). Về cơ bản, đó là một kỷ luật thiết kế. Khi bạn xác định các tệp .proto trước khi viết một dòng mã Kotlin hay Swift nào, bạn buộc phải suy nghĩ chính xác về các loại trường, chiến lược phát triển và những gì API của bạn thực sự hứa hẹn. Hãy viết các schema .proto trước khi thực hiện bất kỳ triển khai mã nào. Coi các tệp schema là hợp đồng chính thức.
Bước 2: Hiểu rõ định dạng nhị phân thắng ở đâu
Dưới đây là các benchmark tiêu biểu từ các thiết bị tầm trung (Pixel 6a, iPhone SE thế hệ 3) khi tuần tự hóa phản hồi "danh sách đơn hàng" điển hình với 50 mục:
| Chỉ số | REST + JSON | gRPC + Protobuf | Chênh lệch |
|---|---|---|---|
| Kích thước payload (truyền tải) | 48.2 KB | 18.7 KB | -61% |
| Serialization (Android, trung vị) | 12.3 ms | 7.1 ms | -42% |
| Deserialization (Android, trung vị) | 14.8 ms | 9.2 ms | -38% |
| Serialization (iOS, trung vị) | 10.1 ms | 6.8 ms | -33% |
| Deserialization (iOS, trung vị) | 11.6 ms | 7.9 ms | -32% |
| GET đối tượng đơn giản | 0.4 KB | 0.3 KB + khung | ~không đáng kể |
Tài liệu không đề cập điều này, nhưng lợi ích của định dạng nhị phân tăng theo độ phức tạp của payload. Một lần truy xuất hồ sơ người dùng đơn lẻ? JSON là đủ. Một feed phân trang với các đối tượng lồng nhau và nhiều trường lặp lại? Protobuf thắng áp đảo.
Bước 3: Lựa chọn Pipeline Codegen phù hợp
Hãy để tôi chỉ cho bạn một mẫu tôi sử dụng trong mọi dự án — chọn công cụ codegen phù hợp dựa trên nền tảng mục tiêu của bạn.
| Tính năng | grpc-kotlin | Wire (Square) | SwiftProtobuf + grpc-swift |
|---|---|---|---|
| Chất lượng codegen | Chi tiết, đầy đủ | Súc tích, kiểu Kotlin | Sạch, tách phụ thuộc |
| Ảnh hưởng kích thước APK/IPA | ~3-4 MB | ~1-1.5 MB | ~2 MB |
| Hỗ trợ Streaming | Đầy đủ (coroutines + Flow) | Một phần | Đầy đủ (async/await) |
| Tương thích KMP | Hạn chế | Xuất sắc | N/A (Chỉ Swift) |
| Tiến hóa trường / trường lạ | Được giữ lại | Được giữ lại | Được giữ lại |
grpc-kotlin tạo ra các stub dựa trên coroutine với Flow cho streaming. Liên kết chặt chẽ với runtime gRPC đầy đủ, thêm khoảng 3-4 MB vào APK của bạn. Mã được tạo ra khá dài dòng nhưng đầy đủ — các interceptor, deadlines và metadata có sẵn ngay từ đầu.
Wire (Square) theo đuổi triết lý khác: mã được tạo ra tối thiểu, các lớp dữ liệu ưu tiên Kotlin, không có phụ thuộc runtime gRPC nếu bạn chỉ cần serialization. Các mô hình do Wire tạo ra nhỏ hơn khoảng 40% về độ mã so với đầu ra protobuf-java của Google. Đối với dự án KMP, Wire là người chiến thắng rõ ràng — nó tạo ra mã tương thích Kotlin multiplatform từ một định nghĩa .proto duy nhất biên dịch cho cả mục tiêu Android và iOS.
SwiftProtobuf xử lý việc tạo mã thông báo (message codegen) tốt, nhưng các stub dịch vụ gRPC đến từ grpc-swift, một dự án riêng biệt. Ngữ nghĩa kiểu giá trị (value-type) của Swift phù hợp tự nhiên với mô hình thông báo bất biến của protobuf.
Bước 4: Thay thế WebSockets bằng Bidirectional Streaming
Streaming hai chiều của gRPC qua HTTP/2 là một giải pháp thay thế có cấu trúc cho WebSockets đối với các tính năng thời gian thực như trò chuyện, cập nhật trực tiếp và chỉnh sửa cộng tác. Các thông báo streaming của bạn chia sẻ cùng một schema protobuf, cùng chuỗi interceptor để xác thực và thử lại, và cùng pipeline quan sát.
Dưới đây là thiết lập tối thiểu để làm cho việc này hoạt động: xếp chuỗi interceptor của bạn dưới dạng xác thực (gắn token bearer), thử lại (backoff cấp số nhân trên mã trạng thái UNAVAILABLE), sau đó là quan sát (histogram độ trễ và chỉ số tỷ lệ lỗi cho mỗi phương thức RPC). Khả năng tổng hợp này là một trong những điểm mạnh thầm lặng của gRPC. Trong REST, bạn phải xây dựng lại điều này cho từng thư viện client HTTP.
Những lưu ý quan trọng
-
gRPC-Web không hỗ trợ streaming hai chiều. Nếu ứng dụng di động của bạn có một client web đồng hành, bạn phải quay lại streaming một chiều (unary hoặc server-side) trong trình duyệt hoặc các môi trường không có HTTP/2 gốc.
-
Payload nhị phân không con người có thể đọc được trong các trình kiểm tra mạng mà không có công cụ như
grpcurlhoặc phản chiếu của Buf. Việc gỡ lỗi thực sự khó hơn. -
Sự phức tạp của bộ công cụ là có thật. Trình biên dịch Protobuf, các plugin cụ thể theo ngôn ngữ, tích hợp hệ thống xây dựng — chi phí thiết lập không nhỏ, và mọi thành viên mới trong nhóm đều phải trả lại chi phí này.
-
Các API CRUD đơn giản thu được ít lợi ích. Nếu ứng dụng của bạn 90% là lấy tài nguyên cơ bản, REST với một đặc tả OpenAPI có định dạng tốt sẽ cung cấp cho bạn tính an toàn kiểu tương tự với một ngăn công nghệ đơn giản hơn.
Kết luận
Hãy áp dụng gRPC cho các API có tải trọng nặng (payload-heavy), streaming nhiều, hoặc đa nền tảng nơi codegen và định dạng nhị phân cộng hưởng thành những khoản tiết kiệm thực tế. Hãy giữ REST cho các endpoint công khai đơn giản. Sử dụng Wire cho các dự án KMP — khả năng tạo mã đa nền tảng và dấu chân nhỏ (footprint) của nó khiến nó trở thành lựa chọn thực tế hơn plugin chính thức của Google. Và luôn viết schema .proto trước. Hành động viết nó chính xác sẽ sớm phơi bày các lỗi thiết kế.
Bài viết liên quan

Công nghệ
Thẩm phán phán quyết chính quyền Trump vi phạm quyền tự do ngôn luận khi gây áp lực gỡ bỏ ứng dụng theo dõi ICE
18 tháng 4, 2026

Phần mềm
App Store đang bùng nổ trở lại, và AI có thể là nguyên nhân chính
18 tháng 4, 2026
Công nghệ
Đánh giá Asus TUF Gaming A14 (2026): Laptop gaming không card rời - Đột phá hay đắt đỏ?
18 tháng 4, 2026
