Rack & Middleware
HTTP processing layer underneath Rails
Rack is the standard interface between Ruby web servers (Puma, Unicorn) and web frameworks (Rails, Sinatra). The spec is very simple: a call(env) method returns a [status, headers, body] array.
Rails itself is a Rack app. When a request arrives, it passes through multiple Middleware layers before reaching the Rails router.
Key Middleware (check with rake middleware):
ActionDispatch::SSLโ Force HTTPSActionDispatch::Cookiesโ Cookie handlingActionDispatch::Sessionโ Session managementActionDispatch::Flashโ Flash messagesRack::MethodOverrideโ PUT/PATCH/DELETE method supportActionDispatch::RequestIdโ Request tracking ID
You can write custom Middleware to handle request logging, authentication, CORS, etc. independently from the Rails app.
Architecture Diagram
Rack::SSL
Force HTTPS
ActionDispatch::Cookies
Cookie handling
ActionDispatch::Session
Session management
ActionDispatch::Flash
Flash messages
Rack::MethodOverride
PUT/PATCH/DELETE support
ActionDispatch::RequestId
Request tracking ID
Key Points
HTTP request arrives at web server (Puma)
Passed to Middleware stack via Rack interface
Each Middleware processes/modifies request in order (onion model)
Reaches Rails Router โ Controller#Action executes
Response passes through Middleware stack in reverse
Final response [status, headers, body] returned to browser
Pros
- ✓ Separation of concerns โ add features without touching Rails code
- ✓ Compatible across Ruby web frameworks (Rails, Sinatra, etc.)
- ✓ Easy to test (independent units)
- ✓ Request/response pipeline customization
Cons
- ✗ Middleware order matters โ wrong order breaks things
- ✗ Hard to find which middleware causes issues during debugging
- ✗ Too many middlewares degrade performance
- ✗ Added abstraction layers increase complexity