← Back to Blog

February 20, 2026

Modern API Design Patterns

APIs are contracts. Break the contract, break the trust. Here's how to design APIs that last.

Choosing the Right Protocol

There's no universal answer. Each protocol excels in different contexts:

Protocol Best For Watch Out For
REST Public APIs, CRUD-heavy services Over-fetching, versioning headaches
GraphQL Frontend-driven development, complex data graphs N+1 queries, caching complexity
gRPC Service-to-service communication, streaming Browser support, debugging difficulty

REST Done Right

Most REST APIs I've seen in enterprise environments are REST in name only. True RESTful design means:

  • Resources, not actions/orders/123 not /getOrder?id=123
  • HTTP verbs matter — GET is safe, PUT is idempotent, POST is neither
  • HATEOAS — controversial, but hypermedia links make APIs self-documenting
{
  "id": "order-123",
  "status": "shipped",
  "total": 149.99,
  "_links": {
    "self": { "href": "/orders/order-123" },
    "cancel": { "href": "/orders/order-123/cancel", "method": "POST" },
    "tracking": { "href": "/shipments/ship-456" }
  }
}

Versioning Strategy

URL versioning (/v2/orders) is the simplest and most explicit. Header-based versioning is cleaner in theory but harder to test with a browser or curl.

Pick one approach and stick with it across your entire platform. Consistency matters more than perfection.

Rate Limiting and Throttling

Every public API needs rate limiting. Every internal API probably does too — a misbehaving batch job can DDoS your own services just as effectively as an external attacker.

Use token bucket or sliding window algorithms. Return 429 Too Many Requests with a Retry-After header. Make it easy for consumers to do the right thing.

The Biggest Mistake

Designing your API around your database schema. Your API is a product interface — it should model the domain, not your tables. An order in your API might pull from five different database tables, and that's fine. The consumer shouldn't know or care.