Diagrams: API Basics¶
REST API Architecture¶
A REST API sits between the client and the database. It receives HTTP requests, processes them, and returns JSON responses.
flowchart LR
subgraph CLIENTS ["Clients"]
PY["Python script<br/>requests.get()"]
WEB["Web browser<br/>fetch()"]
MOB["Mobile app<br/>HTTP client"]
end
subgraph API ["REST API Server"]
ROUTER["Router<br/>Match URL to handler"]
AUTH["Auth middleware<br/>Verify token/key"]
HANDLER["Route handler<br/>Business logic"]
SERIAL["Serializer<br/>Dict to JSON"]
end
subgraph DATA ["Data Layer"]
DB[("Database<br/>PostgreSQL")]
CACHE[("Cache<br/>Redis")]
end
PY -->|"HTTP request"| ROUTER
WEB -->|"HTTP request"| ROUTER
MOB -->|"HTTP request"| ROUTER
ROUTER --> AUTH
AUTH --> HANDLER
HANDLER --> DB
HANDLER --> CACHE
DB --> SERIAL
SERIAL -->|"JSON response"| PY
SERIAL -->|"JSON response"| WEB
SERIAL -->|"JSON response"| MOB
style CLIENTS fill:#4a9eff,stroke:#2670c2,color:#fff
style API fill:#cc5de8,stroke:#9c36b5,color:#fff
style DATA fill:#51cf66,stroke:#27ae60,color:#fff
CRUD to HTTP Method Mapping¶
REST maps the four database operations (Create, Read, Update, Delete) to HTTP methods and URL patterns.
flowchart TD
subgraph CRUD ["Database Operation"]
CREATE["CREATE<br/>Insert new row"]
READ["READ<br/>Select rows"]
UPDATE["UPDATE<br/>Modify row"]
DELOP["DELETE<br/>Remove row"]
end
subgraph HTTP ["HTTP Method + URL"]
POST["POST /users<br/>Body: {name, email}"]
GET1["GET /users<br/>List all"]
GET2["GET /users/42<br/>Get one"]
PUT["PUT /users/42<br/>Body: {name, email}"]
DEL["DELETE /users/42<br/>No body"]
end
subgraph RESPONSE ["Response"]
R201["201 Created<br/>{id: 43, name: ...}"]
R200L["200 OK<br/>[{id: 1}, {id: 2}, ...]"]
R200O["200 OK<br/>{id: 42, name: ...}"]
R200U["200 OK<br/>{id: 42, name: ...}"]
R204["204 No Content"]
end
CREATE --> POST --> R201
READ --> GET1 --> R200L
READ --> GET2 --> R200O
UPDATE --> PUT --> R200U
DELOP --> DEL --> R204
style CRUD fill:#ff922b,stroke:#e8590c,color:#fff
style HTTP fill:#4a9eff,stroke:#2670c2,color:#fff
style RESPONSE fill:#51cf66,stroke:#27ae60,color:#fff
API Request/Response Flow¶
Step-by-step sequence of a typical API call from Python using the requests library.
sequenceDiagram
participant Script as Python Script
participant Lib as requests library
participant API as API Server
participant Logic as Route Handler
Script->>Lib: requests.post(url, json=data, headers=headers)
Note over Lib: Serialize dict to JSON<br/>Add Content-Type header
Lib->>API: POST /users HTTP/1.1<br/>Authorization: Bearer eyJ...<br/>Content-Type: application/json<br/>{"name": "Alice", "email": "..."}
API->>API: Validate auth token
API->>Logic: Call create_user handler
Note over Logic: Validate input<br/>Insert into database<br/>Build response
Logic-->>API: {"id": 43, "name": "Alice"}
API-->>Lib: HTTP/1.1 201 Created<br/>Content-Type: application/json
Lib-->>Script: Response object
Note over Script: response.status_code → 201<br/>response.json() → {"id": 43, ...}
Authentication Token Flow¶
How bearer token authentication works: login once, then include the token with every request.
sequenceDiagram
participant Client as Python Client
participant API as API Server
participant DB as User Database
Note over Client: Step 1: Login to get a token
Client->>API: POST /auth/login<br/>{"username": "alice", "password": "s3cret"}
API->>DB: Verify credentials
DB-->>API: User found, password matches
Note over API: Generate JWT token<br/>Encode user ID + expiry
API-->>Client: 200 OK<br/>{"token": "eyJhbGci...", "expires_in": 3600}
Note over Client: Save the token
Note over Client: Step 2: Use token for API calls
Client->>API: GET /users/me<br/>Authorization: Bearer eyJhbGci...
Note over API: Decode token<br/>Verify signature<br/>Check expiry
API-->>Client: 200 OK<br/>{"id": 1, "name": "Alice", "role": "admin"}
Note over Client: Step 3: Token expires
Client->>API: GET /users/me<br/>Authorization: Bearer eyJhbGci...
Note over API: Token expired!
API-->>Client: 401 Unauthorized<br/>{"detail": "Token expired"}
Note over Client: Must login again<br/>to get a new token