🔗 API Design
APIs & REST Complete Cheatsheet
REST principles, HTTP methods, auth, design patterns, GraphQL comparison and OpenAPI.
📖 10 sections
⏱ 24 min read
✅ Quizzes included
🌙 Dark mode
01 REST Principles
REST
Representational State Transfer. Architectural style for web APIs. Stateless, client-server.
Resource
Everything is a resource (noun): users, products, orders, not verbs.
Stateless
Each request contains all info needed. Server stores NO session state.
Uniform Interface
Consistent API design. Resources identified by URL. Standard methods.
HATEOAS
Hypermedia as Engine of Application State. Responses include links to next actions.
Idempotent
Same request = same result. GET, PUT, DELETE are idempotent. POST is NOT.
Safe methods
No side effects. GET, HEAD, OPTIONS are safe. POST, PUT, DELETE are not.
Content negotiation
Client specifies format: Accept: application/json. Server responds accordingly.
RESTResource naming convention
# Good — nouns, plural, lowercase, hyphens
GET    /users              # list all users
GET    /users/123          # get user 123
POST   /users              # create user
PUT    /users/123          # replace user 123 (full)
PATCH  /users/123          # partial update user 123
DELETE /users/123          # delete user 123

GET    /users/123/orders   # user's orders (nested)
GET    /users/123/orders/456  # specific order of user

# Bad — verbs in URL, inconsistent naming
GET  /getUser?id=123   ❌
POST /createUser       ❌
GET  /user             ❌  (should be plural /users)
GET  /Users            ❌  (should be lowercase)
02 HTTP Methods & Status
MethodOperationIdempotentSafeBody
GETRead✅ Yes✅ YesNo
POSTCreate❌ No❌ NoYes
PUTReplace✅ Yes❌ NoYes
PATCHPartial update❌ Usually❌ NoYes
DELETEDelete✅ Yes❌ NoOptional
HEADLike GET, no body✅ Yes✅ YesNo
OPTIONSList allowed methods✅ Yes✅ YesNo
RESTHTTP status codes
1xx Informational
  100 Continue

2xx Success
  200 OK                  — GET success
  201 Created             — POST success (return new resource)
  204 No Content          — DELETE success (no body)
  206 Partial Content     — Range request (file download)

3xx Redirection
  301 Moved Permanently   — Update bookmarks
  302 Found               — Temporary redirect
  304 Not Modified        — Use cache (ETag match)

4xx Client Error
  400 Bad Request         — Invalid syntax, missing field
  401 Unauthorized        — Not authenticated (login first)
  403 Forbidden           — Authenticated but not allowed
  404 Not Found           — Resource doesn't exist
  409 Conflict            — Duplicate resource
  422 Unprocessable       — Valid syntax but semantic errors
  429 Too Many Requests   — Rate limit exceeded

5xx Server Error
  500 Internal Server Error — Unexpected server error
  502 Bad Gateway          — Upstream server error
  503 Service Unavailable  — Server down, maintenance
03 Request & Response
RESTRequest and Response format
# Request
POST /api/v1/users HTTP/1.1
Host: api.bitwithbite.com
Content-Type: application/json
Authorization: Bearer eyJhbGc...
Accept: application/json
X-Request-ID: abc123

{
  "name": "Ali Khan",
  "email": "ali@test.com",
  "role": "student"
}

# Response (201 Created)
HTTP/1.1 201 Created
Content-Type: application/json
Location: /api/v1/users/456

{
  "success": true,
  "data": {
    "id": 456,
    "name": "Ali Khan",
    "email": "ali@test.com",
    "createdAt": "2026-04-19T10:00:00Z"
  }
}

# Error response (422)
{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Invalid email format",
    "details": [{"field": "email", "message": "Must be valid email"}]
  }
}
04 Authentication
RESTAuthentication methods
# 1. API Key (simplest)
GET /api/data
Authorization: ApiKey your-api-key-here
# OR in header: X-API-Key: your-key

# 2. Basic Auth (username:password base64)
Authorization: Basic dXNlcjpwYXNzd29yZA==
# Decoded: user:password

# 3. Bearer Token / JWT (most common)
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

# JWT structure: header.payload.signature
# header:  {alg, typ}
# payload: {sub, name, role, exp, iat}
# signature: HMAC_SHA256(header+payload, secret)

