Class: Grape::API
- Inherits:
-
Object
- Object
- Grape::API
- Extended by:
- Validations::ClassMethods
- Defined in:
- lib/grape/api.rb,
lib/grape/validations/coerce.rb
Overview
The API class is the primary entry point for creating Grape APIs.Users should subclass this class in order to build an API.
Defined Under Namespace
Modules: Helpers
Constant Summary collapse
- LOCK =
Mutex.new
- Boolean =
rubocop:disable ConstantName
Virtus::Attribute::Boolean
Class Attribute Summary collapse
-
.endpoints ⇒ Object
readonly
Returns the value of attribute endpoints.
-
.instance ⇒ Object
readonly
Returns the value of attribute instance.
- .logger(logger = nil) ⇒ Object
-
.route_set ⇒ Object
readonly
Returns the value of attribute route_set.
-
.routes ⇒ Object
readonly
An array of API routes.
-
.settings ⇒ Object
readonly
Returns the value of attribute settings.
-
.versions ⇒ Object
readonly
Returns the value of attribute versions.
Class Method Summary collapse
- .after(&block) ⇒ Object
- .after_validation(&block) ⇒ Object
-
.auth(type = nil, options = {}, &block) ⇒ Object
Add an authentication type to the API.
- .before(&block) ⇒ Object
- .before_validation(&block) ⇒ Object
- .call(env) ⇒ Object
- .call!(env) ⇒ Object
- .cascade(value = nil) ⇒ Object
- .change! ⇒ Object
- .compile ⇒ Object
-
.content_type(key, val) ⇒ Object
Specify additional content-types, e.g.: content_type :xls, 'application/vnd.ms-excel'.
-
.content_types ⇒ Object
All available content types.
-
.default_error_formatter(new_formatter_name = nil) ⇒ Object
Specify a default error formatter.
-
.default_error_status(new_status = nil) ⇒ Object
Specify the default status code for errors.
-
.default_format(new_format = nil) ⇒ Object
Specify the default format for the API's serializers.
- .delete(paths = ['/'], options = {}, &block) ⇒ Object
-
.desc(description, options = {}) ⇒ Object
Add a description to the next namespace or function.
-
.do_not_route_head! ⇒ Object
Do not route HEAD requests to GET requests automatically.
-
.do_not_route_options! ⇒ Object
Do not automatically route OPTIONS.
- .error_formatter(format, options) ⇒ Object
-
.format(new_format = nil) ⇒ Object
Specify the format for the API's serializers.
-
.formatter(content_type, new_formatter) ⇒ Object
Specify a custom formatter for a content-type.
- .get(paths = ['/'], options = {}, &block) ⇒ Object
- .head(paths = ['/'], options = {}, &block) ⇒ Object
-
.helpers(new_mod = nil, &block) ⇒ Object
Add helper methods that will be accessible from any endpoint within this namespace (and child namespaces).
-
.http_basic(options = {}, &block) ⇒ Object
Add HTTP Basic authorization to the API.
- .http_digest(options = {}, &block) ⇒ Object
-
.imbue(key, value) ⇒ Object
Add to a configuration value for this namespace.
-
.middleware ⇒ Object
Retrieve an array of the middleware classes and arguments that are currently applied to the application.
- .mount(mounts) ⇒ Object
- .namespace(space = nil, options = {}, &block) ⇒ Object (also: group, resource, resources, segment)
- .options(paths = ['/'], options = {}, &block) ⇒ Object
-
.parser(content_type, new_parser) ⇒ Object
Specify a custom parser for a content-type.
- .patch(paths = ['/'], options = {}, &block) ⇒ Object
- .post(paths = ['/'], options = {}, &block) ⇒ Object
-
.prefix(prefix = nil) ⇒ Object
Define a root URL prefix for your entire API.
- .put(paths = ['/'], options = {}, &block) ⇒ Object
-
.represent(model_class, options) ⇒ Object
Allows you to specify a default representation entity for a class.
-
.rescue_from(*exception_classes, options = {}) ⇒ Object
Allows you to rescue certain exceptions that occur to return a grape error rather than raising all the way to the server level.
- .reset! ⇒ Object
-
.route(methods, paths = ['/'], route_options = {}, &block) ⇒ Object
Defines a route that will be recognized by the Grape API.
-
.route_param(param, options = {}, &block) ⇒ Object
Thie method allows you to quickly define a parameter route segment in your API.
-
.scope(name = nil, &block) ⇒ Object
Create a scope without affecting the URL.
-
.set(key, value) ⇒ Object
Set a configuration value for this namespace.
-
.use(middleware_class, *args, &block) ⇒ Object
Apply a custom middleware to the API.
-
.version(*args, &block) ⇒ Object
Specify an API version.
Instance Method Summary collapse
- #call(env) ⇒ Object
-
#cascade? ⇒ Boolean
Some requests may return a HTTP 404 error if grape cannot find a matching route.
-
#initialize ⇒ API
constructor
A new instance of API.
Methods included from Validations::ClassMethods
document_attribute, params, reset_validations!
Constructor Details
#initialize ⇒ API
Returns a new instance of API.
527 528 529 530 531 532 533 534 |
# File 'lib/grape/api.rb', line 527 def initialize @route_set = Rack::Mount::RouteSet.new self.class.endpoints.each do |endpoint| endpoint.mount_in(@route_set) end @route_set.freeze end |
Class Attribute Details
.endpoints ⇒ Object (readonly)
Returns the value of attribute endpoints.
9 10 11 |
# File 'lib/grape/api.rb', line 9 def endpoints @endpoints end |
.instance ⇒ Object (readonly)
Returns the value of attribute instance.
9 10 11 |
# File 'lib/grape/api.rb', line 9 def instance @instance end |
.logger(logger = nil) ⇒ Object
14 15 16 17 18 19 20 |
# File 'lib/grape/api.rb', line 14 def logger(logger = nil) if logger @logger = logger else @logger ||= Logger.new($stdout) end end |
.route_set ⇒ Object (readonly)
Returns the value of attribute route_set.
9 10 11 |
# File 'lib/grape/api.rb', line 9 def route_set @route_set end |
.routes ⇒ Object (readonly)
An array of API routes.
465 466 467 |
# File 'lib/grape/api.rb', line 465 def routes @routes end |
.settings ⇒ Object (readonly)
Returns the value of attribute settings.
9 10 11 |
# File 'lib/grape/api.rb', line 9 def settings @settings end |
.versions ⇒ Object (readonly)
Returns the value of attribute versions.
9 10 11 |
# File 'lib/grape/api.rb', line 9 def versions @versions end |
Class Method Details
.after(&block) ⇒ Object
373 374 375 |
# File 'lib/grape/api.rb', line 373 def after(&block) imbue(:afters, [block]) end |
.after_validation(&block) ⇒ Object
369 370 371 |
# File 'lib/grape/api.rb', line 369 def after_validation(&block) imbue(:after_validations, [block]) end |
.auth(type = nil, options = {}, &block) ⇒ Object
Add an authentication type to the API. Currently
only :http_basic
, :http_digest
and :oauth2
are supported.
296 297 298 299 300 301 302 |
# File 'lib/grape/api.rb', line 296 def auth(type = nil, = {}, &block) if type set(:auth, { type: type.to_sym, proc: block }.merge()) else settings[:auth] end end |
.before(&block) ⇒ Object
361 362 363 |
# File 'lib/grape/api.rb', line 361 def before(&block) imbue(:befores, [block]) end |
.before_validation(&block) ⇒ Object
365 366 367 |
# File 'lib/grape/api.rb', line 365 def before_validation(&block) imbue(:before_validations, [block]) end |
.call(env) ⇒ Object
38 39 40 41 |
# File 'lib/grape/api.rb', line 38 def call(env) LOCK.synchronize { compile } unless instance call!(env) end |
.call!(env) ⇒ Object
43 44 45 |
# File 'lib/grape/api.rb', line 43 def call!(env) instance.call(env) end |
.cascade(value = nil) ⇒ Object
473 474 475 476 477 478 479 |
# File 'lib/grape/api.rb', line 473 def cascade(value = nil) if value.nil? settings.has_key?(:cascade) ? !!settings[:cascade] : true else set(:cascade, value) end end |
.change! ⇒ Object
34 35 36 |
# File 'lib/grape/api.rb', line 34 def change! @instance = nil end |
.compile ⇒ Object
30 31 32 |
# File 'lib/grape/api.rb', line 30 def compile @instance ||= new end |
.content_type(key, val) ⇒ Object
Specify additional content-types, e.g.: content_type :xls, 'application/vnd.ms-excel'
173 174 175 |
# File 'lib/grape/api.rb', line 173 def content_type(key, val) settings.imbue(:content_types, key.to_sym => val) end |
.content_types ⇒ Object
All available content types.
178 179 180 |
# File 'lib/grape/api.rb', line 178 def content_types Grape::ContentTypes.content_types_for(settings[:content_types]) end |
.default_error_formatter(new_formatter_name = nil) ⇒ Object
Specify a default error formatter.
152 153 154 155 156 157 158 159 |
# File 'lib/grape/api.rb', line 152 def default_error_formatter(new_formatter_name = nil) if new_formatter_name new_formatter = Grape::ErrorFormatter::Base.formatter_for(new_formatter_name, {}) set(:default_error_formatter, new_formatter) else settings[:default_error_formatter] end end |
.default_error_status(new_status = nil) ⇒ Object
Specify the default status code for errors.
183 184 185 |
# File 'lib/grape/api.rb', line 183 def default_error_status(new_status = nil) new_status ? set(:default_error_status, new_status) : settings[:default_error_status] end |
.default_format(new_format = nil) ⇒ Object
Specify the default format for the API's serializers.
May be :json
or :txt
(default).
121 122 123 |
# File 'lib/grape/api.rb', line 121 def default_format(new_format = nil) new_format ? set(:default_format, new_format.to_sym) : settings[:default_format] end |
.delete(paths = ['/'], options = {}, &block) ⇒ Object
393 394 395 |
# File 'lib/grape/api.rb', line 393 def delete(paths = ['/'], = {}, &block) route('DELETE', paths, , &block) end |
.desc(description, options = {}) ⇒ Object
Add a description to the next namespace or function.
115 116 117 |
# File 'lib/grape/api.rb', line 115 def desc(description, = {}) @last_description = .merge(description: description) end |
.do_not_route_head! ⇒ Object
Do not route HEAD requests to GET requests automatically
70 71 72 |
# File 'lib/grape/api.rb', line 70 def do_not_route_head! set(:do_not_route_head, true) end |
.do_not_route_options! ⇒ Object
Do not automatically route OPTIONS
75 76 77 |
# File 'lib/grape/api.rb', line 75 def set(:do_not_route_options, true) end |
.error_formatter(format, options) ⇒ Object
161 162 163 164 165 166 167 168 169 |
# File 'lib/grape/api.rb', line 161 def error_formatter(format, ) if .is_a?(Hash) && .has_key?(:with) formatter = [:with] else formatter = end settings.imbue(:error_formatters, format.to_sym => formatter) end |
.format(new_format = nil) ⇒ Object
Specify the format for the API's serializers.
May be :json
, :xml
, :txt
, etc.
127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/grape/api.rb', line 127 def format(new_format = nil) if new_format set(:format, new_format.to_sym) # define the default error formatters set(:default_error_formatter, Grape::ErrorFormatter::Base.formatter_for(new_format, {})) # define a single mime type mime_type = content_types[new_format.to_sym] raise Grape::Exceptions::MissingMimeType.new(new_format) unless mime_type settings.imbue(:content_types, new_format.to_sym => mime_type) else settings[:format] end end |
.formatter(content_type, new_formatter) ⇒ Object
Specify a custom formatter for a content-type.
142 143 144 |
# File 'lib/grape/api.rb', line 142 def formatter(content_type, new_formatter) settings.imbue(:formatters, content_type.to_sym => new_formatter) end |
.get(paths = ['/'], options = {}, &block) ⇒ Object
377 378 379 |
# File 'lib/grape/api.rb', line 377 def get(paths = ['/'], = {}, &block) route('GET', paths, , &block) end |
.head(paths = ['/'], options = {}, &block) ⇒ Object
389 390 391 |
# File 'lib/grape/api.rb', line 389 def head(paths = ['/'], = {}, &block) route('HEAD', paths, , &block) end |
.helpers(new_mod = nil, &block) ⇒ Object
Add helper methods that will be accessible from any endpoint within this namespace (and child namespaces).
When called without a block, all known helpers within this scope are included.
269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 |
# File 'lib/grape/api.rb', line 269 def helpers(new_mod = nil, &block) if block_given? || new_mod mod = settings.peek[:helpers] || Module.new if new_mod inject_api_helpers_to_mod(new_mod) if new_mod.is_a?(Helpers) mod.class_eval do include new_mod end end if block_given? inject_api_helpers_to_mod(mod) do mod.class_eval(&block) end end set(:helpers, mod) else mod = Module.new settings.stack.each do |s| mod.send :include, s[:helpers] if s[:helpers] end change! mod end end |
.http_basic(options = {}, &block) ⇒ Object
Add HTTP Basic authorization to the API.
308 309 310 311 |
# File 'lib/grape/api.rb', line 308 def http_basic( = {}, &block) [:realm] ||= "API Authorization" auth :http_basic, , &block end |
.http_digest(options = {}, &block) ⇒ Object
313 314 315 316 317 |
# File 'lib/grape/api.rb', line 313 def http_digest( = {}, &block) [:realm] ||= "API Authorization" [:opaque] ||= "secret" auth :http_digest, , &block end |
.imbue(key, value) ⇒ Object
Add to a configuration value for this namespace.
60 61 62 |
# File 'lib/grape/api.rb', line 60 def imbue(key, value) settings.imbue(key, value) end |
.middleware ⇒ Object
Retrieve an array of the middleware classes and arguments that are currently applied to the application.
457 458 459 460 461 462 |
# File 'lib/grape/api.rb', line 457 def middleware settings.stack.inject([]) do |a, s| a += s[:middleware] if s[:middleware] a end end |
.mount(mounts) ⇒ Object
319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 |
# File 'lib/grape/api.rb', line 319 def mount(mounts) mounts = { mounts => '/' } unless mounts.respond_to?(:each_pair) mounts.each_pair do |app, path| if app.respond_to?(:inherit_settings, true) app_settings = settings.clone mount_path = Rack::Mount::Utils.normalize_path([settings[:mount_path], path].compact.join("/")) app_settings.set :mount_path, mount_path app.inherit_settings(app_settings) end endpoints << Grape::Endpoint.new( settings.clone, method: :any, path: path, app: app ) end end |
.namespace(space = nil, options = {}, &block) ⇒ Object Also known as: group, resource, resources, segment
405 406 407 408 409 410 411 412 413 414 415 416 417 |
# File 'lib/grape/api.rb', line 405 def namespace(space = nil, = {}, &block) if space || block_given? previous_namespace_description = @namespace_description @namespace_description = (@namespace_description || {}).deep_merge(@last_description || {}) @last_description = nil nest(block) do set(:namespace, Namespace.new(space, )) if space end @namespace_description = previous_namespace_description else Namespace.joined_space_path(settings) end end |
.options(paths = ['/'], options = {}, &block) ⇒ Object
397 398 399 |
# File 'lib/grape/api.rb', line 397 def (paths = ['/'], = {}, &block) route('OPTIONS', paths, , &block) end |
.parser(content_type, new_parser) ⇒ Object
Specify a custom parser for a content-type.
147 148 149 |
# File 'lib/grape/api.rb', line 147 def parser(content_type, new_parser) settings.imbue(:parsers, content_type.to_sym => new_parser) end |
.patch(paths = ['/'], options = {}, &block) ⇒ Object
401 402 403 |
# File 'lib/grape/api.rb', line 401 def patch(paths = ['/'], = {}, &block) route('PATCH', paths, , &block) end |
.post(paths = ['/'], options = {}, &block) ⇒ Object
381 382 383 |
# File 'lib/grape/api.rb', line 381 def post(paths = ['/'], = {}, &block) route('POST', paths, , &block) end |
.prefix(prefix = nil) ⇒ Object
Define a root URL prefix for your entire API.
65 66 67 |
# File 'lib/grape/api.rb', line 65 def prefix(prefix = nil) prefix ? set(:root_prefix, prefix) : settings[:root_prefix] end |
.put(paths = ['/'], options = {}, &block) ⇒ Object
385 386 387 |
# File 'lib/grape/api.rb', line 385 def put(paths = ['/'], = {}, &block) route('PUT', paths, , &block) end |
.represent(model_class, options) ⇒ Object
Allows you to specify a default representation entity for a
class. This allows you to map your models to their respective
entities once and then simply call present
with the model.
Note that Grape will automatically go up the class ancestry to
try to find a representing entity, so if you, for example, define
an entity to represent Object
then all presented objects will
bubble up and utilize the entity provided on that represent
call.
245 246 247 248 |
# File 'lib/grape/api.rb', line 245 def represent(model_class, ) raise Grape::Exceptions::InvalidWithOptionForRepresent.new unless [:with] && [:with].is_a?(Class) imbue(:representations, model_class => [:with]) end |
.rescue_from(*exception_classes, options = {}) ⇒ Object
Allows you to rescue certain exceptions that occur to return a grape error rather than raising all the way to the server level.
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 |
# File 'lib/grape/api.rb', line 207 def rescue_from(*args, &block) if args.last.is_a?(Proc) handler = args.pop elsif block_given? handler = block end = args.last.is_a?(Hash) ? args.pop : {} handler ||= proc { [:with] } if .has_key?(:with) handler_type = !![:rescue_subclasses] ? :rescue_handlers : :base_only_rescue_handlers imbue handler_type, Hash[args.map { |arg| [arg, handler] }] imbue(:rescue_options, ) set(:rescue_all, true) if args.include?(:all) end |
.reset! ⇒ Object
22 23 24 25 26 27 28 |
# File 'lib/grape/api.rb', line 22 def reset! @settings = Grape::Util::HashStack.new @route_set = Rack::Mount::RouteSet.new @endpoints = [] @routes = nil reset_validations! end |
.route(methods, paths = ['/'], route_options = {}, &block) ⇒ Object
Defines a route that will be recognized by the Grape API.
349 350 351 352 353 354 355 356 357 358 359 |
# File 'lib/grape/api.rb', line 349 def route(methods, paths = ['/'], = {}, &block) = { method: methods, path: paths, route_options: (@namespace_description || {}).deep_merge(@last_description || {}).deep_merge( || {}) } endpoints << Grape::Endpoint.new(settings.clone, , &block) @last_description = nil reset_validations! end |
.route_param(param, options = {}, &block) ⇒ Object
Thie method allows you to quickly define a parameter route segment in your API.
424 425 426 427 428 |
# File 'lib/grape/api.rb', line 424 def route_param(param, = {}, &block) = .dup [:requirements] = { param.to_sym => [:requirements] } if [:requirements].is_a?(Regexp) namespace(":#{param}", , &block) end |
.scope(name = nil, &block) ⇒ Object
Create a scope without affecting the URL.
438 439 440 |
# File 'lib/grape/api.rb', line 438 def scope(name = nil, &block) nest(block) end |
.set(key, value) ⇒ Object
Set a configuration value for this namespace.
51 52 53 |
# File 'lib/grape/api.rb', line 51 def set(key, value) settings[key.to_sym] = value end |
.use(middleware_class, *args, &block) ⇒ Object
Apply a custom middleware to the API. Applies to the current namespace and any children, but not parents.
448 449 450 451 452 |
# File 'lib/grape/api.rb', line 448 def use(middleware_class, *args, &block) arr = [middleware_class, *args] arr << block if block_given? imbue(:middleware, [arr]) end |
.version(*args, &block) ⇒ Object
Specify an API version.
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/grape/api.rb', line 96 def version(*args, &block) if args.any? = args.pop if args.last.is_a? Hash ||= {} = { using: :path }.merge() raise Grape::Exceptions::MissingVendorOption.new if [:using] == :header && !.has_key?(:vendor) @versions = versions | args nest(block) do set(:version, args) set(:version_options, ) end end @versions.last unless @versions.nil? end |
Instance Method Details
#call(env) ⇒ Object
536 537 538 539 540 |
# File 'lib/grape/api.rb', line 536 def call(env) status, headers, body = @route_set.call(env) headers.delete('X-Cascade') unless cascade? [status, headers, body] end |
#cascade? ⇒ Boolean
Some requests may return a HTTP 404 error if grape cannot find a matching route. In this case, Rack::Mount adds a X-Cascade header to the response and sets it to 'pass', indicating to grape's parents they should keep looking for a matching route on other resources.
In some applications (e.g. mounting grape on rails), one might need to trap errors from reaching upstream. This is effectivelly done by unsetting X-Cascade. Default :cascade is true.
550 551 552 553 554 |
# File 'lib/grape/api.rb', line 550 def cascade? return !!self.class.settings[:cascade] if self.class.settings.has_key?(:cascade) return !!self.class.settings[:version_options][:cascade] if self.class.settings[:version_options] && self.class.settings[:version_options].has_key?(:cascade) true end |