Class: Rack::API::Runner
- Inherits:
-
Object
- Object
- Rack::API::Runner
- Defined in:
- lib/rack/api/runner.rb
Constant Summary collapse
- HTTP_METHODS =
%w[get post put delete head patch options]- DELEGATE_METHODS =
%w[ version use prefix basic_auth rescue_from helper respond_to default_url_options get post put delete head patch options ]
Instance Attribute Summary collapse
-
#settings ⇒ Object
Returns the value of attribute settings.
Instance Method Summary collapse
-
#basic_auth(realm = "Restricted Area", &block) ⇒ Object
Require basic authentication before processing other requests.
-
#call(env) ⇒ Object
Run all routes.
-
#default_url_options(options) ⇒ Object
Define the server endpoint.
-
#helper(mod = nil, &block) ⇒ Object
Add a helper to application.
-
#initialize ⇒ Runner
constructor
A new instance of Runner.
-
#option(name, mode = :any) ⇒ Object
Try to fetch local configuration, defaulting to the global setting.
-
#prefix(name) ⇒ Object
Set an additional url prefix.
-
#rescue_from(exception, options = {}, &block) ⇒ Object
Rescue from the specified exception.
-
#respond_to(*formats) ⇒ Object
Define the formats that this app implements.
-
#route(method, path, requirements = {}, &block) ⇒ Object
Define a new routing that will be triggered when both request method and path are recognized.
-
#route_set ⇒ Object
Hold all routes.
-
#set(name, value, mode = :override) ⇒ Object
Set configuration based on scope.
-
#use(middleware, *args) ⇒ Object
Add a middleware to the execution stack.
-
#version(name, &block) ⇒ Object
Create a new API version.
Constructor Details
#initialize ⇒ Runner
Returns a new instance of Runner.
14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/rack/api/runner.rb', line 14 def initialize @settings = { :middlewares => [], :helpers => [], :rescuers => [], :global => { :prefix => "/", :formats => %w[json jsonp], :middlewares => [], :helpers => [], :rescuers => [] } } end |
Instance Attribute Details
#settings ⇒ Object
Returns the value of attribute settings.
12 13 14 |
# File 'lib/rack/api/runner.rb', line 12 def settings @settings end |
Instance Method Details
#basic_auth(realm = "Restricted Area", &block) ⇒ Object
Require basic authentication before processing other requests. The authentication reques must be defined before routes.
Rack::API.app do
basic_auth "Protected Area" do |user, pass|
User.authenticate(user, pass)
end
end
You can disable basic authentication by providing :none as realm.
Rack::API.app do
basic_auth "Protected Area" do |user, pass|
User.authenticate(user, pass)
end
version :v1 do
# this version is protected by the
# global basic auth block above.
end
version :v2 do
basic_auth :none
# this version is now public
end
version :v3 do
basic_auth "Admin" do |user, pass|
user == "admin" && pass == "test"
end
end
end
167 168 169 |
# File 'lib/rack/api/runner.rb', line 167 def basic_auth(realm = "Restricted Area", &block) set :auth, (realm == :none ? :none : [realm, block]) end |
#call(env) ⇒ Object
Run all routes.
129 130 131 |
# File 'lib/rack/api/runner.rb', line 129 def call(env) # :nodoc: route_set.freeze.call(env) end |
#default_url_options(options) ⇒ Object
Define the server endpoint. Will be used if you call the method Rack::API::Controller#url_for.
The following options are supported:
-
:host– Specifies the host the link should be targeted at. -
:protocol– The protocol to connect to. Defaults to ‘http’. -
:port– Optionally specify the port to connect to. -
:base_path– Optionally specify a base path.
Some usage examples:
:host => "myhost.com"
#=> http://myhost.com
:host => "myhost.com", :protocol => "https"
#=> https://myhost.com
:host => "myhost.com", :port => 3000
#=> http://myhost.com:3000
:host => "myhost.com", :base_path => "my/custom/path"
#=> http://myhost.com/my/custom/path
114 115 116 |
# File 'lib/rack/api/runner.rb', line 114 def () set :url_options, end |
#helper(mod = nil, &block) ⇒ Object
Add a helper to application.
helper MyHelpers
helper { }
84 85 86 87 88 |
# File 'lib/rack/api/runner.rb', line 84 def helper(mod = nil, &block) mod = Module.new(&block) if block_given? raise ArgumentError, "you need to pass a module or block" unless mod set :helpers, mod, :append end |
#option(name, mode = :any) ⇒ Object
Try to fetch local configuration, defaulting to the global setting. Return nil when no configuration is defined.
47 48 49 50 51 52 53 |
# File 'lib/rack/api/runner.rb', line 47 def option(name, mode = :any) if mode == :merge && (settings[name].kind_of?(Array) || settings[:global][name].kind_of?(Array)) settings[:global].fetch(name, []) | settings.fetch(name, []) else settings.fetch(name, settings[:global][name]) end end |
#prefix(name) ⇒ Object
Set an additional url prefix.
75 76 77 |
# File 'lib/rack/api/runner.rb', line 75 def prefix(name) set :prefix, name end |
#rescue_from(exception, options = {}, &block) ⇒ Object
Rescue from the specified exception.
rescue_from ActiveRecord::RecordNotFound, :status => 404
rescue_from Exception, :status => 500
rescue_from Exception do |error|
$logger.error error.inspect
[500, {"Content-Type" => "text/plain"}, []]
end
284 285 286 |
# File 'lib/rack/api/runner.rb', line 284 def rescue_from(exception, = {}, &block) set :rescuers, {:class_name => exception.name, :options => , :block => block}, :append end |
#respond_to(*formats) ⇒ Object
Define the formats that this app implements. Respond only to :json by default.
When setting a format you have some alternatives on how this object will be formated.
First, Rack::API will look for a formatter defined on Rack::API::Formatter namespace. If there’s no formatter, it will look for a method to_<format>. It will raise an exception if no formatter method has been defined.
See Rack::API::Formatter::Jsonp for an example on how to create additional formatters.
Local formats will override the global configuration on that context.
Rack::API.app do
respond_to :json, :xml, :jsonp
version :v1 do
respond_to :json
end
end
The code above will accept only :json as format on version :v1.
Also, the first value provided to this method will be used as default format, which means that requests that don’t provide the :format param, will use this value.
respond_to :fffuuu, :json
#=> the default format is fffuuu
203 204 205 |
# File 'lib/rack/api/runner.rb', line 203 def respond_to(*formats) set :formats, formats end |
#route(method, path, requirements = {}, &block) ⇒ Object
Define a new routing that will be triggered when both request method and path are recognized.
You’re better off using all verb shortcut methods. Implemented verbs are get, post, put, delete, head and patch.
class MyAPI < Rack::API
version "v1" do
get "users(.:format)" do
# do something
end
end
end
You don’t have to use version or prefix.
class MyAPI < Rack::API
get "users(.:format)" do
# do something
end
end
Alternatively, you can define your routes pretty much like Rails.
class MyAPI < Rack::API
get "users(.:format)", :to => "users#index"
end
The route above will require a class Users with an instance method index.
class Users < Rack::API::Controller
def index
# do something
end
end
Note that your controller must inherit from Rack::API::Controller. Otherwise, your world will explode.
252 253 254 255 256 257 258 259 260 261 262 263 264 265 |
# File 'lib/rack/api/runner.rb', line 252 def route(method, path, requirements = {}, &block) separator = requirements.delete(:separator) { %w[ / . ? ] } path = Rack::Mount::Strexp.compile mount_path(path), requirements, separator controller_class = Controller if requirements[:to] controller_name, action_name = requirements.delete(:to).split("#") controller_class = controller_name.camelize.constantize block = proc { __send__(action_name) } end route_set.add_route(build_app(controller_class, block), :path_info => path, :request_method => method) end |
#route_set ⇒ Object
Hold all routes.
209 210 211 |
# File 'lib/rack/api/runner.rb', line 209 def route_set # :nodoc: @route_set ||= Rack::Mount::RouteSet.new end |
#set(name, value, mode = :override) ⇒ Object
Set configuration based on scope. When defining values outside version block, will set configuration using settings[:global] namespace.
Use the Rack::API::Runner#option method to access a given setting.
34 35 36 37 38 39 40 41 42 |
# File 'lib/rack/api/runner.rb', line 34 def set(name, value, mode = :override) target = settings[:version] ? settings : settings[:global] if mode == :override target[name] = value else target[name] << value end end |
#use(middleware, *args) ⇒ Object
Add a middleware to the execution stack.
Global middlewares will be merged with local middlewares.
Rack::API.app do
use ResponseTime
version :v1 do
use Gzip
end
end
The middleware stack will be something like [ResponseTime, Gzip].
69 70 71 |
# File 'lib/rack/api/runner.rb', line 69 def use(middleware, *args) set :middlewares, [middleware, *args], :append end |
#version(name, &block) ⇒ Object
Create a new API version.
120 121 122 123 124 125 |
# File 'lib/rack/api/runner.rb', line 120 def version(name, &block) raise ArgumentError, "you need to pass a block" unless block_given? settings[:version] = name.to_s instance_eval(&block) settings.delete(:version) end |