I have a config.ru file that is starting to have duplicate code:
map '/route1' do
run SampleApp.new
end
map '/route2' do
run SampleApp.new
end
I would like to turn this config.ru file into its own Rack application so that all I have to do is:
map '/' do
run MyApp.new
end
What is the correct way to create your own Rack application? Specifically, how can I create a class so that I can use the map
method within my class to define a bunch of routes?
Solution:
Here is a working solution:
class MyApp
def initialize
@app = Rack::Builder.new do
# copy contents of your config.ru into this block
map '/route1' do
run SampleApp.new
end
map '/route2' do
run SampleApp.new
end
end
end
def call(env)
@app.call(env)
end
end
I tried this before, but couldn't get it to work because I was trying to pass instance variables to the map
blocks. For example:
def initialize
@sample_app = SampleApp.new
@app = Rack::Builder.new do
map '/route1' do
run @sample_app # will not work
end
end
end
The reason this will not work is because the block being passed to map
is being evaluated in the context of a Rack::Builder
instance.
However, it will work if I pass a local variable:
def initialize
sample_app = SampleApp.new
@app = Rack::Builder.new do
map '/route1' do
run sample_app # will work
end
end
end
config.ru is a Rack configuration file ( ru stands for "rackup"). Rack provides a minimal interface between web servers that support Ruby and Ruby frameworks. It's like a Ruby implementation of a CGI which offers a standard protocol for web servers to execute programs.
Difference between use & run so use will only invoke a middleware, while run will run the rack object which will return final rack response with HTTP status code.
Rack is a modular interface between web servers and web applications developed in the Ruby programming language. With Rack, application programming interfaces (APIs) for web frameworks and middleware are wrapped into a single method call handling HTTP requests and responses.
The DSL used in config.ru
is defined in Rack::Builder
. When using a config.ru
, contents of the file are passed to an instance of Builder
to create the Rack app. You can do this directly yourself in code.
For example, you can take the contents of your existing config.ru
, and create a new class from it:
require 'rack'
class MyApp
def initialize
@app = Rack::Builder.new do
# copy contents of your config.ru into this block
map '/route1' do
run SampleApp.new
end
map '/route2' do
run SampleApp.new
end
end
end
def call(env)
@app.call(env)
end
end
You need the call
method so that your class is a Rack app, but you can just forward the request on to the app you create with Builder
. Then you can create your new config.ru
that uses your new app:
require './my_app'
run MyApp.new
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With