Class: Rack::API::Controller

Inherits:
Object
  • Object
show all
Defined in:
lib/rack/api/controller.rb

Constant Summary collapse

MIME_TYPES =

Registered content types. If you want to use a custom formatter that is not listed here, you have to manually add it. Otherwise, Rack::API::Controller::DEFAULT_MIME_TYPE will be used as the content type.

{
  "json"  => "application/json",
  "jsonp" => "application/javascript",
  "xml"   => "application/xml",
  "rss"   => "application/rss+xml",
  "atom"  => "application/atom+xml",
  "html"  => "text/html",
  "yaml"  => "application/x-yaml",
  "txt"   => "text/plain"
}
DEFAULT_MIME_TYPE =

Default content type. Will be used when a given format hasn’t been registered on Rack::API::Controller::MIME_TYPES.

"application/octet-stream"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Controller

Returns a new instance of Controller.



56
57
58
59
60
61
62
# File 'lib/rack/api/controller.rb', line 56

def initialize(options = {})
  options.each do |name, value|
    instance_variable_set("@#{name}", value)
  end

  @url_options ||= {}
end

Instance Attribute Details

#default_formatObject

Define which will be the default format when format=<format> is not defined.



37
38
39
# File 'lib/rack/api/controller.rb', line 37

def default_format
  @default_format
end

#envObject

Hold environment from current request.



33
34
35
# File 'lib/rack/api/controller.rb', line 33

def env
  @env
end

#handlerObject

Hold block that will be executed in case the route is recognized.



29
30
31
# File 'lib/rack/api/controller.rb', line 29

def handler
  @handler
end

#prefixObject

Set the default prefix path.



41
42
43
# File 'lib/rack/api/controller.rb', line 41

def prefix
  @prefix
end

#rescuersObject

Hold handlers, that will wrap exceptions into a normalized response.



54
55
56
# File 'lib/rack/api/controller.rb', line 54

def rescuers
  @rescuers
end

#url_optionsObject

Hold url options.



49
50
51
# File 'lib/rack/api/controller.rb', line 49

def url_options
  @url_options
end

#versionObject

Specify the API version.



45
46
47
# File 'lib/rack/api/controller.rb', line 45

def version
  @version
end

Instance Method Details

#call(env) ⇒ Object

Render the result of handler.



157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/rack/api/controller.rb', line 157

def call(env) # :nodoc:
  reset!
  @env = env

  response = catch(:error) do
    render instance_eval(&handler)
  end

  response.respond_to?(:to_rack) ? response.to_rack : response
rescue Exception => exception
  handle_exception exception
end

#content_typeObject

Return response content type based on extension. If you’re using an unknown extension that wasn’t registered on Rack::API::Controller::MIME_TYPES, it will return Rack::API::Controller::DEFAULT_MIME_TYPE, which defaults to application/octet-stream.



175
176
177
178
# File 'lib/rack/api/controller.rb', line 175

def content_type
  mime = MIME_TYPES.fetch(format, DEFAULT_MIME_TYPE)
  headers.fetch("Content-Type", mime)
end

#credentialsObject

Return credentials for Basic Authentication request.



148
149
150
151
152
153
# File 'lib/rack/api/controller.rb', line 148

def credentials
  @credentials ||= begin
    request = Rack::Auth::Basic::Request.new(env)
    request.provided? ? request.credentials : []
  end
end

#error(options = {}) ⇒ Object

Stop processing by rendering the provided information.

Rack::API.app do
  version :v1 do
    get "/" do
      error(:status => 403, :message => "Not here!")
    end
  end
end

Valid options are:

  • :status: a HTTP status code. Defaults to 403.

  • :message: a message that will be rendered as the response body. Defaults to “Forbidden”.

  • :headers: the response headers. Defaults to {"Content-Type" => "text/plain"}.

You can also provide a object that responds to to_rack. In this case, this method must return a valid Rack response (a 3-item array).

class MyError
  def self.to_rack
    [500, {"Content-Type" => "text/plain"}, ["Internal Server Error"]]
  end
end

Rack::API.app do
  version :v1 do
    get "/" do
      error(MyError)
    end
  end
end


127
128
129
# File 'lib/rack/api/controller.rb', line 127

def error(options = {})
  throw :error, Response.new(options)
end

#formatObject

Return the requested format. Defaults to JSON.



90
91
92
# File 'lib/rack/api/controller.rb', line 90

def format
  params.fetch(:format, default_format)
end

#headersObject

Hold headers that will be sent on the response.



72
73
74
# File 'lib/rack/api/controller.rb', line 72

def headers
  @headers ||= {}
end

#loggerObject

Always log to the standard output.



66
67
68
# File 'lib/rack/api/controller.rb', line 66

def logger
  @logger ||= Logger.new(STDOUT)
end

#paramsObject

Merge all params into one single hash.



78
79
80
# File 'lib/rack/api/controller.rb', line 78

def params
  @params ||= HashWithIndifferentAccess.new(request.params.merge(env["rack.routing_args"]))
end

#requestObject

Return a request object.



84
85
86
# File 'lib/rack/api/controller.rb', line 84

def request
  @request ||= Rack::Request.new(env)
end

#reset!Object

Reset environment between requests.



140
141
142
143
144
# File 'lib/rack/api/controller.rb', line 140

def reset! # :nodoc:
  @params = nil
  @request = nil
  @headers = nil
end

#status(*args) ⇒ Object

Set response status code.



133
134
135
136
# File 'lib/rack/api/controller.rb', line 133

def status(*args)
  @status = args.first unless args.empty?
  @status || 200
end

#url_for(*args) ⇒ Object

Return a URL path for all segments. You can set default options by using the Rack::API::Runner#default_url_options method.

url_for :users
#=> /users

url_for :users, User.first
#=> /users/1

url_for :users, 1, :format => :json
#=> /users/1?format=json

url_for :users, :filters => [:name, :age]
#=> /users?filters[]=name&filters[]=age

URL segments can be any kind of object. First it’ll be checked if it responds to the to_param method. If not, converts object to string by using the to_s method.



200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
# File 'lib/rack/api/controller.rb', line 200

def url_for(*args)
  options = {}
  options = args.pop if args.last.kind_of?(Hash)

  segments = []
  segments << url_options[:base_path] if url_options[:base_path]
  segments << prefix if prefix
  segments << version
  segments += args.collect {|part| part.respond_to?(:to_param) ? part.to_param : part.to_s }

  url = ""
  url << url_options.fetch(:protocol, "http").to_s << "://"
  url << url_options.fetch(:host, env["SERVER_NAME"])

  port = url_options.fetch(:port, env["SERVER_PORT"]).to_i
  url << ":" << port.to_s if port.nonzero? && port != 80

  url << Rack::Mount::Utils.normalize_path(segments.join("/"))
  url << "?" << options.to_param if options.any?
  url
end