For one of my ruby applications i need the server to route requests based on the subdomain. There are ways to do this using other gems but i decided to make my own "middleware". This code runs applications based on where the request is going to.
config.ru
require './subdomain'
require './www'
run Rack::Subdomain.new([
{
:subdomain => "test",
:application => Sinatra::Application
}
]);
subdomain.rb
module Rack
class Subdomain
def initialize(app)
@app = app
end
def call(env)
@app.each do |app|
match = 'test'.match(app[:subdomain])
if match
return app[:application].call(env)
end
end
end
end
end
My question is how can i modify this working code to work exactly the same but have it called by code that looks like this:
run Rack::Subdomain do
map 'www' do
Example::WWW
end
map 'api' do
Example::API
end
end
With suggested code:
config.ru
require './subdomain'
require './www'
run Rack::Subdomain.new do |x|
x.map 'test' do
Sinatra::Application
end
end
subdomain.rb
module Rack
class Subdomain
def initialize(routes = nil)
@routes = routes
yield self
end
def map(subdomain)
@routes << { subdomain: subdomain, application: yield }
end
def call(env)
@routes.each do |route|
match = 'test'.match(route[:subdomain])
if match
return route[:application].call(env)
end
end
end
end
end
You call the above "working code" but it doesn't seem to detect the subdomain at all, but wires it to the literal 'test'. At any rate, you can implement a pattern similar to what you want by making a map method which adds entries to your list of subdomain->application routes. I've renamed your
@app
to@routes
since it is a hash of routes, not an application reference.