# 4. OAuth 2.0 (delegated auth)
# Client requests token from Auth Server
# Grants: Authorization Code, Client Credentials, PKCE

# JWT in Node.js
const jwt = require('jsonwebtoken');
const token = jwt.sign({userId: 123, role: 'admin'}, SECRET, {expiresIn: '7d'});
const decoded = jwt.verify(token, SECRET);
Refresh tokens
Long-lived token to get new access token. Store securely.
Token expiry
Short-lived access tokens (15min-1hr). Reduces exposure if stolen.
PKCE
Proof Key for Code Exchange. Secure OAuth for SPAs/mobile apps.
05 API Design Best Practices
RESTAPI design best practices
# Versioning — always version your API
GET /api/v1/users    # URL versioning (most common)
GET /api/users       # with header: Accept: application/vnd.api.v2+json

# Pagination
GET /users?page=1&limit=20&sort=name&order=asc
# Response:
{
  "data": [...],
  "pagination": {
    "page": 1, "limit": 20, "total": 250,
    "pages": 13, "next": "/users?page=2&limit=20"
  }
}

# Cursor-based pagination (better for large datasets)
GET /posts?cursor=abc123&limit=20

# Filtering, sorting, field selection
GET /users?role=admin&age[gte]=18&sort=-createdAt&fields=name,email

# Rate limiting response headers
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 995
X-RateLimit-Reset: 1713600000

# Consistent error format (always!)
{ error: { code, message, details, requestId } }
06 REST vs GraphQL
RESTREST vs GraphQL
REST:
  ✅ Simple, widely understood
  ✅ Great HTTP caching
  ✅ Easy to reason about
  ❌ Over-fetching (too many fields)
  ❌ Under-fetching (multiple requests)
  ❌ Multiple endpoints per resource type

GraphQL:
  ✅ Single endpoint: POST /graphql
  ✅ Request exactly what you need (no over/under-fetching)
  ✅ Strongly typed schema
  ✅ Real-time via Subscriptions
  ❌ Harder caching
  ❌ More complex queries
  ❌ N+1 problem (use DataLoader)

# GraphQL query
query {
  user(id: "123") {
    name
    email
    orders {
      id
      total
      items { name, price }
    }
  }
}

# REST equivalent might need:
GET /users/123
GET /users/123/orders
GET /orders/456/items  # for each order
07 API Security
BASHTesting APIs
# cURL
curl https://api.example.com/users
curl -X POST -H 'Content-Type: application/json' \
     -H 'Authorization: Bearer token' \
     -d '{"name":"Ali"}' https://api.example.com/users
curl -I https://api.example.com/users   # headers only
curl -v https://api.example.com/users   # verbose

# HTTPie (simpler than cURL)
http GET api.example.com/users
http POST api.example.com/users name=Ali email=ali@test.com

# Automated testing (Jest + supertest)
describe('POST /users', () => {
  it('creates a user', async () => {
    const res = await request(app)
      .post('/api/users')
      .set('Authorization', `Bearer ${token}`)
      .send({ name: 'Ali', email: 'ali@test.com' });

    expect(res.status).toBe(201);
    expect(res.body.data.name).toBe('Ali');
  });
});

# Python requests
import requests
response = requests.get('https://api.example.com/users',
                        headers={'Authorization': 'Bearer token'})
data = response.json()
08 Testing APIs
RESTAPI Documentation (OpenAPI/Swagger)
# openapi.yaml
openapi: 3.0.0
info:
  title: BitWithBite API
  version: 1.0.0

paths:
  /users:
    get:
      summary: List all users
      parameters:
        - name: page
          in: query
          schema: { type: integer, default: 1 }
      responses:
        '200':
          description: List of users
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items: { $ref: '#/components/schemas/User' }
    post:
      summary: Create user
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: '#/components/schemas/CreateUser' }
      responses:
        '201': { description: User created }
        '422': { description: Validation error }
09 API Documentation
❓ Quiz 1
Which HTTP method is idempotent and safe?
GET is both safe (no side effects) and idempotent (same result every time). PUT and DELETE are idempotent but not safe. POST is neither. PATCH is usually neither.
❓ Quiz 2
What HTTP status code should a successful resource creation return?
201 Created is the correct status for successful POST/resource creation. Include a Location header pointing to the new resource. 200 OK is for successful GETs. 204 No Content is for successful DELETEs with no response body.