<!-- Example 1: Get all users -->
GET /api/users
Output: Returns a JSON list of all users from the server database.
<!-- Example 2: Get user by ID -->
GET /api/users/1 <!-- Retrieves user with ID = 1 -->
Output: JSON object for user ID 1.
<!-- Example 3: Create user -->
POST /api/users
Content-Type: application/json
{
"name": "Alice", <!-- New user's name -->
"email": "alice@example.com" <!-- New user's email -->
}
Output: Confirmation with the new user ID and status 201 Created.
<!-- Example 4: Update user -->
PUT /api/users/1
Content-Type: application/json
{
"name": "Alice Updated", <!-- Updated name -->
"email": "alice@newdomain.com" <!-- Updated email -->
}
Output: Confirms update with a success message or HTTP 200 OK.
<!-- Example 5: Delete user -->
DELETE /api/users/1 <!-- Deletes user with ID = 1 -->
Output: Returns success or 204 No Content.
<!-- Example 6: Filter users with role 'admin' -->
GET /api/users?role=admin
Output: Returns a list of users who are admins.
<!-- Example 7: Get products in 'electronics' category -->
GET /api/products?category=electronics
Output: List of electronics products.
<!-- Example 8: Update entire user object -->
PUT /api/users/1
Content-Type: application/json
{
"name": "Bob", <!-- New name -->
"email": "bob@example.com" <!-- New email -->
}
Output: Replaces the entire user data with new info.
<!-- Example 9: Update only user name -->
PATCH /api/users/1
Content-Type: application/json
{
"name": "Bob Patch" <!-- Only updating name -->
}
Output: Updates only the name field of the user.
<!-- Example 10: JSON structure returned -->
{
"id": 1, <!-- Unique user ID -->
"name": "Jane Doe", <!-- User's full name -->
"email": "jane@example.com" <!-- Email address -->
}
Output: A JSON object with user details.
<!-- Example 11: Auth header with Bearer token -->
GET /api/profile
Authorization: Bearer <your-token-here>
Output: User profile data if token is valid; else 401 Unauthorized.
<!-- Example 12: Basic authentication -->
GET /api/profile
Authorization: Basic dXNlcjpwYXNzd29yZA== <!-- base64(user:password) -->
Output: Same as above with Basic auth scheme.
<!-- Example 13: Paginated results -->
GET /api/users?page=2&limit=5
Output: Returns 5 users from page 2.
<!-- Example 14: Response with metadata -->
{
"data": [...], <!-- Paginated user data -->
"page": 2,
"limit": 5,
"total": 50 <!-- Total number of users -->
}
Output: Data + metadata about pagination.
<!-- Example 15: User not found -->
GET /api/users/999
Output:
{
"error": "User not found", <!-- Error message -->
"status": 404 <!-- HTTP status code -->
}
<!-- Example 16: Invalid input -->
POST /api/users
Content-Type: application/json
{
"email": "invalid" <!-- Missing name, invalid email -->
}
Output: Returns 400 Bad Request with validation error.
<!-- Good: -->
GET /api/products <!-- Refers to a collection of products -->
<!-- Bad: -->
GET /api/getProducts <!-- Verb used, not RESTful -->
<!-- Good: Get reviews for a product -->
GET /api/products/42/reviews
Output: Reviews for product with ID 42.
<!-- Example: Upload an image file -->
POST /api/upload
Content-Type: multipart/form-data
file = <your-file.jpg>
Output: Upload success message with file path or URL.
<!-- Example: Product with reviews -->
GET /api/products/42?include=reviews
Output:
{
"id": 42,
"name": "Smartphone",
"reviews": [
{ "user": "A", "comment": "Great!" },
{ "user": "B", "comment": "Okay!" }
]
}
<!-- Example 1: Version in URL -->
GET /api/v1/products
<!-- Example 2: Version in request header -->
GET /api/products
Accept: application/vnd.api.v2+json
Output: Returns data according to requested API version.
JSON (application/json) <!-- Most widely used -->
XML (application/xml) <!-- Legacy or specific needs -->
HTML (text/html) <!-- For browsers -->
CSV (text/csv) <!-- For exporting data -->
Accept: application/json <!-- Ask for JSON -->
Accept: application/xml <!-- Ask for XML -->
Output: API formats data based on header.
<!-- Example: Sort products by price ascending -->
GET /api/products?sort=price
<!-- Example: Sort descending -->
GET /api/products?sort=-price
Output: Sorted list of products by price.
<!-- Example: A user object with links -->
{
"id": 1,
"name": "Alice",
"links": [
{ "rel": "self", "href": "/api/users/1" },
{ "rel": "orders", "href": "/api/users/1/orders" }
]
}
Output: Clients get URLs to navigate resources dynamically.
<!-- Example: Create multiple users -->
POST /api/users/bulk
[
{ "name": "Alice", "email": "alice@example.com" },
{ "name": "Bob", "email": "bob@example.com" }
]
Output: Array of created users with IDs.
<!-- Example: Filter users by status -->
GET /api/users?status=active
<!-- Example: Filter products by category and price range -->
GET /api/products?category=books&min_price=10&max_price=50
Output: Only items matching the filters are returned.
<!-- Example: 404 Not Found -->
HTTP/1.1 404 Not Found
Content-Type: application/json
{
"error": "User not found",
"code": 404
}
HTTP/1.1 400 Bad Request
{
"error": "Invalid email address"
}
Output: Client sees friendly error description with appropriate status.
GET /api/user/5 <!-- Safe and idempotent -->
PUT /api/user/5 <!-- Replacing resource = idempotent -->
DELETE /api/user/5 <!-- Repeated deletes still delete -->
POST /api/user <!-- Creates a new user each time = not idempotent -->
Output: Ensures safe repeated calls for non-POST methods.
<!-- Example: Bearer Token -->
Authorization: Bearer <token_here>
Basic Authentication: Authorization: Basic <base64_credentials>
API Keys: X-API-Key: <your_key>
Output: API grants or denies access based on credentials.
<!-- Example: URL versioning -->
GET /api/v1/users
GET /api/v2/users
<!-- Example: Header versioning -->
Accept: application/vnd.example.v1+json
Output: Clients can choose which API version to use, preventing breaking changes.
<!-- Example: Cache-Control header -->
Cache-Control: max-age=3600
<!-- Example: ETag for conditional requests -->
ETag: "123456789"
Output: Clients cache responses, reducing server load and improving speed.
<!-- Example: Include links in responses -->
{
"user": { "id": 1, "name": "Alice" },
"links": {
"self": "/api/users/1",
"orders": "/api/users/1/orders"
}
}
Output: Clients navigate API dynamically via links instead of hardcoded URLs.
<!-- Example: Response headers for rate limit -->
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 750
X-RateLimit-Reset: 1609459200
<!-- When limit exceeded -->
HTTP/1.1 429 Too Many Requests
Output: Clients know usage limits and wait or retry after cooldown.
<!-- Good: Nouns representing resources -->
GET /api/users
POST /api/orders
<!-- Bad: Verbs in URLs -->
GET /api/getUsers
POST /api/createOrder
GET /api/users <!-- preferred -->
GET /api/user <!-- avoid singular -->
Output: Clean, intuitive URLs make API easier to use and maintain.
<!-- Use HTTPS to encrypt data -->
<!-- Implement Authentication and Authorization -->
Authorization: Bearer <token>
<!-- Input validation to prevent injection attacks -->
Output: Secure communication and access control protect API and data integrity.
<!-- PUT Example: Replace user info -->
PUT /api/users/1
{
"name": "John",
"email": "john@example.com"
}
<!-- PATCH Example: Update only email -->
PATCH /api/users/1
{
"email": "newemail@example.com"
}
Output: PUT overwrites all fields; PATCH modifies specified fields only.
<!-- Example: 404 Not Found -->
HTTP/1.1 404 Not Found
{
"error": "User not found"
}
<!-- Example: 400 Bad Request -->
HTTP/1.1 400 Bad Request
{
"error": "Invalid user ID"
}
Output: Clients understand error type and reason to handle gracefully.
<!-- Example: CORS response header -->
Access-Control-Allow-Origin: https://example.com
<!-- Allows only specified origins to access the API -->
Output: Prevents unauthorized websites from making requests to your API.
<!-- Example: OpenAPI Specification (Swagger) -->
openapi: 3.0.0
info:
title: User API
version: 1.0.0
paths:
/users:
get:
summary: Get all users
responses:
'200':
description: Successful response
Output: Enables developers to understand and use the API easily.
<!-- URL versioning -->
GET /v1/users
<!-- Header versioning -->
Accept: application/vnd.example.v1+json
<!-- Query parameter versioning -->
GET /users?version=1
Output: Enables smooth upgrades and backward compatibility.
<!-- Cache-Control header -->
Cache-Control: max-age=3600
<!-- ETag for resource validation -->
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
Output: Reduces server load and improves client responsiveness.
<!-- Idempotent HTTP methods: GET, PUT, DELETE -->
<!-- Multiple identical requests have same effect as one request -->
PUT /users/1
{
"email": "new@example.com"
}
Output: Prevents unintended changes or duplication from retries.
<!-- Limit requests per user/IP -->
X-Rate-Limit-Limit: 1000
X-Rate-Limit-Remaining: 750
X-Rate-Limit-Reset: 3600
<!-- Return 429 Too Many Requests when limit exceeded -->
HTTP/1.1 429 Too Many Requests
{
"error": "Rate limit exceeded"
}
Output: Protects API from abuse and ensures fair usage.
<!-- Postman: GUI tool for manual API testing -->
<!-- curl: Command line tool for API requests -->
curl -X GET https://api.example.com/users
<!-- Automated testing frameworks -->
JUnit, Mocha, RestAssured
Output: Helps ensure API reliability and correctness.
<!-- Basic Authentication -->
Authorization: Basic base64(username:password)
<!-- Bearer Token Authentication -->
Authorization: Bearer your_jwt_token
<!-- OAuth 2.0 -->
POST /oauth/token
grant_type=client_credentials
Output: Secures API access by verifying client identity.
<!-- Response example with HATEOAS links -->
{
"userId": 1,
"name": "John Doe",
"links": [
{ "rel": "self", "href": "/users/1" },
{ "rel": "orders", "href": "/users/1/orders" }
]
}
Output: Enables clients to navigate API dynamically via hyperlinks.
<!-- OpenAPI / Swagger -->
swagger: "2.0"
info:
version: "1.0.0"
title: Sample API
<!-- Example endpoint -->
paths:
/users:
get:
summary: Returns list of users
responses:
'200':
description: successful operation
Output: Provides clear, standardized API specs for developers.
<!-- Injection attacks -->
Use parameterized queries to prevent SQL injection
<!-- Broken authentication -->
Implement strong authentication and token expiration
<!-- Data exposure -->
Use HTTPS and encrypt sensitive data
Output: Improves API security and protects user data.
<!-- Query parameters for pagination -->
GET /users?page=2&limit=20
<!-- Response example with pagination info -->
{
"page": 2,
"limit": 20,
"totalPages": 5,
"users": [ ... ]
}
Output: Efficiently handles large datasets by returning data in chunks.
<!-- PUT replaces the entire resource -->
PUT /users/1
{
"name": "Jane Doe",
"email": "jane@example.com"
}
<!-- PATCH updates partial resource data -->
PATCH /users/1
{
"email": "jane.doe@example.com"
}
Output: PUT replaces full data; PATCH modifies parts of data.
<!-- URI Versioning -->
GET /v1/users
GET /v2/users
<!-- Header Versioning -->
GET /users
Header: Accept-version: v1
Output: Maintains backward compatibility by managing API versions.
<!-- Example CORS headers -->
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: Content-Type, Authorization
Output: Enables controlled access to resources from different domains.
<!-- Example error response -->
{
"error": {
"code": 404,
"message": "Resource not found",
"details": "User with id 123 does not exist"
}
}
Output: Provides clear and consistent error messages for clients.
<!-- Use nouns to represent resources -->
GET /users
GET /users/123/orders
<!-- Avoid verbs in URL -->
Avoid: /getUser or /createOrder
<!-- Use lowercase and hyphens -->
GET /order-items
Output: Creates clear, intuitive, and consistent API endpoints.
<!-- Throttling limits the number of API requests per time period -->
Example: 1000 requests per hour per user
<!-- HTTP header to indicate rate limit -->
X-Rate-Limit-Limit: 1000
X-Rate-Limit-Remaining: 750
X-Rate-Limit-Reset: 3600
Output: Prevents abuse and ensures fair usage of API resources.
<!-- Use HTTP cache headers -->
Cache-Control: max-age=3600
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
<!-- Example response -->
GET /users/1
Response with Cache-Control header to reduce server load
Output: Improves API performance by reducing unnecessary requests.
<!-- Acts as a single entry point for multiple backend services -->
<!-- Handles request routing, authentication, rate limiting -->
Example:
Client > API Gateway > Microservices
API Gateway adds security and monitoring capabilities.
Output: Simplifies client interaction and centralizes cross-cutting concerns.
<!-- OAuth 2.0 flow example -->
1. Client requests authorization
2. Authorization server issues access token
3. Client uses token in API requests:
Authorization: Bearer ACCESS_TOKEN
<!-- Protects resources without sharing user credentials -->
Output: Enables secure delegated access to resources.
<!-- Methods that can be called multiple times without different effects -->
PUT /users/1
DELETE /users/1
GET /users/1
<!-- Important for reliable retries and safe operations -->
Output: Ensures consistency and reliability in REST operations.