Skip to content
BytePath v0.0.35

API Design and REST Principles

API learning path · Step 1Available

Design APIs that are predictable, scalable and easy to integrate with proper HTTP semantics and versioning.

Difficulty
Intermediate
Time
85 min
Practice
REST API design exercise
Assessment
Knowledge check

Before you start

Who is this for?

For developers, DevOps engineers and architects who build or integrate APIs.

Prerequisites

  • Understanding of HTTP basics
  • Familiarity with JSON
  • Basic networking concepts

What you'll be able to do

  • Apply REST principles correctly
  • Choose appropriate HTTP methods and status codes
  • Design consistent API endpoints
  • Version APIs responsibly
  • Implement rate limiting and caching
  • Secure APIs with authentication

Practical outcome

You can design a REST API that developers find intuitive to use and that scales reliably.

APIs are the contracts between services. Good API design makes integration seamless; poor design causes frustration and bugs. REST (Representational State Transfer) is the most common style for web APIs.

REST is an architectural style, not a strict protocol. It emphasizes:

  • Client-Server: Clear separation of concerns.
  • Stateless: Each request contains all information needed. Server does not store client context.
  • Uniform Interface: Consistent resource identification and manipulation.
  • Cacheable: Responses should indicate if they can be cached.

A truly RESTful API is more than using HTTP correctly; it follows these principles.

Resources are nouns (things), not verbs (actions). Endpoints identify resources; HTTP methods perform actions on them.

✓ Good: /users, /orders, /products
✗ Bad: /getUserList, /createOrder, /deleteProduct
✓ Good: GET /users/5
✗ Bad: GET /getUser/5
✓ Good: POST /orders
✗ Bad: POST /createOrder

Endpoint structure typically follows:

/v1/resource
/v1/resource/{id}
/v1/resource/{id}/subresource

Each method has a specific meaning. Using the wrong method confuses clients and can cause caching issues.

Method Semantics Idempotent Safe Example
GET Retrieve resource Yes Yes GET /users/5 returns user
POST Create new resource No No POST /users creates user
PUT Replace entire resource Yes No PUT /users/5 replaces user
PATCH Partial update Not guaranteed No PATCH /users/5 updates name only
DELETE Remove resource Yes No DELETE /users/5 deletes user

Idempotent means repeating the same request has the same intended effect as making it once. Safe means it does not request a state change. GET is safe and idempotent; PUT and DELETE are idempotent by HTTP semantics. PATCH is not guaranteed idempotent, though an API can define a particular patch operation so that repeating it has the same effect.

The response status communicates success or failure. Clients should handle status codes, not guess from response content.

Range Meaning Examples
2xx Success 200 OK, 201 Created, 204 No Content
3xx Redirect 301 Moved Permanently, 304 Not Modified
4xx Client error 400 Bad Request, 401 Unauthorized, 404 Not Found
5xx Server error 500 Internal Server Error, 503 Service Unavailable

Common mistakes:

  • Always returning 200, even on error. Clients cannot detect problems.
  • Returning 500 for validation errors (should be 400).
  • Returning 200 for “resource not found” (should be 404).

APIs typically use JSON. Include version in the header or URL.

Request:

POST /v1/users
Content-Type: application/json
Authorization: Bearer token123
{
"name": "Alice",
"email": "alice@example.com",
"role": "admin"
}

Response (success):

HTTP/1.1 201 Created
Content-Type: application/json
{
"id": 42,
"name": "Alice",
"email": "alice@example.com",
"role": "admin",
"created_at": "2026-09-18T08:41:00Z"
}

Response (error):

HTTP/1.1 400 Bad Request
Content-Type: application/json
{
"error": "validation_error",
"message": "Email format is invalid",
"details": {
"field": "email",
"value": "alice@invalid"
}
}

Large result sets must be paginated to prevent loading entire databases.

GET /v1/orders?limit=20&offset=0
GET /v1/orders?page=1&page_size=20
GET /v1/orders?cursor=abc123&limit=20

Response includes metadata:

{
"data": [...],
"pagination": {
"total": 1000,
"limit": 20,
"offset": 0,
"pages": 50
}
}

Cursor-based pagination is best for large datasets because offsets become slow as data grows.

APIs change. Versioning allows clients to continue using old versions while you develop new ones.

Strategies:

  • URL path: /v1/users, /v2/users
  • Header: Accept: application/json; version=2
  • Query parameter: /users?version=2

URL path is most common and explicit. Never remove old versions abruptly; deprecate gradually with warnings.

Rate limiting prevents abuse. Caching reduces server load.

HTTP/1.1 200 OK
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
X-RateLimit-Reset: 1695022860
Cache-Control: public, max-age=3600
ETag: "abc123"
{
"data": [...]
}

Clients check X-RateLimit-Remaining and back off before hitting the limit. Cache-Control tells clients how long to cache. ETag enables conditional requests (If-None-Match).

APIs often expose sensitive data. Security is critical.

  • Authentication: Only authenticated users access the API. Use OAuth2, API keys or JWT.
  • Authorization: Authenticated users can only access their own data. Use role-based or attribute-based access control.
  • Encryption: Use HTTPS everywhere. Sensitive data in request bodies and responses must be encrypted.
  • Input validation: Reject invalid input before processing.
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Never store plain-text passwords or API keys. Use hashing and secrets managers.

  • Inconsistent endpoint naming. Mix of singular/plural, /get vs GET.
  • Wrong HTTP methods. POST when GET should be used.
  • Returning 200 on errors. Status codes communicate intent.
  • No pagination. Large queries returning millions of rows.
  • No API documentation. Developers have to reverse-engineer your API.
  • Breaking changes without versioning. Existing clients break.
  • No rate limiting. Bots abuse the API.
  • Storing secrets in logs. API keys and tokens exposed.
  • Design RESTful endpoints following HTTP semantics;
  • Choose appropriate status codes and error formats;
  • Implement pagination, versioning and rate limiting;
  • Secure APIs with authentication and authorization;