System Design

10) APIs & service design — detailed guide

Protocol choices, gateway patterns, pagination/real-time, versioning, idempotency, multi-tenancy, security, and operational guardrails — with a Facebook-like Home Feed example in every section.

A) REST vs gRPC vs GraphQL (how to choose)

REST (HTTP/JSON)
  • Best for public/partner APIs
  • Human-debuggable, CDN/proxy friendly
  • HTTP caching + ETags
  • Pitfalls: N+1 chatter, inconsistent errors
gRPC (HTTP/2 + Protobuf)
  • Best for service-to-service
  • Low latency, compact payloads
  • Streaming (client/server/bidi)
  • Pitfalls: browsers need proxy, caching awkward
GraphQL
  • Best for complex product UIs
  • Solves over/under-fetching
  • Strong schema + typed fields
  • Pitfalls: expensive queries, caching/resolvers N+1
Protocol choice — template
Template
• REST: external APIs, cacheable reads, heterogeneous clients, “resource” semantics. • gRPC: internal microservices, low latency, strict contracts, streaming. • GraphQL: UI composition across many domains, rapid frontend iteration. Guardrails: • GraphQL: persisted queries, depth/complexity limits, batching (dataloaders). • gRPC: timeouts, retries with budgets, per-method SLOs.
Facebook-like Home Feed — protocol choices
Example
• Public/mobile API: REST for /feed and /posts (easy debugging + CDN). • Internal: gRPC between Feed Service ↔ Ranking ↔ Graph (low latency). • Optional: GraphQL BFF for web UI that composes feed + profile + ads with flexible fields.

B) API gateway & BFF patterns (edge, auth, shaping)

Gateway responsibilities

  • TLS termination, routing, request normalization, compression.
  • AuthN/AuthZ, token validation, scopes, mTLS (internal).
  • Rate limiting, quotas, WAF, bot protection.
  • Response shaping: caching, header policies, partial responses.
  • Protocol translation: REST ↔ gRPC (when needed).
Gateway vs BFF — template
Template
• Edge Gateway: security + traffic controls (auth, rate limits, WAF), routing, caching. • BFF: client-specific aggregation, tailoring payloads, reducing round trips. • Keep business logic in services; BFF should be thin (composition + formatting).
Facebook-like Home Feed — edge + BFF
Example
• Gateway validates JWT, applies per-user quotas, and caches GET /feed for 2–5 seconds. • Web BFF composes feed items with profile snippets and ad metadata for the web UI. • Internal services talk via gRPC; BFF uses timeouts + fallbacks if a dependency is slow.

C) Resource modeling & standards (naming, status codes, caching)

Basics

  • Prefer nouns: /posts, /users, /feed.
  • Use verbs via HTTP methods: GET/POST/PUT/PATCH/DELETE.
  • Return correct status codes: 200/201/204, 400/401/403/404/409/429, 5xx.
  • Use caching for reads: ETag + If-None-Match; short TTL caches at edge (where safe).
REST shape — template
Template
GET  /v1/posts/{post_id}
→ 200
{
  "id": "p_123",
  "author_id": "u_7",
  "created_at": "2026-01-10T00:00:00Z",
  "text": "...",
  "stats": { "likes": 10, "comments": 2 }
}

PATCH /v1/posts/{post_id}
If-Match: "etag_abc"
{ "text": "updated" }
→ 200 (or 409 if ETag mismatch)
Facebook-like Home Feed — endpoint inventory
Example
GET /v1/feed POST /v1/posts POST /v1/posts/{post_id}/likes POST /v1/users/{user_id}/follows Notes: • GET /feed is cacheable (short TTL + ETag). • Writes use idempotency keys and clear 409/429 responses.

D) Pagination, filtering & realtime (SSE/WebSocket/LP)

Pagination

  • Offset/limit: simple but slow/unstable at large offsets.
  • Cursor: stable sort keys like (created_at, id) (explicit string to avoid ESLint no-undef).
  • Rules: bounded limit, stable ordering, return next_cursor, avoid heavy total counts.
Cursor pagination — template
Template
GET /v1/feed?limit=25&cursor=eyJjcmVhdGVkX2F0IjoiMjAyNi0wMS0xMCIsImlkIjoicF8xMjMifQ==
→ 200
{
  "items": [...],
  "next_cursor": "eyJjcmVhdGVkX2F0IjoiMjAyNi0wMS0wOSIsImlkIjoicF85ODcifQ=="
}

Realtime

  • Long polling: simplest fallback, more overhead.
  • SSE: server→client stream over HTTP; easy reconnect; great for feed updates.
  • WebSocket: full duplex; best for chat/presence; needs backpressure + heartbeat.
