The host_routing plugin adds support for more routing requests based on the requested host. It also adds predicate methods for checking whether a request was requested with the given host.
When loading the plugin, you pass a block, which is used for configuring the plugin. For example, if you want to treat requests to api.example.com or api2.example.com as api requests, and treat other requests as www requests, you could use:
plugin :host_routing do |hosts| hosts.to :api, "api.example.com", "api2.example.com" hosts.default :www end
With this configuration, in your routing tree, you can call the r.api
and r.www
methods for dispatching to routing blocks only for those types of requests:
route do |r| r.api do # requests to api.example.com or api2.example.com end r.www do # requests to other domains end end
In addition to the routing methods, predicate methods are also added to the request object:
route do |r| "#{r.api?}-#{r.www?}" end # Requests to api.example.com or api2.example.com return "true-false" # Other requests return "false-true"
If the :scope_predicates
plugin option is given, predicate methods are also created in route block scope:
plugin :host_routing, scope_predicates: true do |hosts| hosts.to :api, "api.example.com" hosts.default :www end route do |r| "#{api?}-#{www?}" end
To handle hosts that match a certain format (such as all subdomains), where the specific host names are not known up front, you can provide a block when calling hosts.default
. This block is passed the host name, or an empty string if no host name is provided, and is evaluated in route block scope. When using this support, you should also call hosts.register
to register host types that could be returned by the block. For example, to handle api subdomains differently:
plugin :host_routing do |hosts| hosts.to :api, "api.example.com" hosts.register :api_sub hosts.default :www do |host| :api_sub if host.end_with?(".api.example.com") end end
This plugin uses the host method on the request to get the hostname (this method is defined by Rack).
Classes and Modules
Public Class methods
Setup the host routing support. The block yields an object used to configure the plugin. Options:
:scope_predicates |
Setup predicate methods in route block scope in addition to request scope. |
# File lib/roda/plugins/host_routing.rb 79 def self.configure(app, opts=OPTS, &block) 80 hosts, host_hash, default_block, default_host = DSL.new.process(&block) 81 app.opts[:host_routing_hash] = host_hash 82 app.opts[:host_routing_default_host] = default_host 83 84 app.send(:define_method, :_host_routing_default, &default_block) if default_block 85 86 app::RodaRequest.class_exec do 87 hosts.each do |host| 88 host_sym = host.to_sym 89 define_method(host_sym){|&blk| always(&blk) if _host_routing_host == host} 90 alias_method host_sym, host_sym 91 92 meth = :"#{host}?" 93 define_method(meth){_host_routing_host == host} 94 alias_method meth, meth 95 end 96 end 97 98 if opts[:scope_predicates] 99 app.class_exec do 100 hosts.each do |host| 101 meth = :"#{host}?" 102 define_method(meth){@_request.send(meth)} 103 alias_method meth, meth 104 end 105 end 106 end 107 end