After this lesson, you will be able to: Choose between REST, GraphQL, and gRPC for a given problem, and design an API with versioning, pagination, idempotency, and consistent error handling.
Every system has an API at its boundary, and how you design it determines whether other teams can build on your service without constant questions. This lesson covers the three dominant API styles and the design decisions (versioning, pagination, idempotency) that separate an API people enjoy using from one they curse.
REST exposes resources over HTTP verbs (GET/POST/PUT/DELETE) and is the default for public web APIs: simple, cacheable, universally understood. GraphQL exposes a single endpoint where the client asks for exactly the fields it wants, which solves over-fetching and under-fetching for complex, client-driven UIs (mobile apps with many screens). gRPC uses Protocol Buffers over HTTP/2 for fast, strongly-typed, binary calls, and shines for internal service-to-service communication where speed and contracts matter more than browser-friendliness. Rule of thumb: REST for public APIs, GraphQL for rich client-driven product APIs, gRPC between your own backend services.
Two decisions every real API has to make on day one.
// Versioning: never break existing clients. Put the version in the path or a header.GET /v1/orders // path versioning (most common, most visible)GET /ordersAccept: application/vnd.api+json; version=2 // header versioning// Pagination: never return an unbounded list.// Offset pagination (simple, but slow + unstable on deep pages):GET /orders?limit=20&offset=40// Cursor pagination (stable + fast for large/changing data sets):GET /orders?limit=20&cursor=eyJpZCI6MTIzfQ// Response includes the next cursor:{ "data": [ ... ], "nextCursor": "eyJpZCI6MTQzfQ" }
Pick one error envelope and use it everywhere: a stable machine-readable `code`, a human `message`, and optional `details`. Use HTTP status codes correctly (400 for bad input, 401 vs 403 for auth, 404 for missing, 409 for conflict, 429 for rate limited, 500 for your fault). For gRPC and GraphQL the transport differs but the principle is identical: predictable, documented error shapes mean clients write less defensive code. Pair this with the OpenAPI documentation from the fundamentals docs lesson so the contract is published, not folklore.
Shipping v1 with no versioning plan, then breaking every client when v2 ships. Version from the first release. Returning unbounded lists with no pagination, which works in dev and falls over in production. Non-idempotent payment or order endpoints, leading to double charges on client retries. Reaching for GraphQL or gRPC because they are fashionable when a boring REST API would have been simpler and cacheable. Inconsistent error shapes across endpoints, so every client has to special-case your API.
Pick the standard solution.
Sign in and purchase access to unlock this lesson.