What is HTTP?
HTTP (HyperText Transfer Protocol) is how browsers and servers communicate:
- Request/response model
- Stateless protocol
- Text-based (mostly)
HTTP Requests
Structure
METHOD /path HTTP/1.1
Headers
[Body]
HTTP Methods
GET Retrieve data
POST Create new resource
PUT Replace entire resource
PATCH Update part of resource
DELETE Remove resource
HEAD GET without body (check existence)
OPTIONS Get allowed methods
Common Usage
# Get a resource
GET /users/123
# Create a resource
POST /users
{"name": "Alice"}
# Update a resource
PUT /users/123
{"name": "Alice", "email": "alice@example.com"}
# Partial update
PATCH /users/123
{"email": "newemail@example.com"}
# Delete a resource
DELETE /users/123
HTTP Responses
Status Codes
2xx Success:
200 OK Request succeeded
201 Created Resource created
204 No Content Success, no body
3xx Redirection:
301 Moved Permanently
302 Found (temporary redirect)
304 Not Modified (cached)
4xx Client Error:
400 Bad Request Invalid request
401 Unauthorized Auth required
403 Forbidden Auth valid, not allowed
404 Not Found Resource doesn't exist
422 Unprocessable Validation error
429 Too Many Requests (rate limited)
5xx Server Error:
500 Internal Error Server problem
502 Bad Gateway Upstream error
503 Service Unavailable
504 Gateway Timeout
Headers
Common Request Headers
Authorization: Bearer token123
Content-Type: application/json
Accept: application/json
User-Agent: MyApp/1.0
Common Response Headers
Content-Type: application/json
Content-Length: 1234
Cache-Control: max-age=3600
X-RateLimit-Remaining: 95
REST Principles
Resources and URLs
/users Collection of users
/users/123 Single user
/users/123/orders User's orders
/orders/456 Single order
CRUD Mapping
Create → POST /users
Read → GET /users/123
Update → PUT/PATCH /users/123
Delete → DELETE /users/123
List → GET /users
Statelessness
Each request contains all information needed. No session state on server.
Making Requests
cURL
# GET
curl https://api.example.com/users
# POST with JSON
curl -X POST https://api.example.com/users \
-H "Content-Type: application/json" \
-d '{"name": "Alice"}'
# With auth
curl https://api.example.com/protected \
-H "Authorization: Bearer token123"
# See response headers
curl -i https://api.example.com/users
Python
import requests
# GET
response = requests.get("https://api.example.com/users")
data = response.json()
# POST
response = requests.post(
"https://api.example.com/users",
json={"name": "Alice"},
headers={"Authorization": "Bearer token123"}
)
# Check status
if response.status_code == 201:
print("Created!")
JavaScript
// GET
const response = await fetch("https://api.example.com/users");
const data = await response.json();
// POST
const response = await fetch("https://api.example.com/users", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer token123"
},
body: JSON.stringify({ name: "Alice" })
});
Query Parameters
For filtering, pagination, sorting:
GET /users?status=active
GET /users?page=2&limit=10
GET /users?sort=name&order=asc
GET /users?search=alice
Request Bodies
JSON (Most Common)
POST /users HTTP/1.1
Content-Type: application/json
{
"name": "Alice",
"email": "alice@example.com"
}
Form Data
POST /login HTTP/1.1
Content-Type: application/x-www-form-urlencoded
username=alice&password=secret
Multipart (File Upload)
POST /upload HTTP/1.1
Content-Type: multipart/form-data; boundary=----Boundary
------Boundary
Content-Disposition: form-data; name="file"; filename="doc.pdf"
Content-Type: application/pdf
[file contents]
------Boundary--
Authentication
API Key
# In header
Authorization: ApiKey sk-xxx123
# Or in query parameter
GET /api/data?api_key=sk-xxx123
Bearer Token (JWT, OAuth)
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
Basic Auth
Authorization: Basic base64(username:password)
Error Handling
Check Status Code
response = requests.get(url)
if response.status_code == 200:
data = response.json()
elif response.status_code == 404:
print("Not found")
elif response.status_code == 401:
print("Unauthorized")
else:
print(f"Error: {response.status_code}")
Parse Error Response
if not response.ok:
error = response.json()
print(f"Error: {error.get('message')}")
Best Practices
Use Appropriate Methods
# Don't
GET /deleteUser?id=123
# Do
DELETE /users/123
Return Appropriate Status Codes
201 for created (not 200)
204 for delete success (not 200)
400 for validation errors (not 500)
Use Consistent Naming
# Consistent
/users
/users/{id}
/users/{id}/orders
# Inconsistent
/getUsers
/user/{id}
/orders_for_user/{id}
Version Your APIs
/api/v1/users
/api/v2/users
Provide Useful Errors
{
"error": "validation_error",
"message": "Email is invalid",
"details": {
"field": "email",
"value": "not-an-email"
}
}
Common Patterns
Pagination
{
"data": [...],
"meta": {
"page": 1,
"per_page": 20,
"total": 100,
"total_pages": 5
},
"links": {
"next": "/users?page=2",
"prev": null
}
}
Filtering
GET /orders?status=completed&date_from=2025-01-01
Expanding Related Data
GET /users/123?expand=orders,profile
Conclusion
HTTP/REST fundamentals:
- Methods: GET, POST, PUT, PATCH, DELETE
- Status codes tell you what happened
- Headers carry metadata
- JSON is the standard format
- REST = resources + HTTP methods
Master these and you can work with any web API.
Next: Data Formats - JSON, XML, CSV, and more