I am reading this article on Rack Middleware. It states the following:
Rack is more than interface that can be used to talk to web server. It's used to group and order modules , which are usually Ruby classes, and specify dependency between them. Rack::Builder puts these modules on top of each other, creating stack-like structure of final web application .
So basically, we can use ruby classes to stack middleware on top of each other. We simply need a reference to the next middleware - kind of reminds me of the decorator design pattern.
All we need to do is have a constructor that takes the next application (middleware in the stack) as a paraemter. Second, we need to define a call method, which takes the environment hash as a parameter and returns an array of status code, environment hash and response body.
This is the example provided:
# shrimp.rb
class Shrimp
def initialize(app)
@app = app
end
def call(env)
@app.call(env)
end
end
# config.ru
require 'rack'
require 'rack/lobster'
require 'shrimp'
use Shrimp
run Rack::Lobster.new </pre>
According to the Rack documentation, The use method adds middleware to the stack, and the run method dispatches to an application. I'm a little confused by this syntax. use adds Shrimp to the middleware stack and run passes Lobster instance into the Shrimp constructor? I am still confused by the role of run here.
The article you have linked to mentions that Rack
comes with a sample application Lobster
so yes, for a start, that is an app.
The Shrimp
class is just a Ruby class which is how a middleware should be written.
In the config.ru
file, you require the modules, register the middleware, and then run the application.
use adds Shrimp to the middleware stack and run passes Lobster instance into the Shrimp constructor?
You are right when you say use
adds Shrimp
to the middleware stack but run
does not necessarily pass a Lobster
instance into the Shrimp
constructor. run
just executes the Rack
application and passing the app
instance is how Rack
works internally. The real thing happens in the use
part where you register the middleware.
For example:
# config.ru
require 'rack'
require 'rack/lobster'
require 'shrimp_1'
require 'shrimp_2'
require 'shrimp_3'
use Shrimp_1
use Shrimp_2
use Shrimp_3
run Rack::Lobster.new </pre>
All three Shrimp
classes will be passed the app(Lobster)
instance in that order and this will be handled by Rack
itself.
Have you tried this? Maybe it can be helpful. http://guides.rubyonrails.org/rails_on_rack.html#configuring-middleware-stack
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.