API Design

APIs are the contracts between services and between services and clients. A well-designed API is intuitive, consistent, versioned, and resilient. This chapter covers REST, GraphQL, gRPC, and the principles that apply to all API styles.

REST (Representational State Transfer)

REST is the most widely used API style for web services. It uses HTTP methods and standard conventions to expose resources.

Core Principles

  • Resources: Everything is a resource identified by a URL. /users/123 is the resource for user 123.
  • HTTP Methods: Use GET to read, POST to create, PUT to replace, PATCH to update, DELETE to remove.
  • Stateless: Each request contains all the information needed to process it. No server-side session state.
  • Representations: Resources can have multiple representations (JSON, XML, HTML). JSON is the de facto standard.

URL Design Best Practices

GET /users # List all users GET /users/123 # Get user 123 POST /users # Create a new user PUT /users/123 # Replace user 123 PATCH /users/123 # Partially update user 123 DELETE /users/123 # Delete user 123 GET /users/123/orders # List orders for user 123 GET /users/123/orders/456 # Get order 456 for user 123
  • Use nouns, not verbs: /users not /getUsers.
  • Use plural nouns: /users not /user.
  • Use kebab-case for multi-word resources: /user-profiles.
  • Nest resources to express relationships: /users/123/orders.
  • Do not nest more than two levels deep. Beyond that, use query parameters or separate endpoints.

Pagination

Large collections must be paginated. Common approaches:

StyleParametersProsCons
Offset-based?offset=20&limit=10Simple. Allows jumping to any page.Slow for large offsets. Inconsistent if data changes between requests.
Cursor-based?cursor=abc123&limit=10Consistent pagination. Fast regardless of position.Cannot jump to arbitrary pages.
Keyset-based?after_id=123&limit=10Uses indexed column. Very efficient.Requires a unique, sequential key.

Idempotency

Idempotent endpoints produce the same result regardless of how many times they are called. GET, PUT, and DELETE are idempotent by design. POST is not.

For non-idempotent operations (e.g., payment processing), use an idempotency key: the client sends a unique key with the request. If the server sees the same key again, it returns the cached result instead of processing again.

GraphQL

GraphQL is a query language for APIs developed by Facebook. Instead of fixed endpoints returning fixed data, the client specifies exactly what fields it needs.

GraphQL# Client requests exactly the fields it needs query { user(id: "123") { name email orders(last: 5) { id total status } } }

Advantages

  • No over-fetching: Clients get exactly the data they ask for, nothing more.
  • No under-fetching: A single request can fetch related data (user + orders) that would require multiple REST calls.
  • Strong typing: The schema defines all available types and fields. Validated at build time.
  • Introspection: The API is self-documenting. Tools can auto-generate clients and documentation.

Disadvantages

  • Complexity: More complex server-side implementation (resolvers, data loaders).
  • Caching: HTTP-level caching does not work naturally (all requests are POST to the same URL). Requires application-level caching.
  • N+1 Problem: Naive resolvers can generate too many database queries. Mitigated with DataLoader batching.
  • Security: Arbitrary query depth can be exploited for denial-of-service. Must enforce query complexity limits.

gRPC

gRPC is a high-performance RPC framework using HTTP/2 and Protocol Buffers. Ideal for service-to-service communication.

Protobufsyntax = "proto3"; service UserService { rpc GetUser (GetUserRequest) returns (User); rpc ListUsers (ListUsersRequest) returns (stream User); } message GetUserRequest { string id = 1; } message User { string id = 1; string name = 2; string email = 3; }

When to Use gRPC

  • Internal microservice-to-microservice calls where performance matters.
  • Streaming use cases (server- or bi-directional streaming).
  • When you need strong typing across multiple languages.
  • Not ideal for browser clients (limited browser support for HTTP/2 trailers, though gRPC-Web bridges the gap).

API Versioning

StrategyExampleProsCons
URL Path/v1/users, /v2/usersClear, explicit. Easy to route.Breaks URL semantics (version is not a resource).
Query Parameter/users?version=2URL remains clean. Optional.Easy to forget. Routing is harder.
HeaderAccept: application/vnd.api.v2+jsonURL stays the same. No coupling to version in URL.Less discoverable. Harder to test in browser.
Recommendation
URL path versioning (/v1/) is the most common and practical choice. It is explicit, easy to understand, and well-supported by load balancers and API gateways. Use it unless you have a specific reason not to.

Rate Limiting in APIs

APIs should communicate rate limits to clients via response headers:

X-RateLimit-Limit: 100 # Max requests per window X-RateLimit-Remaining: 42 # Requests remaining X-RateLimit-Reset: 1612345678 # Unix timestamp when window resets Retry-After: 30 # Seconds to wait (on 429 response)

REST vs. GraphQL vs. gRPC

AspectRESTGraphQLgRPC
ProtocolHTTP/1.1 or HTTP/2HTTP (usually POST)HTTP/2
Data FormatJSONJSONProtocol Buffers (binary)
TypingWeak (OpenAPI spec optional)Strong (schema)Strong (protobuf)
CachingHTTP caching works naturallyRequires custom cachingNo HTTP caching
Best ForPublic APIs, CRUD operationsFlexible client-driven queriesInternal service-to-service
Learning CurveLowMediumMedium-High

Key Takeaways

  • REST is the pragmatic default for public-facing APIs. Follow conventions strictly.
  • GraphQL shines when clients need flexible, efficient data fetching: especially mobile apps with bandwidth constraints.
  • gRPC is the performance champion for internal services. Use it for server-to-server communication.
  • Always version your APIs from day one. URL path versioning is the most straightforward approach.
  • Design for idempotency, especially for write operations that may be retried on failure.
  • Use cursor-based pagination for large, dynamic datasets.

Chapter Check-Up

Quick quiz to reinforce what you just learned.

๐Ÿงช

Practice What You Learned

Set up an API Gateway with authentication and rate limiting in our guided lab.

Start Guided Lab โ†’