Card 04/ 09
Style Example: An Order and Its Items in REST, GraphQL and gRPC
One screen needs an order, its items and each item's product; count the calls and the unused fields in each style.
Putting one screen through REST, GraphQL and gRPC shows how each handles over-fetching, receiving fields the client does not use, and under-fetching, needing extra requests to get everything. The phone screen shows an order number, and for each of its three items the product name and quantity. The counts and sizes are illustrative.
| Style | Calls made | Data returned | Fields unused |
|---|---|---|---|
| REST, resource per URL | 7: the order, then each of 3 items, then each of 3 products | About 18 KB | Most: the order alone has 40 fields, and the screen uses 1 |
| REST, with ?include=items.product | 1 | About 9 KB | Many: still every field of each resource |
| GraphQL | 1 query naming the order number and each item's product name and quantity | About 0.4 KB | None |
| gRPC, GetOrderDetails | 1 | About 0.6 KB, binary | Some: the message the procedure returns is fixed |
REST under-fetches and over-fetches at once. Seven requests, each paying the network's delay on a phone, and most of the bytes are fields nobody reads. An include parameter, or a dedicated endpoint for the screen, fixes the calls but not the size.
GraphQL fits the screen exactly. One request, and only the fields named. That is what it was designed for: many screens, each wanting a different slice of the same data.
gRPC depends on the procedure. With a procedure designed for this screen, one call returns a compact binary message. With fine-grained procedures, GetOrder then GetItem three times, it under-fetches like REST, though each call is cheaper.
What it does not show. The REST responses can be cached by every HTTP cache on the way; the GraphQL query cannot without extra work. The smallest response is not always the fastest system.
← → move through sections and cards