Skip to content

Restful Middleware

DodaTech 3 min read

title: "RESTful Middleware — Authentication, Logging, and Request Processing" description: "RESTful middleware processes requests and responses across your entire API, handling authentication, logging, rate limiting, CORS, and request validation centrally." date: 2026-06-28 lastmod: 2026-06-28 weight: 31 tags: [apis, restful] }

RESTful middleware provides centralized request processing for authentication, logging, rate limiting, CORS, request ID tracking, and response formatting across all endpoints.

What You'll Learn

  • Middleware pattern for REST APIs
  • Common middleware implementations
  • Middleware ordering

Why It Matters

Middleware eliminates repetitive code. Instead of adding auth checks to every endpoint, you implement it once in middleware.

Code Examples

from flask import g, request, jsonify
import uuid, time

# Request ID middleware
@app.before_request
def add_request_id():
    g.request_id = request.headers.get('X-Request-Id', str(uuid.uuid4()))

# Logging middleware
@app.before_request
def log_request():
    g.start_time = time.time()

@app.after_request
def log_response(response):
    elapsed = time.time() - g.start_time
    app.logger.info(
        f"{request.method} {request.path} "
        f"{response.status_code} {elapsed:.3f}s "
        f"[{g.get('request_id', '')}]"
    )
    return response

# Authentication middleware
@app.before_request
def authenticate():
    if request.path.startswith('/public/'):
        return

    auth_header = request.headers.get('Authorization', '')
    if not auth_header.startswith('Bearer '):
        return jsonify({"error": "Authentication required"}), 401

    try:
        token = auth_header[7:]
        payload = verify_token(token)
        g.user_id = payload['user_id']
        g.scopes = payload.get('scopes', [])
    except Exception:
        return jsonify({"error": "Invalid token"}), 401

# Response headers middleware
@app.after_request
def add_common_headers(response):
    response.headers['X-Request-Id'] = g.get('request_id', '')
    response.headers['X-Content-Type-Options'] = 'nosniff'
    response.headers['X-Frame-Options'] = 'DENY'
    return response

# Error handling middleware
@app.errorhandler(404)
def not_found(error):
    return jsonify({"error": "Not found", "request_id": g.get('request_id', '')}), 404

@app.errorhandler(500)
def server_error(error):
    return jsonify({"error": "Internal server error", "request_id": g.get('request_id', '')}), 500
// Express middleware
const express = require('express');
const crypto = require('crypto');
const app = express();

// Middleware order matters!

// 1. Request ID
app.use((req, res, next) => {
  req.requestId = req.headers['x-request-id'] || crypto.randomUUID();
  res.set('X-Request-Id', req.requestId);
  next();
});

// 2. Logging
app.use((req, res, next) => {
  const start = Date.now();
  res.on('finish', () => {
    const duration = Date.now() - start;
    console.log(`${req.method} ${req.path} ${res.statusCode} ${duration}ms`);
  });
  next();
});

// 3. Authentication
app.use('/api', (req, res, next) => {
  const auth = req.headers.authorization;
  if (!auth || !auth.startsWith('Bearer ')) {
    return res.status(401).json({ error: 'Authentication required' });
  }
  try {
    req.user = jwt.verify(auth.split(' ')[1], process.env.JWT_SECRET);
    next();
  } catch (err) {
    return res.status(401).json({ error: 'Invalid token' });
  }
});

// 4. Rate limiting
const rateLimit = {};
app.use('/api', (req, res, next) => {
  const key = req.user?.id || req.ip;
  // ... rate limit logic
  next();
});

Common Mistakes

1. Wrong Middleware Order

Auth should come before logging, response headers after processing.

2. Blocking Operations in Middleware

Don't do heavy computation or blocking I/O in middleware.

3. No Error Handling in Middleware

Middleware errors crash the entire request.

4. Modifying Request/Response Incorrectly

Changing request body or response in unexpected ways.

5. Skipping next() in Conditional Middleware

Forgetting to call next() hangs the request.

Practice Questions

  1. What is the purpose of middleware?
  2. What order should middleware be applied?
  3. Why is request ID middleware important?
  4. What middleware should run before and after request handling?
  5. How do you handle errors in middleware?

Answers:

  1. Process requests/responses across all endpoints, avoiding code duplication.
  2. Security (auth, CORS), then logging, then rate limiting, then response headers.
  3. Correlates logs and errors for debugging.
  4. Before: request ID, auth, logging start. After: logging end, response headers.
  5. Wrap middleware in try/catch and call the error handler.

Challenge: Implement a middleware pipeline for your REST API. Include request ID, logging, auth, rate limiting, and response headers.

FAQ

Can middleware modify the response body?

: Yes. After-request middleware can transform the response.

Should I use global or route-specific middleware?

: Global for cross-cutting concerns, route-specific for endpoint-specific logic.

How do I pass data from middleware to handlers?

: Context objects (Flask g) or request properties (Express req).

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro