Sid Ngeth's Blog A blog about anything (but mostly development)

Understanding Rails HTTP Processing

I had an interesting interview recently where the interviewer asked me what do you write in a Rails controller. I’ve written a lot of web apps and APIs and I really couldn’t understand the aim of the question. Is it a probe in the technical depth of how web frameworks work, or appreciation of how the controller organizes seperation of concerns? Something i’ve realized is modern day to day work is simply magic we don’t think about.

To appreciate why this matters, let’s remember what web development looked like before MVC frameworks. Here’s a typical PHP script from the early 2000s:

<?php
// article.php - A single file handling database, business logic, and view
$conn = mysql_connect("localhost", "user", "password");
mysql_select_db("blog");

if ($_POST['action'] == 'create') {
    $title = mysql_real_escape_string($_POST['title']);
    $content = mysql_real_escape_string($_POST['content']);
    mysql_query("INSERT INTO posts (title, content) VALUES ('$title', '$content')");
    header("Location: article.php");
}

$result = mysql_query("SELECT * FROM posts ORDER BY created_at DESC");
?>

<html>
<body>
    <form method="post">
        <input type="hidden" name="action" value="create">
        Title: <input type="text" name="title"><br>
        Content: <textarea name="content"></textarea><br>
        <input type="submit" value="Create Post">
    </form>

    <?php while ($row = mysql_fetch_assoc($result)) { ?>
        <h2><?php echo htmlspecialchars($row['title']); ?></h2>
        <p><?php echo htmlspecialchars($row['content']); ?></p>
    <?php } ?>
</body>
</html>

The PHP example shows:

  1. Database connection mixed with business logic
  2. SQL queries embedded directly in the page
  3. HTML templates mixed with PHP code
  4. No separation of concerns
  5. Basic security handled manually (mysql_real_escape_string)

However, understanding this ā€œmagicā€ becomes crucial when:

  • Debugging complex routing issues
  • Building custom middleware
  • Optimizing application performance
  • Designing APIs that deviate from Rails conventions

Let’s peek behind the curtain and see how Rails transforms raw HTTP into the clean, object-oriented code we work with daily.

The HTTP Request Journey

Step 1: Raw HTTP Arrives

Everything starts with a raw HTTP request hitting your server:

GET /posts/5 HTTP/1.1
Host: example.com
Accept: text/html
User-Agent: Mozilla/5.0
Cookie: session=abc123

This text-based protocol carries all the information needed to process the request: method, path, headers, and potentially a body. But working with raw text would be cumbersome and error-prone.

Step 2: Rack Middleware Processing

Rack, the unsung hero of Ruby web applications, transforms raw HTTP into something more manageable.

env = {
  'REQUEST_METHOD' => 'GET',
  'PATH_INFO' => '/posts/5',
  'HTTP_ACCEPT' => 'text/html',
  'HTTP_COOKIE' => 'session=abc123'
}

This standardized hash becomes the common currency of request handling. Every piece of middleware can modify this hash, adding features like:

  • Session handling
  • Request parsing
  • Authentication
  • Logging

Step 3: Rails Router Takes Control

The router (config/routes.rb) acts as traffic control, determining which code should handle the request:

Rails.application.routes.draw do
  resources :posts
  # Expands to multiple routes including:
  # GET /posts/:id => posts#show
end

When a request arrives, the router:

  1. Matches the path and HTTP method against defined routes
  2. Extracts parameters from dynamic segments
  3. Identifies the target controller and action

Step 4: Controller Processing

Finally, we reach familiar territory. The controller receives a clean, normalized request:

class PostsController < ApplicationController
  def show
    @post = Post.find(params[:id])
    render json: @post
  end
end

All the complexity of HTTP has been abstracted away. We can focus on business logic rather than protocol details.

Why This Matters

For Development

  • Understanding the request cycle helps you debug issues more effectively
  • Knowledge of middleware lets you add cross-cutting concerns cleanly
  • Appreciation of HTTP details improves API design

For Performance

  • Each layer adds some processing overhead
  • Knowing the flow helps identify optimization opportunities
  • Understanding middleware ordering can prevent unnecessary processing
comments powered by Disqus