Class: Rutter::Builder

Inherits:
Object
  • Object
show all
Defined in:
lib/rutter/builder.rb

Overview

The router redirect incoming requests to defined endpoints. Most often it's to a controller and an action or a Rack endpoint.

Examples:

basic usage

Rutter.new do
  get "/", to: ->(env) {}
  post "/", to: ->(env) {}
  put "/", to: ->(env) {}
  patch "/", to: ->(env) {}
  delete "/", to: ->(env) {}
  options "/", to: ->(env) {}
  head "/", to: ->(env) {}
  trace "/", to: ->(env) {}
end.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(scheme: "http", host: "example.com", port: 80, controller_suffix: nil) { ... } ⇒ self

Initializes the router.

Parameters:

  • scheme (String) (defaults to: "http")

    URL scheme.

  • host (String) (defaults to: "example.com")

    URL host.

  • port (Integer) (defaults to: 80)

    URL port.

  • controller_suffix (String) (defaults to: nil)

    Suffix string for controllers (BooksController).

Yields:

  • Block is run inside the created Builder context.



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/rutter/builder.rb', line 48

def initialize(
  scheme: "http",
  host: "example.com",
  port: 80,
  controller_suffix: nil,
  &block
)
  @scheme = scheme
  @host = host
  @port = port
  @controller_suffix = controller_suffix
  @flat_map = []
  @verb_map = Hash.new { |hash, key| hash[key] = [] }
  @named_map = {}

  instance_eval(&block) if block_given?
end

Instance Attribute Details

#flat_mapArray<Rutter::Route> (readonly)

Defined routes.

Returns:



30
31
32
# File 'lib/rutter/builder.rb', line 30

def flat_map
  @flat_map
end

#named_mapHash<Symbol => Rutter::Route> (readonly)

Named routes.

Returns:

  • (Hash<Symbol => Rutter::Route>)

    the current value of named_map



30
31
32
# File 'lib/rutter/builder.rb', line 30

def named_map
  @named_map
end

#verb_mapHash<String => Array> (readonly)

Routes group by verb.

Returns:

  • (Hash<String => Array>)

    the current value of verb_map



30
31
32
# File 'lib/rutter/builder.rb', line 30

def verb_map
  @verb_map
end

Instance Method Details

#add(method, path, to:, as: nil) ⇒ Rutter::Route

Adds a new route to the collection.

Parameters:

  • method (String, Symbol)

    Request method.

  • path (String)

    Path template.

  • as (String, Symbol) (defaults to: nil)

    Route identifier (name).

  • to (String, Proc)

    Route endpoint.

Returns:



122
123
124
125
126
127
128
129
130
131
# File 'lib/rutter/builder.rb', line 122

def add(method, path, to:, as: nil)
  route = Route.new(method, path, to, controller_suffix: @controller_suffix)

  flat_map << route
  verb_map[route.method] << route

  return route unless as

  add_named_route!(as, route)
end

#freezeself

Freezes the router and its routes.

Returns:

  • (self)


247
248
249
250
251
252
253
# File 'lib/rutter/builder.rb', line 247

def freeze
  flat_map.freeze
  verb_map.freeze
  named_map.freeze

  super
end

#mount(app, at:) ⇒ void

This method returns an undefined value.

Mount a Rack application at the specified path.

Parameters:

  • app (Class, Object)

    A class or an object that responds to call.

  • at (String)

    Path prefix to match.



74
75
76
# File 'lib/rutter/builder.rb', line 74

def mount(app, at:)
  Route::VERBS.each { |verb| add verb, "#{at}*_", to: app }
end

#path(name, params = {}) ⇒ String

Transforms a named route into a URL path.

Parameters:

  • name (Symbol)

    Name of the route.

  • params (Hash) (defaults to: {})

    Route paremeters.

Returns:

  • (String)

Raises:

  • (ArgumentError)

    if route not found.



183
184
185
186
187
188
189
190
191
# File 'lib/rutter/builder.rb', line 183

def path(name, params = {})
  route = named_map[name]

  raise ArgumentError, "no route called '#{name}'" unless route

  path = route.expand(params)
  path = path.gsub(%r{\A[\/]+|[\/]+\z}, "")
  "/#{path}"
end

#redirect(destination, status: 302) ⇒ Proc

Convenient method to create a redirect endpoint.

Examples:

basic usage

Rutter.new do
  get "/legacy-path", to: redirect("/new_path")
end

with custom status

Rutter.new do
  get "/legacy-path", to: redirect("/new_path", status: 301)
end

Parameters:

  • destination (String)

    The destination.

  • status (Integer) (defaults to: 302)

    Response status code.

Returns:

  • (Proc)

    Redirect endpoint.



97
98
99
# File 'lib/rutter/builder.rb', line 97

def redirect(destination, status: 302)
  ->(_env) { [status, { "Location" => destination.to_s }, []] }
end

#root(**opts) ⇒ Rutter::Route

Defines a root route (a GET route for '/').

Returns:

See Also:



106
107
108
# File 'lib/rutter/builder.rb', line 106

def root(**opts)
  get "/", **opts.merge(as: :root)
end

#scope(**opts) { ... } ⇒ Rutter::Scope

Starts a scoped collection of routes.

Examples:

Rutter.new do
  scope path: "animals", namespace: "Species", as: "animals" do
    scope path: "mammals", namespace: "Mammals", as: "mammals" do
      get "/cats", to: "Cats#index", as: :cats
    end
  end
end

with subdomain

Rutter.new do
  scope path: "v1", namespace: "Api::V1", subdomain: "api" do
    get "/books", to: "Books#index"
  end
end

Parameters:

  • opts (Hash)

    a customizable set of options

Options Hash (**opts):

  • :path (String) — default: nil

    Path prefix

  • :namespace (String) — default: nil

    Namespace prefix

  • :as (String, Symbol) — default: nil

    Name prefix

Yields:

  • Scope context.

Returns:



168
169
170
# File 'lib/rutter/builder.rb', line 168

def scope(**opts, &block)
  Scope.new(self, **opts, &block)
end

#url(name, params = {}) ⇒ String

Transforms a named route into a full URL with scheme and host.

Parameters:

  • name (Symbol)

    Name of the route.

  • params (Hash) (defaults to: {})

    a customizable set of options

Options Hash (params):

  • :_scheme (String) — default: configuration.scheme

    Override scheme.

  • :_host (String) — default: configuration.host

    Override host.

  • :_subdomain (String) — default: nil

    Set a specific subdomain for the URL.

  • :_port (Symbol) — default: configuration.port

    Override port. The port will only be visible unless it's set to 80 or 443.

Returns:

  • (String)

Raises:

  • (ArgumentError)

    If route not found.



211
212
213
214
215
216
217
218
219
# File 'lib/rutter/builder.rb', line 211

def url(name, params = {})
  scheme = params.delete(:_scheme) || @scheme
  host = params.delete(:_host) || @host
  port = (params.delete(:_port) || @port).to_i
  host = "#{host}:#{port}" unless [80, 443].include?(port)
  subdomain = params.delete(:_subdomain)
  host = "#{subdomain}.#{host}" if subdomain
  "#{scheme}://#{host}#{path(name, params)}"
end