Facebook-like Home Feed — pagination + realtime
Example
• Feed scrolling uses cursor pagination (created_at + post_id). • Feed updates use SSE: - client connects to /v1/feed/stream - server pushes “new_post” - client merges into UI and can re-fetch with cursor if needed.

E) Versioning & compatibility (expand → dual-run → contract)

Compatibility — template
Template
• Expand: add new fields/endpoints alongside old. • Dual-run: write/read both shapes where needed, compare results. • Contract: remove old after deprecation window and adoption is high. • Measure: traffic by version + error rates + client adoption before removal.
Facebook-like Home Feed — versioning example
Example
• v1: GET /feed returns basic items. • v2: adds “reason” fields (“why you saw this post”) and new ranking metadata. • Sunset: warn in response headers, track v1 traffic, then deprecate.

F) Idempotency & exactly-once effects (practical)

Idempotency key — template
Template
POST /v1/posts
Idempotency-Key: 8f1a1c9a-...
{ "post_id": "p_123", "text": "hello" }

Server behavior:
• First request: create record + store response keyed by (tenant, key, route)
• Retry: return same response (200/201) without re-creating
Facebook-like Home Feed — idempotent writes
Example
• POST /posts uses Idempotency-Key to avoid double post creation. • POST /likes uses (user_id, post_id) unique constraint to prevent duplicate likes. • Fanout events use outbox; consumers are idempotent (dedupe by event_id).

G) AuthN/AuthZ, security & abuse controls

  • AuthN: JWT/OAuth2; validate issuer/audience/expiry; short TTL access tokens.
  • AuthZ: scopes + resource checks (owner/relationship/privacy). Enforce again in service.
  • Abuse: WAF + bot controls; rate limits per user/app/IP; anomaly detection.
  • Privacy: least privilege; audit logs for sensitive operations.
Facebook-like Home Feed — privacy & auth
Example
• GET /feed enforces privacy: blocks, private accounts, content restrictions. • Gateway validates JWT; Feed service re-checks resource-level authorization. • Write endpoints are more strictly rate-limited than reads.

H) Multi-tenancy, quotas & isolation

  • Isolation: shared-everything (tenant_id), isolated DB, or dedicated stack.
  • Noisy neighbor: per-tenant quotas, concurrency caps, priority queues.
  • Tenant-safe caches: tenant_id in keys; no cross-tenant leakage.
Facebook-like Home Feed — tenant controls
Example
• Per-tenant quotas at gateway + service. • Per-tenant concurrency caps prevent one tenant spike from exhausting DB pools. • Cache keys include tenant_id + user_id + privacy policy version.

I) Error model & API ergonomics

Error response — template
Template
{
  "error": {
    "code": "invalid_argument",
    "message": "limit must be between 1 and 50",
    "details": [{ "field": "limit", "reason": "out_of_range", "min": 1, "max": 50 }]
  },
  "request_id": "req_abc123"
}
Facebook-like Home Feed — client-friendly behaviors
Example
• 429 responses include Retry-After + rate limit headers. • Errors always include request_id for support correlation. • Write endpoints accept Idempotency-Key to make retries safe.

J) Observability for APIs

  • Metrics: RED per route (RPS, error rate, latency histograms), sizes.
  • Tracing: propagate TraceContext end-to-end (sync + async).
  • Logs: structured, include request_id, route template, tenant_id (no PII).
  • Alerts: page on SLO burn; ticket on dependency saturation.
Facebook-like Home Feed — SLOs
Example
• SLO: GET /feed p95 ≤ 200ms, availability 99.9% monthly. • Paging: multi-window burn-rate alerts (fast + slow). • Drilldown: metric exemplar → trace → logs by request_id.

K) Rollouts & safety

  • Canary 1%→5%→25%→100% gated on latency/error/burn deltas.
  • Feature flags for fast bailout without redeploy.
  • Schema compatibility tests in CI.
Facebook-like Home Feed — shipping a new ranking feature
Example
• Gate canary on p95 + error deltas. • If slow: flag off enrichment and serve cached feed. • Rollback: gateway routes traffic back to previous version immediately.

Interview one-liners

  • “REST at the edge, gRPC inside; GraphQL for UI composition.”
  • “Cursor pagination with stable sort keys; bounded limits.”
  • “Expand → dual-run → contract for safe versioning.”
  • “Idempotency keys + outbox + UPSERT gives exactly-once effects.”
  • “SLO-burn paging, exemplars for drill-down, canary rollouts with guardrails.”