rest - dwilson2547/wiki_demo GitHub Wiki
-
REST (Representational State Transfer) Explained in Detail
- 1. What is REST?
- 2. Six Constraints of REST
- 3. RESTful API Design Principles
- 4. HATEOAS (Hypermedia as the Engine of Application State)
- 5. REST vs. SOAP vs. GraphQL vs. gRPC
- 6. REST API Example: Blog System
- 7. REST API Authentication and Authorization
- 8. REST API Documentation Tools
- 9. REST API Testing Tools
- 10. Building a REST API: Example with Node.js and Express
- 11. Best Practices for REST API Design
- 12. REST API Frameworks and Libraries
- 13. REST API Example: FastAPI (Python)
- 14. REST API Performance Optimization
- 15. REST API Security Best Practices
- 16. REST API Testing Strategies
- 17. REST API Deployment
- 18. REST API Monitoring and Logging
- 19. REST API Evolution: Trends and Future
- 20. Summary
REST (Representational State Transfer) is an architectural style for designing networked applications. It relies on stateless, client-server communication using HTTP/HTTPS and standardizes how resources are identified, addressed, and manipulated through URI paths, HTTP methods, and representations (e.g., JSON, XML).
REST is not a protocol or standard but a set of constraints that, when followed, create scalable, maintainable, and interoperable APIs.
RESTful APIs must adhere to these six architectural constraints:
-
Separation of Concerns:
- Client: Handles the user interface and user experience.
- Server: Manages data storage and business logic.
- Example: A web browser (client) interacts with a backend API (server).
- No Client Context: Each request from the client must contain all the information needed to process it.
- Session State: Stored entirely on the client (e.g., cookies, tokens).
- Example: Authentication tokens (JWT) are sent with every request.
-
Responses Must Define Cacheability:
- Use HTTP headers like
Cache-Control
,ETag
, andLast-Modified
to control caching.
- Use HTTP headers like
-
Example:
Cache-Control: max-age=3600
- Tells clients to cache the response for 1 hour.
REST APIs must provide a consistent way to interact with resources using:
-
Resource Identification in URIs:
- Use nouns (not verbs) in endpoints (e.g.,
/users
,/users/123
).
- Use nouns (not verbs) in endpoints (e.g.,
-
Resource Manipulation via Representations:
- Clients interact with resources using standard HTTP methods (GET, POST, PUT, DELETE).
-
Self-Descriptive Messages:
- Responses include metadata (e.g.,
Content-Type: application/json
).
- Responses include metadata (e.g.,
-
HATEOAS (Hypermedia as the Engine of Application State):
- Responses include hypermedia links to related resources.
- Example:
{ "id": 123, "name": "Alice", "links": [ { "rel": "self", "href": "/users/123" }, { "rel": "friends", "href": "/users/123/friends" } ] }
-
Intermediary Servers:
- Proxies, gateways, or load balancers can be inserted between client and server without affecting interactions.
- Example: A CDN caches responses to improve performance.
-
Server Can Extend Client Functionality:
- Servers can send executable code (e.g., JavaScript) to clients.
- Example: A web app loads JavaScript dynamically to render UI components.
- Use nouns (not verbs) for endpoints.
- Use plural nouns for collections.
- Use hierarchical relationships for nested resources.
Good | Bad | Reason |
---|---|---|
/users |
/getUsers |
Use nouns, not verbs. |
/users/123 |
/user?id=123 |
Use paths, not query params for IDs. |
/users/123/posts |
/posts?userId=123 |
Prefer hierarchical relationships. |
/articles?limit=10 |
/articles/page1 |
Use query params for filtering. |
Use standard HTTP methods to perform CRUD (Create, Read, Update, Delete) operations:
Method | Usage | Example |
---|---|---|
GET |
Retrieve a resource. | GET /users/123 |
POST |
Create a new resource. | POST /users |
PUT |
Replace a resource (full update). | PUT /users/123 |
PATCH |
Partially update a resource. | PATCH /users/123 |
DELETE |
Delete a resource. | DELETE /users/123 |
HEAD |
Retrieve headers only. | HEAD /users/123 |
OPTIONS |
Describe communication options. | OPTIONS /users |
Use standard HTTP status codes to indicate the result of a request:
Code | Meaning | Example Use Case |
---|---|---|
200 OK |
Success. |
GET /users/123 (resource found) |
201 Created |
Resource created. |
POST /users (new user created) |
204 No Content |
Success, no response body. |
DELETE /users/123 (user deleted) |
400 Bad Request |
Client error. | Invalid input data. |
401 Unauthorized |
Authentication failed. | Missing or invalid API key. |
403 Forbidden |
No permission. | User not authorized to access resource. |
404 Not Found |
Resource doesn’t exist. |
GET /users/999 (user not found) |
405 Method Not Allowed |
Invalid HTTP method. |
PUT /users (should be POST ) |
500 Internal Server Error |
Server error. | Database connection failed. |
-
Request Headers:
-
Content-Type
: Specifies the format of the request body (e.g.,application/json
). -
Authorization
: Includes credentials (e.g.,Bearer <token>
). -
Accept
: Specifies the desired response format (e.g.,application/json
).
-
-
Response Headers:
-
Content-Type
: Specifies the format of the response body. -
Cache-Control
: Defines caching behavior. -
ETag
: Unique identifier for a version of a resource.
-
-
Example Request (Create User):
POST /users HTTP/1.1 Host: api.example.com Content-Type: application/json Authorization: Bearer abc123 { "name": "Alice", "email": "[email protected]" }
-
Example Response:
HTTP/1.1 201 Created Content-Type: application/json Location: /users/123 { "id": 123, "name": "Alice", "email": "[email protected]" }
HATEOAS makes APIs self-descriptive by including hypermedia links in responses, allowing clients to dynamically discover available actions.
{
"id": 123,
"name": "Alice",
"links": [
{
"rel": "self",
"href": "/users/123",
"method": "GET"
},
{
"rel": "delete",
"href": "/users/123",
"method": "DELETE"
},
{
"rel": "friends",
"href": "/users/123/friends",
"method": "GET"
}
]
}
Feature | REST | SOAP | GraphQL | gRPC |
---|---|---|---|---|
Protocol | HTTP/HTTPS | HTTP, SMTP, etc. | HTTP | HTTP/2 |
Data Format | JSON, XML, plain text | XML | JSON | Protocol Buffers (binary) |
State | Stateless | Stateful (SOAP headers) | Stateless | Stateless |
Performance | Moderate (text-based) | Slow (XML parsing) | Moderate (flexible queries) | High (binary, HTTP/2) |
Caching | ✅ Yes (HTTP caching) | ❌ No | ❌ No (but can be added) | ❌ No |
Flexibility | Fixed endpoints | Rigid (WSDL contracts) | Flexible (client-defined queries) | Fixed (protobuf definitions) |
Use Cases | Public APIs, web services | Enterprise apps, banking | Complex queries, mobile apps | Microservices, internal APIs |
Tooling | Postman, cURL, Swagger | SOAPUI | GraphiQL, Apollo | BloomRPC, gRPC CLI |
Endpoint | Method | Description | Request Body | Response |
---|---|---|---|---|
/posts |
GET |
List all posts. | - | Array of posts. |
/posts |
POST |
Create a new post. | { "title": "...", "body": "..." } |
Created post. |
/posts/{id} |
GET |
Get a single post. | - | Post data. |
/posts/{id} |
PUT |
Replace a post. | { "title": "...", "body": "..." } |
Updated post. |
/posts/{id} |
PATCH |
Partially update a post. | { "title": "..." } |
Updated post. |
/posts/{id} |
DELETE |
Delete a post. | - |
204 No Content . |
/posts/{id}/comments |
GET |
List comments for a post. | - | Array of comments. |
Request:
POST /posts HTTP/1.1
Host: api.example.com
Content-Type: application/json
Authorization: Bearer abc123
{
"title": "REST API Guide",
"body": "A deep dive into RESTful APIs...",
"authorId": 123
}
Response:
HTTP/1.1 201 Created
Content-Type: application/json
Location: /posts/1
{
"id": 1,
"title": "REST API Guide",
"body": "A deep dive into RESTful APIs...",
"authorId": 123,
"createdAt": "2023-10-01T12:00:00Z",
"links": [
{ "rel": "self", "href": "/posts/1" },
{ "rel": "author", "href": "/users/123" }
]
}
Request:
GET /posts/1 HTTP/1.1
Host: api.example.com
Accept: application/json
Response:
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": 1,
"title": "REST API Guide",
"body": "A deep dive into RESTful APIs...",
"authorId": 123,
"createdAt": "2023-10-01T12:00:00Z",
"links": [
{ "rel": "self", "href": "/posts/1" },
{ "rel": "author", "href": "/users/123" },
{ "rel": "comments", "href": "/posts/1/comments" }
]
}
Request:
PATCH /posts/1 HTTP/1.1
Host: api.example.com
Content-Type: application/json
Authorization: Bearer abc123
{
"title": "Updated REST API Guide"
}
Response:
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": 1,
"title": "Updated REST API Guide",
"body": "A deep dive into RESTful APIs...",
"authorId": 123,
"createdAt": "2023-10-01T12:00:00Z",
"updatedAt": "2023-10-02T09:00:00Z"
}
Request:
DELETE /posts/1 HTTP/1.1
Host: api.example.com
Authorization: Bearer abc123
Response:
HTTP/1.1 204 No Content
Method | Description | Example |
---|---|---|
API Keys | Simple, but less secure. | Authorization: ApiKey abc123 |
Basic Auth | Username/password (Base64-encoded). | Authorization: Basic base64(user:pass) |
Bearer Tokens | JWT or OAuth tokens. | Authorization: Bearer abc123.xyz456 |
OAuth 2.0 | Delegated authorization (e.g., Google, Facebook login). | Authorization: Bearer <OAuth2_token> |
Digest Auth | More secure than Basic Auth. | Authorization: Digest ... |
-
Client Logs In:
POST /auth/login HTTP/1.1 Content-Type: application/json { "email": "[email protected]", "password": "secret123" }
-
Server Responds with JWT:
HTTP/1.1 200 OK Content-Type: application/json { "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkFsaWNlIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c" }
-
Client Uses JWT in Subsequent Requests:
GET /posts/1 HTTP/1.1 Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkFsaWNlIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Tool | Description | Example |
---|---|---|
Swagger/OpenAPI | Industry standard for API documentation. | Swagger UI |
Postman | API testing and documentation. | Postman Documentation |
Redoc | Beautiful OpenAPI documentation. | Redoc |
Stoplight | API design, documentation, and testing. | Stoplight |
openapi: 3.0.0
info:
title: Blog API
version: 1.0.0
paths:
/posts:
get:
summary: List all posts
responses:
200:
description: A list of posts
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Post'
post:
summary: Create a new post
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/PostInput'
responses:
201:
description: Post created
content:
application/json:
schema:
$ref: '#/components/schemas/Post'
/posts/{id}:
get:
summary: Get a post by ID
parameters:
- name: id
in: path
required: true
schema:
type: integer
responses:
200:
description: Post details
content:
application/json:
schema:
$ref: '#/components/schemas/Post'
components:
schemas:
Post:
type: object
properties:
id:
type: integer
title:
type: string
body:
type: string
authorId:
type: integer
PostInput:
type: object
properties:
title:
type: string
body:
type: string
authorId:
type: integer
required:
- title
- body
- authorId
Tool | Description | Example |
---|---|---|
Postman | GUI for testing APIs. | Postman |
cURL | Command-line tool for HTTP requests. | curl -X GET https://api.example.com/posts |
Insomnia | Alternative to Postman. | Insomnia |
Httpie | User-friendly CLI HTTP client. | http GET https://api.example.com/posts |
JMeter | Load testing and performance measurement. | JMeter |
mkdir rest-api-example
cd rest-api-example
npm init -y
npm install express body-parser
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.json());
// In-memory "database"
let posts = [
{ id: 1, title: "First Post", body: "Hello, world!" }
];
// GET /posts
app.get('/posts', (req, res) => {
res.json(posts);
});
// POST /posts
app.post('/posts', (req, res) => {
const { title, body } = req.body;
const id = posts.length + 1;
const newPost = { id, title, body };
posts.push(newPost);
res.status(201).json(newPost);
});
// GET /posts/:id
app.get('/posts/:id', (req, res) => {
const post = posts.find(p => p.id === parseInt(req.params.id));
if (!post) return res.status(404).json({ error: "Post not found" });
res.json(post);
});
// PATCH /posts/:id
app.patch('/posts/:id', (req, res) => {
const post = posts.find(p => p.id === parseInt(req.params.id));
if (!post) return res.status(404).json({ error: "Post not found" });
if (req.body.title) post.title = req.body.title;
if (req.body.body) post.body = req.body.body;
res.json(post);
});
// DELETE /posts/:id
app.delete('/posts/:id', (req, res) => {
const index = posts.findIndex(p => p.id === parseInt(req.params.id));
if (index === -1) return res.status(404).json({ error: "Post not found" });
posts.splice(index, 1);
res.status(204).end();
});
const PORT = 3000;
app.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
});
node server.js
curl http://localhost:3000/posts
curl -X POST -H "Content-Type: application/json" -d '{"title": "Second Post", "body": "Another example."}' http://localhost:3000/posts
curl http://localhost:3000/posts/1
curl -X PATCH -H "Content-Type: application/json" -d '{"title": "Updated Post"}' http://localhost:3000/posts/1
curl -X DELETE http://localhost:3000/posts/1
- Use URL path versioning (e.g.,
/v1/posts
) or header versioning (e.g.,Accept: application/vnd.example.v1+json
). - Avoid breaking changes in stable versions.
- Use
limit
andoffset
(orcursor
-based pagination) for large datasets. - Example:
GET /posts?limit=10&offset=20
- Use query parameters for filtering:
GET /posts?authorId=123&status=published
- Use
sort
for ordering:GET /posts?sort=-createdAt # Descending order
- Protect your API from abuse with rate limiting (e.g., 100 requests/minute per user).
- Use headers like:
X-RateLimit-Limit: 100 X-RateLimit-Remaining: 95 X-RateLimit-Reset: 30
- Use
Cache-Control
headers to specify caching behavior:Cache-Control: public, max-age=3600
- Use
ETag
orLast-Modified
for conditional requests.
- Ensure
PUT
,DELETE
, andPATCH
are idempotent (same result if called multiple times). - Use idempotency keys for
POST
requests (e.g.,Idempotency-Key: abc123
).
- Return meaningful error messages and appropriate status codes.
- Example:
{ "error": { "code": 404, "message": "Post not found", "details": { "postId": 999 } } }
- Use OpenAPI/Swagger to document your API.
- Provide interactive documentation (e.g., Swagger UI, Redoc).
- Always use HTTPS.
- Validate all inputs (e.g., SQL injection, XSS).
- Sanitize outputs to prevent data leaks.
-
Use CORS to restrict cross-origin requests:
Access-Control-Allow-Origin: https://example.com
- Log requests and responses for debugging.
- Use tools like Prometheus, Grafana, or ELK Stack for monitoring.
Language | Frameworks/Libraries |
---|---|
JavaScript | Express, Fastify, NestJS, Koa |
Python | Flask, Django REST Framework, FastAPI |
Java | Spring Boot, JAX-RS (Jersey), Micronaut |
Go | Gin, Echo, Fiber, standard net/http
|
Ruby | Ruby on Rails, Sinatra |
PHP | Laravel, Symfony |
C# | ASP.NET Core |
Rust | Actix-web, Rocket |
pip install fastapi uvicorn
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import List
app = FastAPI()
# Models
class PostBase(BaseModel):
title: str
body: str
class Post(PostBase):
id: int
# In-memory database
posts = [
{"id": 1, "title": "First Post", "body": "Hello, world!"}
]
# GET /posts
@app.get("/posts", response_model=List[Post])
async def get_posts():
return posts
# POST /posts
@app.post("/posts", response_model=Post, status_code=201)
async def create_post(post: PostBase):
new_post = {"id": len(posts) + 1, **post.dict()}
posts.append(new_post)
return new_post
# GET /posts/{id}
@app.get("/posts/{post_id}", response_model=Post)
async def get_post(post_id: int):
for post in posts:
if post["id"] == post_id:
return post
raise HTTPException(status_code=404, detail="Post not found")
# PATCH /posts/{id}
@app.patch("/posts/{post_id}", response_model=Post)
async def update_post(post_id: int, post: PostBase):
for p in posts:
if p["id"] == post_id:
p.update(post.dict())
return p
raise HTTPException(status_code=404, detail="Post not found")
# DELETE /posts/{id}
@app.delete("/posts/{post_id}", status_code=204)
async def delete_post(post_id: int):
for i, post in enumerate(posts):
if post["id"] == post_id:
posts.pop(i)
return
raise HTTPException(status_code=404, detail="Post not found")
uvicorn main:app --reload
- Open http://localhost:8000/docs for interactive Swagger UI.
- Use
curl
or Postman to test endpoints (same as the Node.js example).
- Use Redis or Memcached to cache frequent responses.
- Example (FastAPI with Redis):
import redis.asyncio as redis from fastapi import Depends r = redis.Redis(host="localhost", port=6379, db=0) @app.get("/posts") async def get_posts(cache: redis.Redis = Depends(lambda: r)): cached = await cache.get("posts") if cached: return json.loads(cached) # ... fetch from DB await cache.set("posts", json.dumps(posts), ex=3600) # Cache for 1 hour return posts
- Use indexes for frequent queries.
- Implement connection pooling (e.g., SQLAlchemy in Python).
- Use read replicas for read-heavy workloads.
- Use Nginx or HAProxy to distribute traffic across multiple API instances.
- Example Nginx config:
upstream api_servers { server localhost:3000; server localhost:3001; server localhost:3002; } server { listen 80; location / { proxy_pass http://api_servers; } }
- Enable gzip or Brotli compression for responses.
- Example (Express):
const compression = require('compression'); app.use(compression());
- Offload long-running tasks to background workers (e.g., Celery, Bull).
- Example (FastAPI with Celery):
from celery import Celery celery = Celery("tasks", broker="redis://localhost:6379/0") @app.post("/posts/async") async def create_post_async(post: PostBase): task = celery.send_task("create_post_task", args=[post.dict()]) return {"task_id": task.id}
- Validate all inputs to prevent SQL injection, XSS, and CSRF.
- Example (FastAPI):
from pydantic import BaseModel, constr class PostBase(BaseModel): title: constr(max_length=100) # Max 100 chars body: str
- Use libraries like FastAPI’s
slowapi
or Express’srate-limiter
. - Example (Express):
const rateLimit = require('express-rate-limit'); const limiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15 minutes max: 100 // limit each IP to 100 requests per windowMs }); app.use(limiter);
- Use JWT or OAuth 2.0 for authentication.
- Example (FastAPI with JWT):
from fastapi.security import OAuth2PasswordBearer from jose import JWTError, jwt SECRET_KEY = "your-secret-key" ALGORITHM = "HS256" oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") async def get_current_user(token: str = Depends(oauth2_scheme)): try: payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM]) return payload.get("sub") except JWTError: raise HTTPException(status_code=401, detail="Invalid token")
- Always use HTTPS in production.
- Use Let’s Encrypt for free TLS certificates:
sudo apt install certbot sudo certbot --nginx -d api.example.com
- Restrict cross-origin requests to trusted domains.
- Example (Express):
const cors = require('cors'); app.use(cors({ origin: ['https://example.com', 'https://app.example.com'] }));
- Regularly update dependencies to patch vulnerabilities.
- Use tools like
npm audit
,snyk
, ordependabot
.
- Test individual functions or endpoints in isolation.
- Example (Python with
pytest
):from fastapi.testclient import TestClient from main import app client = TestClient(app) def test_create_post(): response = client.post("/posts", json={"title": "Test", "body": "Hello"}) assert response.status_code == 201 assert response.json()["title"] == "Test"
- Test interactions between components (e.g., API + database).
- Example (Node.js with Jest):
const request = require('supertest'); const app = require('../server'); describe('POST /posts', () => { it('creates a new post', async () => { const res = await request(app) .post('/posts') .send({ title: 'Test', body: 'Hello' }); expect(res.statusCode).toEqual(201); }); });
- Test the entire API workflow (e.g., client → API → database).
- Use tools like Postman, Cypress, or Selenium.
- Simulate high traffic to test performance.
- Use tools like JMeter, Locust, or k6.
- Example (k6):
Run with:
import http from 'k6/http'; export default function () { http.get('http://localhost:3000/posts'); }
k6 run --vus 100 --duration 30s script.js
- Test for vulnerabilities (e.g., SQL injection, XSS).
- Use tools like OWASP ZAP, Burp Suite, or Nmap.
- Package your API in a Docker container for easy deployment.
- Example
Dockerfile
(Node.js):FROM node:18 WORKDIR /app COPY package*.json ./ RUN npm install COPY . . EXPOSE 3000 CMD ["node", "server.js"]
- Build and run:
docker build -t rest-api . docker run -p 3000:3000 rest-api
- Deploy to AWS (EC2, ECS, Lambda), Google Cloud Run, or Azure App Service.
- Example (Google Cloud Run):
gcloud run deploy --source .
- Use Nginx as a reverse proxy for load balancing and SSL termination.
- Example Nginx config:
server { listen 80; server_name api.example.com; location / { proxy_pass http://localhost:3000; proxy_set_header Host $host; } }
- Automate deployment with GitHub Actions, GitLab CI, or Jenkins.
- Example GitHub Actions workflow (
.github/workflows/deploy.yml
):name: Deploy API on: [push] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - run: npm install - run: npm test - run: docker build -t my-api . - run: docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_PASSWORD }} - run: docker push my-api
- Log requests, responses, and errors for debugging.
- Example (Express with
morgan
):const morgan = require('morgan'); app.use(morgan('combined'));
- Use Prometheus + Grafana for metrics and dashboards.
- Example (FastAPI with Prometheus):
from prometheus_fastapi_instrumentator import Instrumentator Instrumentator().instrument(app).expose(app)
- Use Sentry, Datadog, or New Relic to track errors.
- Example (Sentry with Express):
const Sentry = require('@sentry/node'); Sentry.init({ dsn: 'YOUR_DSN' }); app.use(Sentry.Handlers.requestHandler());
- Flexible queries: Clients request only the data they need.
- Example: Replace multiple REST endpoints with a single GraphQL endpoint.
- Tools: Apollo Server, Hasura.
- High-performance RPC: Binary protocol (Protobuf) over HTTP/2.
- Use Case: Microservices communication, real-time apps.
- Example: Replace REST with gRPC for internal services.
- Real-time communication: Bidirectional, full-duplex channels.
- Use Case: Chat apps, live updates, gaming.
- Example: Add WebSocket support to REST APIs for real-time features.
- Auto-scaling: Pay-per-use APIs (e.g., AWS Lambda, Google Cloud Functions).
- Example: Deploy REST APIs as serverless functions.
- Low-latency APIs: Deploy APIs closer to users (e.g., Cloudflare Workers, AWS Lambda@Edge).
- Example: Serve REST APIs from edge locations.
- REST is an architectural style for designing scalable, stateless, and interoperable APIs.
- Six Constraints: Client-server, statelessness, cacheability, uniform interface, layered system, code on demand.
-
HTTP Methods:
GET
,POST
,PUT
,PATCH
,DELETE
,HEAD
,OPTIONS
. -
Status Codes:
200 OK
,201 Created
,400 Bad Request
,401 Unauthorized
,404 Not Found
,500 Internal Server Error
. - Best Practices: Versioning, pagination, filtering, rate limiting, caching, security, and monitoring.
- Tools: Swagger/OpenAPI, Postman, cURL, FastAPI, Express, Django REST Framework.
- Future Trends: GraphQL, gRPC, WebSockets, serverless, and edge computing.
REST remains the dominant paradigm for web APIs due to its simplicity, scalability, and widespread adoption. Whether you're building a small project or a large-scale microservices architecture, REST provides a flexible and standardized way to design APIs.