REST API Advanced

Design for retries, scale, and failure.

Advanced REST work starts when calls are high-volume, user money is involved, or multiple services depend on the same endpoint. At this level you design for duplicates, timeouts, abuse, and data consistency.

Idempotency

Use an `Idempotency-Key` when the same create request might be retried. This prevents duplicate orders, payments, or conversions.

Retries and backoff

Retry only safe failures such as timeouts or transient 5xx errors, and always back off instead of retrying instantly.

Rate limiting

Protect shared infrastructure with per-key, per-IP, or per-user request limits.

Concurrency control

Prevent lost updates with row version fields, timestamps, or optimistic locking.

Observability

Attach request ids, trace ids, latency, and error tags so teams can debug distributed systems quickly.

Webhook security

Sign webhook payloads with HMAC and verify the signature before trusting the event.

Architecture choice

Choose REST, GraphQL, gRPC, async events, or streaming based on public compatibility, flexibility, and performance needs.

Idempotency and retries

If a client times out, it may retry even though the server already created the record. Idempotency lets the server recognize that duplicate attempt and return the original result instead of creating a second row.

POST /api/orders
Idempotency-Key: order-20260325-00091
Content-Type: application/json
Authorization: Bearer TOKEN

{
  "customer_id": 44,
  "amount": 199.00,
  "currency": "USD"
}

Concurrency and consistency

  • Two users updating the same record at the same time can overwrite each other if the API blindly accepts both writes.
  • Use `updated_at`, version numbers, or ETags to detect that the record changed after the client last read it.
  • Return `409 Conflict` when the client needs to re-fetch and retry with fresh data.

Webhook signature verification

REST is request-response, but production systems often pair it with webhooks so downstream systems get updates as soon as something changes.

$payload = file_get_contents('php://input');
$incomingSignature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';
$expectedSignature = hash_hmac('sha256', $payload, $sharedSecret);

if (!hash_equals($expectedSignature, $incomingSignature)) {
    http_response_code(401);
    exit('Invalid signature');
}

Tracing and logs

When multiple services call each other, a request id or trace id is what lets you connect the browser error to the backend logs, queue message, and database write.

{
  "request_id": "req_74b2",
  "trace_id": "trace_98ee",
  "status": "error",
  "error_code": "upstream_timeout",
  "latency_ms": 1432
}

REST plus queues

A fast REST endpoint can accept the request, validate it, store a job, and return immediately while background workers do the heavier processing.

REST plus caching

High-read endpoints often sit behind CDN or Redis caching layers so the origin database is not hit for every dashboard load.

REST plus websockets

If the UI needs push updates instead of periodic fetch calls, REST usually handles CRUD while websockets or SSE handle live notifications.

Architecture patterns used beyond simple CRUD

API Gateway

Central place for auth, TLS termination, rate limits, routing, and policy enforcement.

BFF

Backend-for-Frontend keeps mobile, web, and partner clients from forcing one generic API shape.

Saga

Distributed workflows use local transactions plus compensating steps instead of one global transaction.

Service mesh

Moves mTLS, retries, telemetry, and traffic control into the proxy layer instead of every app.

REST vs GraphQL vs gRPC

Style Typical contract Strength Best fit
REST OpenAPI plus HTTP semantics Strong HTTP caching and public interoperability Public APIs and broad platform support
GraphQL Schema and client-selected operations Harder to cache at the CDN edge Client-driven data graphs
gRPC Protobuf service definition Usually internal and performance-oriented Inter-service calls and streaming RPC

Event-driven APIs

A common production pattern is REST for commands and queries, then async events for propagation. Think `OrderCreated`, `PaymentCaptured`, or `ItemUpdated` flowing through queues or brokers.

Streaming and real-time

Use SSE for simple server push over HTTP and WebSockets when you need full-duplex communication or bidirectional live interaction.

Developer experience and monetization

Public API products often combine docs, usage plans, API keys, quotas, billing, and self-serve portals. Developer experience becomes part of the product itself.