Mnemosyne

API Design

Principles and patterns for designing robust, scalable APIs.

REST Fundamentals

REST (Representational State Transfer) is an architectural style built on top of HTTP. A well-designed REST API maps resources to URLs and uses HTTP methods to express operations:

  • GET — read a resource (idempotent)
  • POST — create a new resource
  • PUT — replace a resource entirely (idempotent)
  • PATCH — partially update a resource
  • DELETE — remove a resource (idempotent)

Resources should be nouns (/users/123), not verbs (/getUser). Use plural nouns for collections.

Status Codes

Use HTTP status codes meaningfully:

RangeMeaningExamples
2xxSuccess200 OK, 201 Created, 204 No Content
3xxRedirection301 Moved, 304 Not Modified
4xxClient error400 Bad Request, 401 Unauthorized, 404 Not Found, 429 Too Many Requests
5xxServer error500 Internal, 502 Bad Gateway, 503 Unavailable

Pagination

For large collections, always paginate. Common approaches:

  • Offset-based: ?page=2&limit=20 — simple but skips are expensive on large datasets
  • Cursor-based: ?cursor=abc123&limit=20 — more efficient, uses an opaque token pointing to the last item

Versioning Strategies

APIs evolve, and breaking changes are inevitable. Plan for versioning from day one:

  1. URL path: /v1/users — most common, very explicit
  2. Query parameter: /users?version=1 — flexible but easy to miss
  3. Header: Accept: application/vnd.myapi.v1+json — cleanest separation but harder to test in browsers

Rate Limiting

Protect your API with rate limiting. Include rate limit headers in responses:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1625097600

Common algorithms: token bucket (smooth, allows bursts), sliding window (precise), and fixed window (simplest).

Authentication

  • API Keys — simple, good for server-to-server. Pass in headers, not URLs.
  • OAuth 2.0 — standard for delegated access. Use authorization code flow for web apps.
  • JWT — self-contained tokens with claims. Verify signature server-side. Set short expiration times.

Error Responses

Return consistent, structured error bodies:

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Email is required",
    "details": [
      { "field": "email", "issue": "must not be empty" }
    ]
  }
}

Review Questions