module Roda::RodaPlugins::HostRouting

  1. lib/roda/plugins/host_routing.rb

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).

Methods

Public Class

  1. configure

Constants

REQUEST_INSTANCE_VARIABLES = [:@_host_routing_host].freeze  

Public Class methods

configure(app, opts=OPTS, &block)

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.

[show source]
    # File lib/roda/plugins/host_routing.rb
 81 def self.configure(app, opts=OPTS, &block)
 82   hosts, host_hash, default_block, default_host = DSL.new.process(&block)
 83   app.opts[:host_routing_hash] = host_hash
 84   app.opts[:host_routing_default_host] = default_host
 85 
 86   app.send(:define_method, :_host_routing_default, &default_block) if default_block
 87 
 88   app::RodaRequest.class_exec do
 89     hosts.each do |host|
 90       host_sym = host.to_sym
 91       define_method(host_sym){|&blk| always(&blk) if _host_routing_host == host}
 92       alias_method host_sym, host_sym
 93 
 94       meth = :"#{host}?"
 95       define_method(meth){_host_routing_host == host}
 96       alias_method meth, meth
 97     end
 98   end
 99 
100   if opts[:scope_predicates]
101     app.class_exec do
102       hosts.each do |host|
103         meth = :"#{host}?"
104         define_method(meth){@_request.send(meth)}
105         alias_method meth, meth
106       end
107     end
108   end
109 end