🌐 Detecting your location…
📢 Advertisement — Configure AdSense in Appearance → Customize → AdSense Settings

REST API Design Best Practices 2026: URLs, Status Codes and Pagination

⏱️4 min read  ·  661 words

Well-designed REST APIs are intuitive to use, consistent, and easy to maintain. In 2026, REST remains the dominant API style for public-facing services, while GraphQL and gRPC serve specific use cases. This guide covers the REST API design principles and patterns used at top companies.

URL Design — Resource-Centric

Good REST URL design:

Resources = nouns (not verbs!)
  /users           ✓  (not /getUsers)
  /users/123       ✓  (not /getUserById?id=123)
  /users/123/posts ✓  (nested resources)

HTTP methods define the action:
  GET    /users          → list users
  POST   /users          → create user
  GET    /users/123      → get user 123
  PUT    /users/123      → replace user 123 (full update)
  PATCH  /users/123      → partial update user 123
  DELETE /users/123      → delete user 123

Use plural nouns:
  /users  not /user
  /posts  not /post
  /items  not /item

Versioning:
  /api/v1/users  → version in URL path (most common)
  Header: Accept: application/vnd.api+json;version=1  → header versioning

HTTP Status Codes

2xx Success:
  200 OK           — GET success, PUT/PATCH success
  201 Created      — POST success (include Location header)
  204 No Content   — DELETE success, PATCH with no body
  206 Partial Content — paginated response

4xx Client Errors:
  400 Bad Request        — malformed request, validation error
  401 Unauthorized       — not authenticated (missing/invalid token)
  403 Forbidden          — authenticated but not authorized
  404 Not Found          — resource doesn't exist
  409 Conflict           — duplicate resource (unique constraint)
  422 Unprocessable      — validation failed (preferred over 400 for validation)
  429 Too Many Requests  — rate limited

5xx Server Errors:
  500 Internal Server Error — generic server error
  502 Bad Gateway          — upstream service failed
  503 Service Unavailable  — server down/overloaded
  504 Gateway Timeout      — upstream timeout

Response Format Conventions

{
  "data": {
    "id": 1,
    "name": "Alice Chen",
    "email": "alice@example.com",
    "createdAt": "2026-05-29T10:00:00Z"
  }
}

// List response with pagination
{
  "data": [...],
  "meta": {
    "total": 500,
    "page": 1,
    "perPage": 20,
    "totalPages": 25
  },
  "links": {
    "self": "/api/v1/users?page=1",
    "next": "/api/v1/users?page=2",
    "last": "/api/v1/users?page=25"
  }
}

// Error response
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Request validation failed",
    "details": [
      { "field": "email", "message": "Invalid email format" },
      { "field": "age", "message": "Must be 13 or older" }
    ]
  }
}

Authentication Patterns

JWT Bearer Token (most common for APIs):
  Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

API Keys (for service-to-service):
  X-API-Key: my-api-key-here
  OR: ?api_key=xxx (less secure, shows in logs)

OAuth 2.0 (for user-facing apps with third-party auth):
  Authorization Code Flow → access_token + refresh_token

Best practices:
  - Short-lived access tokens (15 min)
  - Refresh tokens for "remember me"
  - Always use HTTPS
  - Rotate API keys periodically

Filtering, Sorting, Pagination

Filtering:
  GET /users?status=active&role=admin
  GET /posts?author_id=123&published=true

Sorting:
  GET /users?sort=name&order=asc
  GET /posts?sort=-created_at  (minus = descending)

Pagination:
  Offset (simple):
    GET /users?page=2&per_page=20
    (skip = (page-1) * per_page)

  Cursor (scalable for large datasets):
    GET /users?cursor=eyJpZCI6MTAwfQ&limit=20
    Response includes next_cursor for next page

  Keyset (fastest for ordered data):
    GET /users?after_id=1000&limit=20

Field selection (reduce payload):
  GET /users?fields=id,name,email

Rate Limiting Headers

Response headers for rate limiting:
  X-RateLimit-Limit: 100       # max requests per window
  X-RateLimit-Remaining: 87    # remaining requests
  X-RateLimit-Reset: 1717000000  # Unix timestamp when limit resets
  Retry-After: 30              # seconds to wait (on 429 response)

OpenAPI / Swagger Documentation

openapi: 3.1.0
info:
  title: TechPulse API
  version: 1.0.0

paths:
  /users:
    get:
      summary: List users
      parameters:
        - name: page
          in: query
          schema: { type: integer, default: 1 }
      responses:
        '200':
          description: List of users
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserList'

    post:
      summary: Create user
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateUserRequest'
      responses:
        '201': { description: User created }
        '422': { description: Validation error }

REST API design in 2026: use resource-centric URLs, correct HTTP methods and status codes, consistent JSON response format, versioning from day one, and OpenAPI documentation. The Swagger/OpenAPI spec drives code generation, documentation, and testing. Design your API as if external developers will use it — they might someday.

✍️ Leave a Comment

Your email address will not be published. Required fields are marked *

🌐 Read in:🇬🇧 English🇩🇪 Deutsch🇧🇷 Português🇸🇦 العربية🇮🇳 हिन्दी🇧🇩 বাংলা