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