Article

How Do You Design a Good REST API? A Practical Guide

How Do You Design a Good REST API? A Practical Guide

A good REST API is predictable, resource-oriented, secure, and easy to evolve. This guide covers URLs, HTTP semantics, errors, pagination, versioning, security, documentation, and Laravel implementation.

5 min readLanguage: EN EnglishFree0 claps0 comments
Reading options

A good REST API feels unsurprising. A developer can predict an endpoint before opening the documentation, understand a response without reading server code, and recover from errors without guessing. That quality comes from consistent design decisions—not from adding more endpoints.

What makes a REST API good?

A strong API models business resources clearly, follows HTTP semantics, uses consistent representations, returns actionable errors, protects data, and evolves without breaking clients. Optimize for the developer consuming the API: names should be obvious, defaults safe, and exceptional behavior documented.

1. Design around resources and nouns

Model stable business concepts such as orders, customers, and invoices. Use plural nouns and express relationships through paths. Prefer /orders/42/items over RPC-style URLs such as /getOrderItems. Keep nesting shallow; deeply nested URLs are hard to authorize and maintain.

GET    /api/v1/orders
POST   /api/v1/orders
GET    /api/v1/orders/42
PATCH  /api/v1/orders/42
DELETE /api/v1/orders/42

2. Use HTTP methods according to their meaning

GET reads without changing state. POST creates or triggers a non-idempotent operation. PUT replaces a resource and should be idempotent. PATCH partially updates it. DELETE removes it and should normally be safe to retry. Following RFC 9110 HTTP semantics makes clients, proxies, caches, and monitoring tools behave correctly.

3. Return precise status codes

Use 200 OK for successful reads or updates, 201 Created plus a Location header for creation, and 204 No Content when success has no body. Distinguish 400 malformed input, 401 missing or invalid authentication, 403 forbidden access, 404 missing resources, 409 conflicts, 422 validation failure, 429 rate limiting, and 5xx server failures.

4. Keep JSON representations consistent

Choose conventions once: field naming, date format, money representation, nullability, and envelope structure. Use ISO 8601 timestamps with time zones. Do not expose database columns accidentally; treat the response as a public contract.

{
  "data": {
    "id": 42,
    "status": "paid",
    "total": 129.90,
    "currency": "USD"
  }
}

5. Make errors useful

Every error should be machine-readable and useful to a human. Include a stable type or code, a short title, the HTTP status, a safe explanation, field-level validation errors, and a request or trace ID. RFC 9457 Problem Details provides a standard format.

{
  "type": "https://api.example.com/problems/validation",
  "title": "Validation failed",
  "status": 422,
  "detail": "One or more fields are invalid.",
  "errors": {"email": ["The email field is required."]}
}

6. Standardize collections

Use explicit query parameters such as ?status=paid&sort=-created_at&page=2&per_page=25. Document allowed filters and sort fields. Set a maximum page size. Cursor pagination is preferable for large or rapidly changing datasets; offset pagination is convenient for small administrative lists.

7. Plan compatibility and versioning

Additive changes are usually safe: new optional fields, new endpoints, and new enum values when clients tolerate unknown values. Renaming fields, changing types, or removing behavior is breaking. Version deliberately—often with /api/v1—and publish a deprecation window and migration notes.

8. Build security into the contract

Require HTTPS, authenticate with an appropriate mechanism, and authorize every resource action. Validate input with allowlists, limit request sizes, rate-limit by identity and route sensitivity, and never return secrets or stack traces. Prefer opaque public IDs where enumeration creates risk. Log security-relevant events without logging credentials or personal data.

9. Support caching and concurrency

For safe reads, use Cache-Control, ETag, and conditional requests where appropriate. For concurrent updates, accept If-Match with an ETag or another version token so one client does not silently overwrite another. Idempotency keys make retried payment or creation requests safer.

10. Document and test the API

Maintain an OpenAPI contract with examples for success, validation, authentication, and rate-limit responses. Use it for generated docs, client SDKs, schema validation, and contract tests. Add correlation IDs, structured logs, latency and error metrics, and distributed traces so production behavior is explainable.

A clean REST API in Laravel

Laravel provides a strong foundation. Route::apiResource creates conventional CRUD routes, Sanctum can authenticate clients, and the throttle middleware protects endpoints.

use App\Http\Controllers\Api\OrderController;
use Illuminate\Support\Facades\Route;

Route::prefix('v1')
    ->middleware(['auth:sanctum', 'throttle:api'])
    ->group(function () {
        Route::apiResource('orders', OrderController::class);
    });

Use Form Request classes for validation and authorization, Eloquent policies for resource permissions, and API Resources to control the JSON contract. Keep controllers focused on HTTP orchestration while services or actions hold complex business logic.

public function show(Order $order): OrderResource
{
    return new OrderResource($order);
}

public function toArray(Request $request): array
{
    return [
        'id' => $this->id,
        'status' => $this->status,
        'total' => $this->total,
        'currency' => $this->currency,
    ];
}

REST API design checklist

  • Resource-oriented, plural, predictable URLs
  • Correct HTTP methods and status codes
  • Stable JSON and Problem Details errors
  • Documented filtering, sorting, and pagination
  • Authentication, authorization, validation, and rate limits
  • Compatibility policy and version strategy
  • OpenAPI examples, contract tests, logs, metrics, and traces

Frequently asked questions

Should REST URLs contain verbs?

Usually no. Use nouns for resources and HTTP methods for actions. A domain command such as POST /orders/42/cancellation is acceptable when it represents a real business resource or state transition.

Should every API be versioned?

Every public API needs a compatibility strategy. A version in the URL is useful when breaking changes are likely; a small internal API may instead rely on strict additive evolution.

What is the most important rule?

Consistency. A slightly imperfect convention applied everywhere is easier to consume than individually clever endpoints that behave differently.

Featured Articles

Kafka in Production: Partition Strategy, Consumer Lag, Reliability, and an Incident Playbook
EditorialEN
17 minFree

Kafka in Production: Partition Strategy, Consumer Lag, Reliability, and an Incident Playbook

A production Kafka cluster needs more than brokers. Learn to choose partition keys, plan retention and capacity, monitor lag, handle rebalances, and rehearse failure recovery.

Engineering ArticlesPlatform Guides
0 claps
Read
Laravel and Kafka Without Lost Events: The Transactional Outbox, Idempotent Consumers, and PostgreSQL
EditorialEN
17 minFree

Laravel and Kafka Without Lost Events: The Transactional Outbox, Idempotent Consumers, and PostgreSQL

A database commit and a Kafka publish cannot safely be treated as one ordinary transaction. This guide builds an outbox and consumer design that survives crashes and duplicate delivery.

Engineering ArticlesPlatform Guides
0 claps
Read
Apache Kafka Explained: Topics, Partitions, Consumer Groups, and Your First Event Pipeline
EditorialEN
15 minFree

Apache Kafka Explained: Topics, Partitions, Consumer Groups, and Your First Event Pipeline

Follow one order event from producer to consumers, then run a local Kafka topic and learn what partitions, offsets, keys, and consumer groups actually do.

Engineering ArticlesPlatform Guides
0 claps
Read

Comments

0 comments

No approved comments are visible yet. New community replies may wait for moderation.