Zero→Hero
0/17
Module 2 · Communication · Unit 07

API Design

The API is the contract between clients and your system. Designing it well — and knowing REST vs GraphQL vs gRPC tradeoffs and idempotency — sets up everything downstream.

⏱ 30 min Prereq: Unit 01 You'll be able to: define a clean API and reason about its tradeoffs

By the end of this unit

REST vs GraphQL vs gRPC

RESTGraphQLgRPC
StyleResources + HTTP verbsSingle endpoint, client-specified queryBinary RPC over HTTP/2
Best forPublic APIs, CRUD, cachingRich clients needing varied/aggregated dataInternal service-to-service
WinsSimple, cacheable, ubiquitousNo over/under-fetching; one round tripFast, typed (protobuf), streaming
CostsOver/under-fetching; many endpointsCaching & rate-limiting harder; server complexityNot browser-native; less human-readable
The clean answer "REST for the public/client API because it's cacheable and simple; gRPC between internal services for speed and typed contracts. I'd reach for GraphQL if mobile clients need to assemble lots of related data in one call and over-fetching is hurting them."

Designing good REST

Resources are nouns, verbs are HTTP methods:

POST /v1/posts → create a post (returns 201 + id)

GET /v1/posts/{id} → fetch one (200 / 404)

GET /v1/users/{id}/feed?cursor=abc&limit=20 → paginated feed

DELETE /v1/posts/{id} → remove (204)

Idempotency — the one they probe

An operation is idempotent if doing it twice has the same effect as once. GET, PUT, DELETE are naturally idempotent; POST usually isn't (two posts = two records). This matters because networks retry: a client doesn't know if a timed-out request succeeded, so it resends.

The fix for unsafe writes: an idempotency key. The client sends a unique key with the request; the server records it and, on a duplicate key, returns the original result instead of doing the work again. This is how payment APIs guarantee a retry never double-charges.

Always raise this for writes Any "create payment / place order / send message" endpoint should mention idempotency keys. It's a top signal that you think about real-world failure, not just the happy path.

Auth & the edge

Authentication ("who are you?") vs authorization ("what may you do?"). Typical pattern: client logs in, gets a token (often a JWT or an opaque session token); an API gateway validates it on every request before traffic reaches your services. Put cross-cutting concerns at this edge: TLS termination, auth, rate limiting, request validation.

Intra-service communication patterns

Synchronous (REST/gRPC call and wait): simple, but couples services and propagates latency/failure. Asynchronous (publish an event to a queue/bus): decouples services, absorbs spikes, but is eventually consistent and harder to trace. Rule of thumb: synchronous when the caller needs an answer now (e.g., auth check); asynchronous for fan-out side-effects (e.g., "post created → update feeds, send notifications, index for search"). Queues are Unit 08.

Quick check
A "charge card" endpoint times out, so the mobile client retries. How do you prevent a double charge?
Idempotency key. The client can't know if the first attempt succeeded, so retries are inevitable. Recording the key server-side makes the second attempt a safe no-op that returns the first result. Turning a charge into a GET would be semantically wrong and unsafe.
Quick check
Two internal microservices exchange high-volume, latency-sensitive calls with strict typed contracts. Best protocol?
gRPC. For internal east-west traffic, gRPC's compact binary encoding, multiplexed HTTP/2 connections, generated typed stubs, and streaming make it faster and safer than JSON REST. GraphQL/REST are better suited to external clients.

Practice before you move on

Write the API for a URL shortener: the create endpoint, the redirect, and listing a user's links with pagination. Mark which methods are idempotent, choose cursor vs offset pagination with a reason, and say where auth and rate limiting live.

Finished this 30-min unit?