What is Rack middleware?

Viewed 77317

What is Rack middleware in Ruby? I couldn't find any good explanation for what they mean by "middleware".

9 Answers

Rack as Design

Rack middleware is more than "a way to filter a request and response" - it's an implementation of the pipeline design pattern for web servers using Rack.

It very cleanly separates out the different stages of processing a request - separation of concerns being a key goal of all well designed software products.

For example with Rack I can have separate stages of the pipeline doing:

  • Authentication: when the request arrives, are the users logon details correct? How do I validate this OAuth, HTTP Basic Authentication, name/password?

  • Authorization: "is the user authorised to perform this particular task?", i.e. role-based security.

  • Caching: have I processed this request already, can I return a cached result?

  • Decoration: how can I enhance the request to make downstream processing better?

  • Performance & Usage Monitoring: what stats can I get from the request and response?

  • Execution: actually handle the request and provide a response.

Being able to separate the different stages (and optionally include them) is a great help in developing well structured applications.

Community

There's also a great eco-system developing around Rack Middleware - you should be able to find pre-built rack components to do all of the steps above and more. See the Rack GitHub wiki for a list of middleware.

What's Middleware?

Middleware is a dreadful term which refers to any software component/library which assists with but is not directly involved in the execution of some task. Very common examples are logging, authentication and the other common, horizontal processing components. These tend to be the things that everyone needs across multiple applications but not too many people are interested (or should be) in building themselves.

More Information

image showing rack in between unicorn and rails

Rack is a gem which provides a simple interface to abstract HTTP request/response. Rack sits between web frameworks (Rails, Sinatra etc) and web servers (unicorn, puma) as an adaptor. From above image this keeps unicorn server completely independent from knowing about rails and rails doesn't know about unicorn. This is a good example of loose coupling, separation of concerns.

Above image is from this rails conference talk on rack https://youtu.be/3PnUV9QzB0g I recommend watching it for deeper understanding.

Rack - The Interface b/w Web & App Server

Rack is a Ruby package which provides an interface for a web server to communicate with the application. It is easy to add middleware components between the web server and the app to modify the way your request/response behaves. The middleware component sits between the client and the server, processing inbound requests and outbound responses.

In layman words, It is basically just a set of guidelines for how a server and a Rails app (or any other Ruby web app) should talk to each other.

To use Rack, provide an "app": an object that responds to the call method, taking the environment hash as a parameter, and returning an Array with three elements:

  • The HTTP response code
  • A Hash of headers
  • The response body, which must respond to each request.

For more explanation, you can follow the below links.

1. https://rack.github.io/
2. https://redpanthers.co/rack-middleware/
3. https://blog.engineyard.com/2015/understanding-rack-apps-and-middleware
4. https://guides.rubyonrails.org/rails_on_rack.html#resources

In rails, we have config.ru as a rack file, you can run any rack file with rackup command. And the default port for this is 9292. To test this, you can simply run rackup in your rails directory and see the result. You can also assign port on which you want to run it. Command to run rack file on any specific port is

rackup -p PORT_NUMBER
Related