SkillPilotAI

API Design and Service Communication: REST vs gRPC vs GraphQL

How services and clients talk to each other: REST (resources over HTTP), gRPC (fast binary RPC) or GraphQL (the client gets exactly the data it asks for).

31.1 Why is it used?

  • Good API design lets mobile, web and partners integrate easily and keeps breaking changes low.
  • Between microservices every millisecond matters; gRPC gives a payload much smaller and faster than JSON REST.
  • If a mobile app must call 5 APIs for one screen, it is slow; GraphQL can fetch everything in one query.
  • Duplicate payments on retry, or returning lakhs of records at once: idempotency and pagination solve these.

31.2 How it works

  • REST: resources + HTTP verbs (GET /orders/123, POST /orders), status codes (200, 201, 400, 404, 429, 500), JSON body.
  • gRPC: the contract lives in Protocol Buffers (.proto), binary over HTTP/2; unary + client/server/bidirectional streaming, code is auto-generated.
  • GraphQL: one endpoint (/graphql), schema + typed queries; the client chooses the fields, so over-fetching/under-fetching disappear.
  • Versioning: URL (/v1/orders), header (Accept-Version), or backward-compatible changes (only add new optional fields); in GraphQL you deprecate fields.
  • Pagination: offset/limit (simple, but deep pages are slow and data shifts); cursor/keyset (next_cursor=last_id, best for big data).
  • Idempotency key: the client sends a unique 'Idempotency-Key' header with every POST; the server stores the result and returns the same response on retry (Stripe's pattern).
  • Timeouts, retries with backoff and circuit breaker: essential for service-to-service calls so one slow service does not bring everyone down.
  • Sync vs async: if you need an immediate answer use REST/gRPC; do the rest asynchronously through events/queues.
REST, gRPC, GraphQL and an idempotent Payment API
  1. 1.A REST: Mobile app calls GET /v1/users/42, /v1/payments, /v1/rewards; 1 screen = 3 calls; status codes 200 / 201 / 400 / 404 / 429; over/under-fetching
  2. 2.B gRPC: API server -> Payment service, HTTP/2 + binary protobuf + streaming; code auto-generated from payment.proto; not directly usable from a browser
  3. 3.C GraphQL: the web dashboard sends one query (user id 42: name, payments last 5, rewards) -> POST /graphql -> resolvers (users, payments, rewards), backed by gRPC calls
  4. 4.D Payment API: POST /v1/payments + Idempotency-Key 7f3a; the server saves the key as 'processing' in Redis/DB, then gRPC Pay 499 (charged once)
  5. 5.If the response is lost / times out, the app retries with the same key; the key is found, so the stored response, 201 + paymentId, is returned and there is no double charge
  6. 6.Pagination: GET /v1/payments?limit=20 -> 20 records + next_cursor; ?cursor=abc fetches the next 20 (better than offset)

REST/GraphQL outside, gRPC + async events inside

31.3 Tools

ToolTypeHow it is used
OpenAPI (Swagger)REST API specWrite the REST contract in YAML, generate docs and client SDKs.
gRPC + Protocol BuffersRPC framework (Google, CNCF)Internal microservice calls; you can also expose them to REST clients via Envoy/grpc-gateway.
Apollo GraphQL / GraphQL FederationGraphQL server + gatewayJoins the schemas of multiple services into one supergraph, giving the frontend a single API.
AWS AppSyncManaged GraphQL (AWS)DynamoDB/Lambda resolvers, real-time subscriptions, serverless.
PostmanAPI testing / docsCollections, automated API tests and mock servers.
Kong / AWS API Gateway / ApigeeAPI GatewayVersioned routes, auth, rate limit, transformations; placed in front of public APIs.

31.4 Comparison: REST vs gRPC vs GraphQL

PointRESTgRPCGraphQL
FormatJSON (text) over HTTP/1.1 or 2Protobuf (binary) over HTTP/2JSON over HTTP, mostly one endpoint
SpeedGood, but larger payloadFastest, small payload, multiplexingGood, but complex queries are heavy on the server
ContractOptional (OpenAPI)Strict .proto, code generationStrictly typed schema
Data fetchingFixed response, over/under fetchingFixed per RPC methodThe client asks for exact fields
StreamingNo (SSE/WebSocket are separate)Built-in bidirectional streamingSubscriptions (over WebSocket)
Browser supportNative, everywhereNot direct, needs gRPC-Web + a proxyNative
CachingHTTP caching is easy (GET, CDN)HardHard (POST), better with persisted queries
Best forPublic APIs, simple CRUDInternal microservice calls, low latencyMobile/web frontends with complex screens

31.5 When to choose which

  • REST: public/partner APIs, simple CRUD, when you need CDN caching.
  • gRPC: internal service-to-service calls where latency and throughput are critical, or when you need streaming.
  • GraphQL: when the frontend needs data from multiple services in one call and screens change quickly.
  • Common pattern: REST/GraphQL outside, gRPC + async events inside.

31.6 Real-world example

Scenario: Payment API with idempotency and pagination

  1. The mobile app taps 'Pay 499': POST /v1/payments with header Idempotency-Key: 7f3a-uuid.
  2. The API server checks the key in Redis/DB; it is new, so it saves status 'processing' and makes a gRPC call to the payment service.
  3. Because of a network timeout the app did not get the response, and retries with the same key.
  4. The server already has the key, so it does not charge again; it returns the stored response (201, paymentId). No double charge.
  5. The user opens transaction history: GET /v1/payments?limit=20 -> 20 records + next_cursor; on scroll, ?cursor=abc fetches the next 20.
  6. A new field 'upi_app' is added; it is optional, so old clients do not break and no v2 is needed.
  7. The web dashboard uses GraphQL to get user + last 5 payments + rewards in one query; in the backend this resolves into gRPC calls.

31.7 Interview tips

  • A POST payment API without an idempotency key: a mobile retry causes a double charge.
  • Offset pagination on big tables (OFFSET 1000000): the DB gets slow; use cursor-based.
  • A breaking change without versioning: a field was renamed and old app versions crash.
  • Interview tip: say 'REST for public, gRPC for internal, GraphQL for aggregation', with reasons.