Chọn giao thức theo hình dạng cuộc hội thoại, không theo độ phổ biến.Pick a protocol by the shape of the conversation, not by popularity.
Ai hỏi, ai đẩy, kết nối sống bao lâu, hợp đồng chặt đến đâu. Trả lời bốn câu đó là gần như đã chọn xong. Dải bên dưới xếp sáu cái tên theo trục quan trọng nhất: ai khởi xướng.Who asks, who pushes, how long the connection lives, how strict the contract is. Answer those four and you've almost chosen. The strip below places all six on the axis that matters most: who initiates.
Sáu cái tên, không cùng một loại. REST là phong cách kiến trúc, GraphQL là ngôn ngữ truy vấn, gRPC là framework; chỉ SOAP, WebSocket và MQTT là giao thức đúng nghĩa. Vì vậy chúng hay đi cùng nhau: GraphQL subscriptions chạy trên WebSocket, MQTT chạy được trên WebSocket để vào trình duyệt.Six names, not one kind of thing. REST is an architectural style, GraphQL a query language, gRPC a framework; only SOAP, WebSocket and MQTT are protocols in the strict sense. That's why they combine: GraphQL subscriptions run over WebSocket, and MQTT can run over WebSocket to reach browsers.
Chọn cái nàoWhich one to pick
Hỏi trước: có cần cái nào không? Phương án nhàm chán thường đủ, và rẻ hơn nhiều.Ask first: do you need any of them? The boring option is often enough, and much cheaper.
Không cần cái nào cả khi…You need none of them when…
Hai module trong cùng một ứng dụngTwo modules in the same appGọi hàm trực tiếp. Tách service là quyết định tổ chức, không phải kỹ thuật.Call the function. Splitting services is an organizational decision, not a technical one.
Đồng bộ một ngày một lầnSyncing once a dayCron xuất file lên S3, bên kia đọc.A cron job exports a file to S3; the other side reads it.
Server chỉ cần đẩy xuống trình duyệtThe server only pushes to the browserServer-Sent Events: HTTP thường, tự kết nối lại.Server-Sent Events: plain HTTP, auto-reconnect.
Cập nhật vài phút một lần là đủUpdates every few minutes are finePolling mỗi 30–60 giây. Cache được, không có trạng thái.Poll every 30–60 s. Cacheable, stateless.
Báo cho hệ thống khác khi có sự kiệnNotifying another system of an eventWebhook: một POST có chữ ký và retry.A webhook: one signed POST with retries.
Nếu cần, đi từ trên xuống, dừng ở dòng đầu tiên khớpIf you do, go top to bottom and stop at the first match
Đối tác bắt buộc SOAP, gửi bạn file WSDLA partner requires SOAP and sent a WSDLSOAP
Client là thiết bị IoT, pin yếu, mạng chập chờnClients are IoT devices, low battery, flaky networkMQTT
Cần real-time, chỉ server đẩy xuốngReal-time, server to client onlySSE
Cần real-time hai chiều từ trình duyệtReal-time both ways from a browserWebSocket
Service nội bộ, cần hiệu năng hoặc streamingInternal services needing speed or streaminggRPC
Nhiều client, mỗi màn hình cần dữ liệu từ nhiều nguồnMany clients, each screen pulls from many sourcesGraphQL
Còn lại: API công khai, CRUD, webhookEverything else: public APIs, CRUD, webhooksREST
Kết hợp là bình thường: REST ra ngoài, gRPC bên trong, WebSocket cho tính năng live.Mixing is normal: REST outside, gRPC inside, WebSocket for live features.
Tra cứu từng cáiReference
Ba họ, chia theo cách hai bên nói chuyện. Màu của họ đi theo xuyên suốt trang.Three families, grouped by how the two sides talk. Each family's color follows it across the page.
Hỏi–đáp qua HTTPRequest–response over HTTP
Client hỏi, server trả lời, kết nối xong là thôi.The client asks, the server answers, and that's the end of it.
REST
Hỏi–đápRequest–response
Phong cách kiến trúc, Fielding 2000Architectural style, Fielding 2000
Mọi thứ là tài nguyên có URL, thao tác bằng động từ HTTP; server không nhớ phiên.Everything is a resource with a URL, handled with HTTP verbs; the server keeps no session.
Dùng choUse for
API công khai, CRUD cho web và mobile, dữ liệu đọc nhiều cần CDN, webhook.Public APIs, CRUD for web and mobile, read-heavy data behind a CDN, webhooks.
ĐượcGain
Ai cũng gọi được, cache HTTP miễn phí, mở rộng ngang dễ, gỡ lỗi bằng curl.Anyone can call it, free HTTP caching, easy horizontal scaling, debug with curl.
MấtLose
Thừa hoặc thiếu dữ liệu mỗi lần gọi, hợp đồng không bắt buộc, không có push.Over- or under-fetching, no enforced contract, no push.
Đánh đổiTrade-offChọn REST là đổi hiệu năng và độ chính xác của dữ liệu trả về lấy tính phổ quát và khả năng cache.Choosing REST trades performance and precise data shaping for universality and cacheability.
Dấu hiệu:Signal:bạn không biết trước ai sẽ gọi API và họ dùng ngôn ngữ gì.you don't know in advance who will call the API or in what language.
Server công bố schema có kiểu; client hỏi đúng hình dạng dữ liệu cần qua một endpoint duy nhất.The server publishes a typed schema; the client asks for exactly the shape it needs through one endpoint.
Dùng choUse for
Frontend gom dữ liệu nhiều nguồn, nhiều loại client chung backend, lớp BFF.Frontends aggregating many sources, many client types on one backend, BFF layers.
ĐượcGain
Đúng field trong một round-trip, schema là tài liệu sống, ít cần versioning.Exact fields in one round trip, the schema is living docs, versioning rarely needed.
MấtLose
Lỗi N+1, mất cache HTTP, truy vấn lồng sâu thành DoS, lỗi trả về HTTP 200.N+1 queries, no HTTP caching, deep queries become DoS, errors return HTTP 200.
Đánh đổiTrade-offChọn GraphQL là đổi sự đơn giản và cache ở server lấy sự linh hoạt ở client.Choosing GraphQL trades server-side simplicity and caching for client-side flexibility.
Dấu hiệu:Signal:đội frontend liên tục xin "thêm một endpoint nữa".the frontend team keeps asking for "one more endpoint".
SOAP
Hỏi–đápRequest–response
Giao thức XML, W3C 2003XML protocol, W3C 2003
Thông điệp XML bọc trong Envelope, hợp đồng mô tả bằng WSDL, chạy được trên HTTP, SMTP hay JMS.XML messages wrapped in an Envelope, a WSDL contract, runs over HTTP, SMTP or JMS.
Hợp đồng chặt, ký và mã hoá từng thông điệp, lỗi có cấu trúc chuẩn.Strict contract, per-message signing and encryption, standard error structure.
MấtLose
XML nặng, công cụ cũ, không cache, khó gọi từ web và mobile.Heavy XML, dated tooling, no caching, awkward from web and mobile.
Đánh đổiTrade-offChọn SOAP là đổi tốc độ phát triển lấy hợp đồng chính thức và bảo mật cấp thông điệp.Choosing SOAP trades development speed for a formal contract and message-level security.
Dấu hiệu:Signal:đối tác gửi bạn file .wsdl thay vì link tài liệu.the partner sends you a .wsdl file instead of a docs link.
Gọi hàm có hợp đồngContract-first remote calls
Hợp đồng viết trước, code sinh ra sau; gọi từ xa như gọi hàm local.Write the contract first, generate the code; call remote functions as if they were local.
gRPC
RPC
Framework RPC, Google 2015RPC framework, Google 2015
Định nghĩa service trong .proto, sinh code cho mọi ngôn ngữ, gọi qua HTTP/2 bằng Protocol Buffers.Define services in .proto, generate code for every language, call over HTTP/2 with Protocol Buffers.
Dùng choUse for
Microservice nội bộ, hệ thống độ trễ thấp, streaming giữa các service, API hạ tầng.Internal microservices, low-latency systems, service-to-service streaming, infrastructure APIs.
ĐượcGain
Payload nhị phân nhỏ, nhiều cuộc gọi trên một kết nối, hợp đồng kiểm tra lúc build, bốn kiểu streaming, deadline lan truyền.Small binary payloads, many calls on one connection, build-time contract checks, four streaming modes, deadline propagation.
MấtLose
Trình duyệt không gọi trực tiếp được, khó đọc bằng mắt, cần load balancing L7.Browsers can't call it directly, hard to read by eye, needs L7 load balancing.
Đánh đổiTrade-offChọn gRPC là đổi khả năng đọc bằng mắt và hỗ trợ trình duyệt lấy hiệu năng và hợp đồng do trình biên dịch kiểm tra.Choosing gRPC trades human readability and browser support for performance and compiler-checked contracts.
Dấu hiệu:Signal:hàng chục service viết bằng nhiều ngôn ngữ, gọi nhau hàng nghìn lần mỗi giây.dozens of services in several languages calling each other thousands of times per second.
Kết nối liên tục, đẩy sự kiệnPersistent connections, pushed events
Kết nối giữ mở; dữ liệu tới ngay khi có, không cần hỏi lại.The connection stays open; data arrives the moment it exists, no re-asking.
Nâng cấp một request HTTP thành kết nối TCP mở lâu; cả hai bên gửi tin bất cứ lúc nào.Upgrade one HTTP request into a long-lived TCP connection; either side sends at any time.
Dùng choUse for
Chat, cộng tác thời gian thực, game trình duyệt, bảng giá, dashboard live.Chat, real-time collaboration, browser games, tickers, live dashboards.
ĐượcGain
Độ trễ thấp, header frame chỉ 2–14 byte, trình duyệt hỗ trợ sẵn.Low latency, frame headers of only 2–14 bytes, native browser support.
MấtLose
Chỉ là kênh truyền thô (không ack, không tự kết nối lại), có trạng thái nên khó mở rộng, proxy cắt kết nối rảnh (idle).Just a pipe (no acks, no reconnect), stateful and harder to scale, proxies drop idle connections.
Đánh đổiTrade-offChọn WebSocket là đổi sự đơn giản của stateless lấy độ trễ thấp và đẩy hai chiều.Choosing WebSocket trades the simplicity of statelessness for low latency and two-way push.
Dấu hiệu:Signal:cả hai phía cùng gửi tin liên tục, nhiều lần mỗi giây.both sides send messages continuously, several times a second.
Thiết bị publish vào topic trên broker; broker chuyển tin tới mọi subscriber khớp topic.Devices publish to a topic on a broker; the broker forwards to every matching subscriber.
Dùng choUse for
IoT, telemetry xe, nhà máy, push nền trên mobile.IoT, vehicle telemetry, factories, background push on mobile.
ĐượcGain
Header tối thiểu 2 byte, bên gửi và bên nhận tách rời, QoS 0/1/2 và Last Will có sẵn.Headers as small as 2 bytes, senders and receivers decoupled, QoS 0/1/2 and Last Will built in.
MấtLose
Broker bắt buộc và là điểm lỗi tập trung, payload không schema, không thay được Kafka.The broker is mandatory and a single point of failure, schemaless payloads, not a Kafka replacement.
Đánh đổiTrade-offChọn MQTT là đổi sự đơn giản của kết nối điểm–điểm lấy khả năng tách rời và chịu mạng kém ở quy mô lớn.Choosing MQTT trades point-to-point simplicity for decoupling and resilience to bad networks at scale.
Dấu hiệu:Signal:thiết bị chạy pin, mạng chập chờn, số lượng tính bằng nghìn.battery-powered devices, flaky networks, counted in thousands.
Bảng đánh đổiTrade-off table
Mỗi hàng là một trục bạn thật sự phải cân khi chọn.Each row is an axis you actually weigh when choosing.
REST
GraphQL
SOAP
gRPC
WebSocket
MQTT
Ai khởi xướngWho initiates
Client
Client (+ subscription)Client (+ subscriptions)
Client
Cả haiBoth
Cả haiBoth
Qua brokerVia broker
Kết nốiConnection
NgắnShort
NgắnShort
NgắnShort
Dài (HTTP/2)Long (HTTP/2)
DàiLong
DàiLong
Hợp đồngContract
Tuỳ chọn (OpenAPI)Optional (OpenAPI)
Schema bắt buộcSchema required
WSDL bắt buộcWSDL required
.proto bắt buộc.proto required
Không cóNone
Không cóNone
Từ trình duyệtFrom a browser
CóYes
CóYes
Cồng kềnhAwkward
Cần gRPC-Web + proxyNeeds gRPC-Web + proxy
CóYes
Qua WebSocketOver WebSocket
Cache HTTP
TốtGood
KémPoor
KhôngNone
KhôngNone
KhôngNone
KhôngNone
Payload
Vừa (JSON)Medium (JSON)
Vừa, đúng fieldMedium, exact fields
Lớn (XML)Large (XML)
Nhỏ (nhị phân)Small (binary)
Tuỳ bạnUp to you
Rất nhỏVery small
Gỡ lỗi bằng mắtDebug by eye
DễEasy
DễEasy
KhóHard
Cần công cụNeeds tools
VừaMedium
Cần công cụNeeds tools
Gánh vận hànhOps burden
ThấpLow
VừaMedium
VừaMedium
VừaMedium
Cao (có trạng thái)High (stateful)
Cao (broker)High (broker)
Sai lầm hay gặpCommon mistakes
Sai lầmMistake
Vì sao saiWhy it's wrong
Sửa thế nàoFix
gRPC cho API công khai gọi từ trình duyệtgRPC for a public browser-facing API
Trình duyệt không nói gRPC; ai dùng cũng phải thêm proxyBrowsers don't speak gRPC; every consumer needs a proxy
REST hoặc GraphQL ra ngoài, gRPC chỉ bên trongREST or GraphQL outside, gRPC only inside
WebSocket khi chỉ server đẩy xuốngWebSocket when only the server pushes
Gánh trọn chi phí có trạng thái mà không cần hai chiềuFull stateful cost without needing two-way
SSE
GraphQL không có DataLoaderGraphQL without DataLoader
N+1 truy vấn, DB sập khi danh sách dàiN+1 queries; the DB falls over on long lists
Batch theo request, đo số câu SQL mỗi operationBatch per request; count SQL queries per operation
GraphQL công khai không giới hạn truy vấnPublic GraphQL with no query limits
Một truy vấn lồng sâu có thể ăn hết CPUOne deeply nested query can eat all CPU
Giới hạn độ sâu, độ phức tạp; persisted queriesDepth and complexity limits; persisted queries
Đổi số tag trong .protoRenumbering .proto tags
Client cũ giải mã sai dữ liệu mà không báo lỗiOld clients silently decode the wrong data
Chỉ thêm field mới, khoá field cũ bằng reservedOnly add fields; lock old ones with reserved
Coi MQTT như KafkaTreating MQTT like Kafka
Không replay, không consumer group; consumer chết là mất tinNo replay or consumer groups; a dead consumer loses data
MQTT ở biên, đẩy vào queue để xử lýMQTT at the edge, feed a queue for processing
WebSocket không heartbeat, không reconnectWebSocket without heartbeat or reconnect
Kết nối chết im lặng, người dùng thấy dữ liệu đứngConnections die silently; users see frozen data
Ping 20–30 giây, backoff + jitter, đánh số tinPing every 20–30 s, backoff + jitter, sequence numbers
Tách microservice rồi mới chọn giao thứcSplitting services, then picking a protocol
Gánh độ phức tạp mạng cho vấn đề chưa tồn tạiNetwork complexity for a problem you don't have
Bắt đầu bằng monolith, tách khi có lý do đo đượcStart with a monolith; split for a measured reason
Ba câu cần nhớThree things to remember
Sáu cái tên nằm ở các tầng khác nhau: REST là phong cách, GraphQL là ngôn ngữ truy vấn, gRPC là framework, còn SOAP, WebSocket và MQTT là giao thức.These six live at different layers: REST is a style, GraphQL a query language, gRPC a framework, and SOAP, WebSocket and MQTT are protocols.
Câu hỏi đầu tiên là ai khởi xướng: client hỏi thì nghĩ tới REST, GraphQL, gRPC; server cần đẩy thì nghĩ tới SSE, WebSocket, MQTT.The first question is who initiates: if the client asks, think REST, GraphQL, gRPC; if the server must push, think SSE, WebSocket, MQTT.
Bắt đầu bằng phương án nhàm chán nhất và chỉ nâng cấp khi đo được nó không đủ.Start with the most boring option and upgrade only when you can measure that it isn't enough.