rest - dwilson2547/wiki_demo GitHub Wiki

REST (Representational State Transfer) Explained in Detail


1. What is REST?

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.


2. Six Constraints of REST

RESTful APIs must adhere to these six architectural constraints:

2.1. Client-Server Architecture

  • 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).

2.2. Statelessness

  • 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.

2.3. Cacheability

  • Responses Must Define Cacheability:
    • Use HTTP headers like Cache-Control, ETag, and Last-Modified to control caching.
  • Example:
    Cache-Control: max-age=3600
    • Tells clients to cache the response for 1 hour.

2.4. Uniform Interface

REST APIs must provide a consistent way to interact with resources using:

  1. Resource Identification in URIs:
    • Use nouns (not verbs) in endpoints (e.g., /users, /users/123).
  2. Resource Manipulation via Representations:
    • Clients interact with resources using standard HTTP methods (GET, POST, PUT, DELETE).
  3. Self-Descriptive Messages:
    • Responses include metadata (e.g., Content-Type: application/json).
  4. 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" }
        ]
      }

2.5. Layered System

  • 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.

2.6. Code on Demand (Optional)

  • 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.

3. RESTful API Design Principles

3.1. Resource Naming

  • 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.

3.2. HTTP Methods

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

3.3. HTTP Status Codes

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.

3.4. Request and Response Formats

  • 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]"
    }

4. HATEOAS (Hypermedia as the Engine of Application State)

HATEOAS makes APIs self-descriptive by including hypermedia links in responses, allowing clients to dynamically discover available actions.

Example Response with HATEOAS

{
  "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"
    }
  ]
}

5. REST vs. SOAP vs. GraphQL vs. gRPC

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

6. REST API Example: Blog System

6.1. Endpoints

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.

6.2. Example Requests and Responses

Create a Post (POST /posts)

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" }
  ]
}

Get a Post (GET /posts/1)

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" }
  ]
}

Update a Post (PATCH /posts/1)

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"
}

Delete a Post (DELETE /posts/1)

Request:

DELETE /posts/1 HTTP/1.1
Host: api.example.com
Authorization: Bearer abc123

Response:

HTTP/1.1 204 No Content

7. REST API Authentication and Authorization

7.1. Authentication Methods

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 ...

7.2. Example: JWT Authentication

  1. Client Logs In:

    POST /auth/login HTTP/1.1
    Content-Type: application/json
    
    {
      "email": "[email protected]",
      "password": "secret123"
    }
  2. Server Responds with JWT:

    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkFsaWNlIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
    }
  3. Client Uses JWT in Subsequent Requests:

    GET /posts/1 HTTP/1.1
    Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkFsaWNlIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

8. REST API Documentation Tools

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

8.1. Example OpenAPI/Swagger Specification

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

9. REST API Testing Tools

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

10. Building a REST API: Example with Node.js and Express

10.1. Set Up a Node.js Project

mkdir rest-api-example
cd rest-api-example
npm init -y
npm install express body-parser

