Introduction

Middleware plays a crucial role in the Rails request/response lifecycle. It allows developers to modify requests before they reach the controller and manipulate responses before they reach the client.

In this guide, we’ll cover:
✔️ Understanding Rails middleware
✔️ Inserting custom middleware
✔️ Modifying existing middleware
✔️ Optimizing middleware for performance and security


1. What Is Middleware in Rails?

Middleware is a stack of Rack components that process HTTP requests before they reach your Rails controllers. Each middleware layer can:
Modify requests before they hit controllers
Intercept responses before they are sent to the client
Enhance security with authentication and rate-limiting
Improve performance through caching and compression


2. Viewing the Default Rails Middleware Stack

To inspect the middleware stack in your Rails app, run:

rails middleware  

A typical Rails application includes middleware such as:

  • Rack::Sendfile – Handles file transfers
  • ActionDispatch::Static – Serves static assets
  • Rack::MethodOverride – Supports PUT and DELETE in browsers
  • ActionDispatch::Session::CookieStore – Manages session storage

3. Adding Custom Middleware in Rails

Step 1: Create a Custom Middleware Class

Define a middleware that logs request details:

class RequestLogger  
def initialize(app)  
@app = app  
end

def call(env)  
Rails.logger.info "Processing request: #{env["REQUEST_METHOD"]} #{env["PATH_INFO"]}"  
@app.call(env)  
end  
end  
Step 2: Insert Middleware into the Stack

In config/application.rb, register the middleware:

config.middleware.use RequestLogger  

Now, every request will be logged for debugging!


4. Modifying Existing Middleware

Example: Customizing Session Store

Change the session store to use Redis instead of cookies:

Rails.application.config.middleware.swap(  
ActionDispatch::Session::CookieStore,  
ActionDispatch::Session::RedisStore,  
servers: ["redis://localhost:6379/0/session"]  
)  

Why? Redis improves session performance and scalability


5. Removing Unnecessary Middleware for Performance

Optimize performance by removing unused middleware:

config.middleware.delete Rack::Lock  

Why? Reduces unnecessary processing, improving request speed


6. Implementing Security Middleware

Example: Rate-Limiting Middleware

Prevent abuse by limiting requests per minute:

class RateLimiter  
def initialize(app)  
@app = app  
@requests = Hash.new { |h, k| h[k] = 0 }  
end

def call(env)  
ip = env["REMOTE_ADDR"]  
if @requests[ip] > 100  
return [429, { "Content-Type" => "text/plain" }, ["Rate limit exceeded"]]  
else  
@requests[ip] += 1  
@app.call(env)  
end  
end  
end  

Add it to your stack:

config.middleware.use RateLimiter  

Now, clients making too many requests will be blocked!


7. Middleware Best Practices

🚀 Keep middleware lightweight – Avoid complex logic in middleware
🚀 Place security middleware early – Protect requests before they reach controllers
🚀 Log and monitor middleware performance – Use tools like NewRelic or Skylight


Conclusion

By customizing Rails middleware, you can:
✔️ Improve performance by optimizing request handling
✔️ Enhance security with authentication and rate-limiting
✔️ Add custom behavior to the request/response cycle

🔗 Next Steps: Experiment with custom middleware logging, caching, and security features!