Inline Routes in Rails

Inline Routes in Rails

If you want to quickly try out some Rails feature or code in the browser without spinning up a whole new controller and a view, simply map the incoming request to a lambda Rack endpoint, i.e. a lambda that returns the status, headers, and response body.

3 min read

One thing I really like about Sinatra is the incredibly simple router.

# app.rb

get '/' do
  # show something 
end

post '/' do
  # create something
end

Did you know you can do something similar in Rails?

Simply map an incoming request to a Rack endpoint, which is a fancy way to say an object responding to the call method that accepts the request environment and returns an array containing the status, headers, and response body.

Or a lambda.

# config/routes.rb

get 'rack', to: ->(env) {
  response = 'hello world'
  
  [200, {}, [response]] 
}

Agreed, not as elegant as Sinatra, but still useful when you quickly want to try some Rails feature in the browser, and don't want to spin up a whole new controller and view.

Now you might wonder if we can do everything we can inside a Rails controller. The answer is no, as the controller classes include various modules to provide additional functionality.

However, the point of this post is 'not' to do everything we can with Rails controllers, but quickly try out something that you want to understand that doesn't necessarily need the controller and views.

A good example is playing with the routing itself. Whenever I want to understand how some feature of Rails Router works, say custom non-resourceful routes, I use the above lambda, put the breakpoint in it to ensure the route is getting hit, inspect the request, and so on.

Note: If you need access to the Rails request, just wrap the Rack env hash inside the ActionDispatch::Request class. This also gives you access to the params hash.

get 'test', to: ->(env) {
  req = ActionDispatch::Request.new(env)
  puts req.params
  
  [200, {}, ['response']] 
}

A Reddit user also pointed out another excellent use case, which is for one-off health-check endpoints that simply return some 'success' response, and don't need any controller and view.

What do you think?


To learn more about routing in Rails, check out my in-depth article on the Rails Router.

Understanding the Rails Router: Why, What, and How
The router is the entry point of your Rails application. It acts as the gatekeeper for all incoming HTTP requests, inspecting and sending them to a controller action; even filtering and rejecting them if necessary. In this article, we’ll do a deep dive into the Rails Router to understand it better.

To learn more about Rack interface, see this article:

The Definitive Guide to Rack for Rails Developers
The word Rack actually refers to two things: a protocol and a gem. This article explains pretty much everything you need to know about Rack as a Rails developer. We will start by understanding the problem Rack solves and move to more advanced concepts like middleware and the Rack DSL.