10.2. Create the Server (server.js)

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}`);
});

10.3. Run the Server

node server.js

10.4. Test the API

List Posts

curl http://localhost:3000/posts

Create a Post

curl -X POST -H "Content-Type: application/json" -d '{"title": "Second Post", "body": "Another example."}' http://localhost:3000/posts

Get a Post

curl http://localhost:3000/posts/1

Update a Post

curl -X PATCH -H "Content-Type: application/json" -d '{"title": "Updated Post"}' http://localhost:3000/posts/1

Delete a Post

curl -X DELETE http://localhost:3000/posts/1

11. Best Practices for REST API Design

11.1. Versioning

  • 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.

11.2. Pagination

  • Use limit and offset (or cursor-based pagination) for large datasets.
  • Example:
    GET /posts?limit=10&offset=20

11.3. Filtering, Sorting, and Searching

  • Use query parameters for filtering:
    GET /posts?authorId=123&status=published
  • Use sort for ordering:
    GET /posts?sort=-createdAt  # Descending order

11.4. Rate Limiting

  • 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

11.5. Caching

  • Use Cache-Control headers to specify caching behavior:
    Cache-Control: public, max-age=3600
  • Use ETag or Last-Modified for conditional requests.

11.6. Idempotency

  • Ensure PUT, DELETE, and PATCH are idempotent (same result if called multiple times).
  • Use idempotency keys for POST requests (e.g., Idempotency-Key: abc123).

11.7. Error Handling

  • Return meaningful error messages and appropriate status codes.
  • Example:
    {
      "error": {
        "code": 404,
        "message": "Post not found",
        "details": {
          "postId": 999
        }
      }
    }

11.8. API Documentation

  • Use OpenAPI/Swagger to document your API.
  • Provide interactive documentation (e.g., Swagger UI, Redoc).

11.9. Security

  • 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

11.10. Monitoring and Analytics

  • Log requests and responses for debugging.
  • Use tools like Prometheus, Grafana, or ELK Stack for monitoring.

12. REST API Frameworks and Libraries

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

13. REST API Example: FastAPI (Python)

13.1. Install FastAPI and Uvicorn

pip install fastapi uvicorn

13.2. Create the API (main.py)

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")

13.3. Run the API

uvicorn main:app --reload

13.4. Test the API

  • Open http://localhost:8000/docs for interactive Swagger UI.
  • Use curl or Postman to test endpoints (same as the Node.js example).

14. REST API Performance Optimization

14.1. Caching

  • 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

14.2. Database Optimization

  • Use indexes for frequent queries.
  • Implement connection pooling (e.g., SQLAlchemy in Python).
  • Use read replicas for read-heavy workloads.

14.3. Load Balancing

  • 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;
      }
    }

14.4. Compression

  • Enable gzip or Brotli compression for responses.
  • Example (Express):
    const compression = require('compression');
    app.use(compression());

14.5. Asynchronous Processing

  • 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}

15. REST API Security Best Practices

15.1. Input Validation

  • 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

15.2. Rate Limiting

  • Use libraries like FastAPI’s slowapi or Express’s rate-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);

15.3. Authentication and Authorization

  • 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")

15.4. HTTPS and TLS

  • Always use HTTPS in production.
  • Use Let’s Encrypt for free TLS certificates:
    sudo apt install certbot
    sudo certbot --nginx -d api.example.com

15.5. CORS (Cross-Origin Resource Sharing)

  • Restrict cross-origin requests to trusted domains.
  • Example (Express):
    const cors = require('cors');
    app.use(cors({
      origin: ['https://example.com', 'https://app.example.com']
    }));

15.6. Dependency Security

  • Regularly update dependencies to patch vulnerabilities.
  • Use tools like npm audit, snyk, or dependabot.

16. REST API Testing Strategies

16.1. Unit Testing

  • 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"

16.2. Integration Testing

  • 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);
      });
    });

16.3. End-to-End (E2E) Testing

  • Test the entire API workflow (e.g., client → API → database).
  • Use tools like Postman, Cypress, or Selenium.

16.4. Load Testing

  • Simulate high traffic to test performance.
  • Use tools like JMeter, Locust, or k6.
  • Example (k6):
    import http from 'k6/http';
    
    export default function () {
      http.get('http://localhost:3000/posts');
    }
    Run with:
    k6 run --vus 100 --duration 30s script.js

16.5. Security Testing

  • Test for vulnerabilities (e.g., SQL injection, XSS).
  • Use tools like OWASP ZAP, Burp Suite, or Nmap.

17. REST API Deployment

17.1. Containerization (Docker)

  • 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

17.2. Cloud Deployment

  • Deploy to AWS (EC2, ECS, Lambda), Google Cloud Run, or Azure App Service.
  • Example (Google Cloud Run):
    gcloud run deploy --source .

17.3. Reverse Proxy (Nginx)

  • 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;
      }
    }

17.4. CI/CD Pipelines

  • 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

18. REST API Monitoring and Logging

18.1. Logging

  • Log requests, responses, and errors for debugging.
  • Example (Express with morgan):
    const morgan = require('morgan');
    app.use(morgan('combined'));

18.2. Monitoring

  • Use Prometheus + Grafana for metrics and dashboards.
  • Example (FastAPI with Prometheus):
    from prometheus_fastapi_instrumentator import Instrumentator
    Instrumentator().instrument(app).expose(app)

18.3. Error Tracking

  • 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());

19. REST API Evolution: Trends and Future

19.1. GraphQL

  • Flexible queries: Clients request only the data they need.
  • Example: Replace multiple REST endpoints with a single GraphQL endpoint.
  • Tools: Apollo Server, Hasura.

19.2. gRPC

  • High-performance RPC: Binary protocol (Protobuf) over HTTP/2.
  • Use Case: Microservices communication, real-time apps.
  • Example: Replace REST with gRPC for internal services.

19.3. WebSockets

  • 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.

19.4. Serverless APIs

  • Auto-scaling: Pay-per-use APIs (e.g., AWS Lambda, Google Cloud Functions).
  • Example: Deploy REST APIs as serverless functions.

19.5. Edge Computing

  • Low-latency APIs: Deploy APIs closer to users (e.g., Cloudflare Workers, AWS Lambda@Edge).
  • Example: Serve REST APIs from edge locations.

20. Summary

  • 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.

⚠️ **GitHub.com Fallback** ⚠️