Class: Grape::API

Inherits:
Object
  • Object
show all
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.

Constant Summary collapse

Boolean =
Virtus::Attribute::Boolean

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Validations::ClassMethods

document_attribute, params, reset_validations!

Constructor Details

#initializeAPI

Returns a new instance of API.



418
419
420
421
422
423
424
425
# File 'lib/grape/api.rb', line 418

def initialize
  @route_set = Rack::Mount::RouteSet.new
  self.class.endpoints.each do |endpoint|
    endpoint.mount_in(@route_set)
  end
  add_head_not_allowed_methods
  @route_set.freeze
end

Class Attribute Details

.endpointsObject (readonly)

Returns the value of attribute endpoints.



20
21
22
# File 'lib/grape/api.rb', line 20

def endpoints
  @endpoints
end

.instanceObject (readonly)

Returns the value of attribute instance.



22
23
24
# File 'lib/grape/api.rb', line 22

def instance
  @instance
end

.logger(logger = nil) ⇒ Object



24
25
26
27
28
29
30
# File 'lib/grape/api.rb', line 24

def logger(logger = nil)
  if logger
    @logger = logger
  else
    @logger ||= Logger.new($stdout)
  end
end

.mountingsObject (readonly)

Returns the value of attribute mountings.



21
22
23
# File 'lib/grape/api.rb', line 21

def mountings
  @mountings
end

.route_setObject (readonly)

Returns the value of attribute route_set.



15
16
17
# File 'lib/grape/api.rb', line 15

def route_set
  @route_set
end

.routesObject (readonly)

An array of API routes.



373
374
375
# File 'lib/grape/api.rb', line 373

def routes
  @routes
end

.settingsObject (readonly)

Returns the value of attribute settings.



18
19
20
# File 'lib/grape/api.rb', line 18

def settings
  @settings
end

.versionsObject (readonly)

Returns the value of attribute versions.



16
17
18
# File 'lib/grape/api.rb', line 16

def versions
  @versions
end

Class Method Details

.after(&block) ⇒ Object



315
316
317
# File 'lib/grape/api.rb', line 315

def after(&block)
  imbue(:afters, [block])
end

.after_validation(&block) ⇒ Object



311
312
313
# File 'lib/grape/api.rb', line 311

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.



245
246
247
248
249
250
251
# File 'lib/grape/api.rb', line 245

def auth(type = nil, options = {}, &block)
  if type
    set(:auth, {:type => type.to_sym, :proc => block}.merge(options))
  else
    settings[:auth]
  end
end

.before(&block) ⇒ Object



307
308
309
# File 'lib/grape/api.rb', line 307

def before(&block)
  imbue(:befores, [block])
end

.call(env) ⇒ Object



49
50
51
52
# File 'lib/grape/api.rb', line 49

def call(env)
  compile unless instance
  call!(env)
end

.call!(env) ⇒ Object



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

def call!(env)
  instance.call(env)
end

.change!Object



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

def change!
  @instance = nil
end

.compileObject



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

def compile
  @instance = self.new
end

.content_type(key, val) ⇒ Object

Specify additional content-types, e.g.:

content_type :xls, 'application/vnd.ms-excel'


144
145
146
# File 'lib/grape/api.rb', line 144

def content_type(key, val)
  settings.imbue(:content_types, key.to_sym => val)
end

.default_error_status(new_status = nil) ⇒ Object

Specify the default status code for errors.



149
150
151
# File 'lib/grape/api.rb', line 149

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



123
124
125
# File 'lib/grape/api.rb', line 123

def default_format(new_format = nil)
  new_format ? set(:default_format, new_format.to_sym) : settings[:default_format]
end

.delete(paths = ['/'], options = {}, &block) ⇒ Object



323
# File 'lib/grape/api.rb', line 323

def delete(paths = ['/'], options = {}, &block); route('DELETE', paths, options, &block) end

.desc(description, options = {}) ⇒ Object

Add a description to the next namespace or function.



117
118
119
# File 'lib/grape/api.rb', line 117

def desc(description, options = {})
  @last_description = options.merge(:description => description)
end

.error_formatter(format, new_formatter) ⇒ Object



138
139
140
# File 'lib/grape/api.rb', line 138

def error_formatter(format, new_formatter)
  settings.imbue(:error_formatters, format.to_sym => new_formatter)
end

.format(new_format = nil) ⇒ Object

Specify the format for the API’s serializers. May be ‘:json` or `:txt`.



129
130
131
# File 'lib/grape/api.rb', line 129

def format(new_format = nil)
  new_format ? set(:format, new_format.to_sym) : settings[:format]
end

.formatter(content_type, new_formatter) ⇒ Object

Specify a custom formatter for a content-type.



134
135
136
# File 'lib/grape/api.rb', line 134

def formatter(content_type, new_formatter)
  settings.imbue(:formatters, content_type.to_sym => new_formatter)
end

.get(paths = ['/'], options = {}, &block) ⇒ Object



319
# File 'lib/grape/api.rb', line 319

def get(paths = ['/'], options = {}, &block); route('GET', paths, options, &block) end

.head(paths = ['/'], options = {}, &block) ⇒ Object



322
# File 'lib/grape/api.rb', line 322

def head(paths = ['/'], options = {}, &block); route('HEAD', paths, options, &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.

Examples:

Define some helpers.

class ExampleAPI < Grape::API
  helpers do
    def current_user
      User.find_by_id(params[:token])
    end
  end
end

Parameters:

  • mod (Module)

    optional module of methods to include

  • &block (Block)

    optional block of methods to include



223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
# File 'lib/grape/api.rb', line 223

def helpers(new_mod = nil, &block)
  if block_given? || new_mod
    mod = settings.peek[:helpers] || Module.new
    if new_mod
      mod.class_eval do
        include new_mod
      end
    end
    mod.class_eval &block if block_given?
    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.

Parameters:

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

    A hash of options.

Options Hash (options):

  • :realm (String)

    “API Authorization” The HTTP Basic realm.



257
258
259
260
# File 'lib/grape/api.rb', line 257

def http_basic(options = {}, &block)
  options[:realm] ||= "API Authorization"
  auth :http_basic, options, &block
end

.http_digest(options = {}, &block) ⇒ Object



262
263
264
265
266
# File 'lib/grape/api.rb', line 262

def http_digest(options = {}, &block)
  options[:realm] ||= "API Authorization"
  options[:opaque] ||= "secret"
  auth :http_digest, options, &block
end

.imbue(key, value) ⇒ Object

Add to a configuration value for this namespace.

Parameters:

  • key (Symbol)

    The key of the configuration variable.

  • value (Object)

    The value to which to set the configuration variable.



71
72
73
# File 'lib/grape/api.rb', line 71

def imbue(key, value)
  settings.imbue(key, value)
end

.middlewareObject

Retrieve an array of the middleware classes and arguments that are currently applied to the application.



368
369
370
# File 'lib/grape/api.rb', line 368

def middleware
  settings.stack.inject([]){|a,s| a += s[:middleware] if s[:middleware]; a}
end

.mount(mounts) ⇒ Object



268
269
270
271
272
273
274
275
276
277
278
279
280
281
# File 'lib/grape/api.rb', line 268

def mount(mounts)
  mounts = {mounts => '/'} unless mounts.respond_to?(:each_pair)
  mounts.each_pair do |app, path|
    if app.respond_to?(:inherit_settings)
      app.inherit_settings(settings.clone)
    end

    endpoints << Grape::Endpoint.new(settings.clone,
      :method => :any,
      :path => path,
      :app => app
    )
  end
end

.namespace(space = nil, &block) ⇒ Object Also known as: group, resource, resources, segment



327
328
329
330
331
332
333
334
335
336
337
338
339
# File 'lib/grape/api.rb', line 327

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, space.to_s) if space
    end
    @namespace_description = previous_namespace_description
  else
    Rack::Mount::Utils.normalize_path(settings.stack.map{|s| s[:namespace]}.join('/'))
  end
end

.options(paths = ['/'], options = {}, &block) ⇒ Object



324
# File 'lib/grape/api.rb', line 324

def options(paths = ['/'], options = {}, &block); route('OPTIONS', paths, options, &block) end

.patch(paths = ['/'], options = {}, &block) ⇒ Object



325
# File 'lib/grape/api.rb', line 325

def patch(paths = ['/'], options = {}, &block); route('PATCH', paths, options, &block) end

.post(paths = ['/'], options = {}, &block) ⇒ Object



320
# File 'lib/grape/api.rb', line 320

def post(paths = ['/'], options = {}, &block); route('POST', paths, options, &block) end

.prefix(prefix = nil) ⇒ Object

Define a root URL prefix for your entire API.



77
78
79
# File 'lib/grape/api.rb', line 77

def prefix(prefix = nil)
  prefix ? set(:root_prefix, prefix) : settings[:root_prefix]
end

.put(paths = ['/'], options = {}, &block) ⇒ Object



321
# File 'lib/grape/api.rb', line 321

def put(paths = ['/'], options = {}, &block); route('PUT', paths, options, &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.

Examples:

class ExampleAPI < Grape::API
  represent User, :with => Entity::User

  get '/me' do
    present current_user # :with => Entity::User is assumed
  end
end

Parameters:

  • model_class (Class)

    The model class that will be represented.

  • options (Hash)

    a customizable set of options

Options Hash (options):

  • :with (Class)

    The entity class that will represent the model.

Raises:

  • (ArgumentError)


201
202
203
204
# File 'lib/grape/api.rb', line 201

def represent(model_class, options)
  raise ArgumentError, "You must specify an entity class in the :with option." unless options[:with] && options[:with].is_a?(Class)
  imbue(:representations, model_class => options[: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.

Examples:

Rescue from custom exceptions

class ExampleAPI < Grape::API
  class CustomError < StandardError; end

  rescue_from CustomError
end

Parameters:

  • exception_classes (Array)

    A list of classes that you want to rescue, or the symbol :all to rescue from all exceptions.

  • block (Block)

    Execution block to handle the given exception.

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

    Options for the rescue usage.

Options Hash (options):

  • :backtrace (Boolean)

    Include a backtrace in the rescue response.



170
171
172
173
174
175
176
177
178
179
# File 'lib/grape/api.rb', line 170

def rescue_from(*args, &block)
  if block_given?
    args.each do |arg|
      imbue(:rescue_handlers, { arg => block })
    end
  end
  imbue(:rescue_options, args.pop) if args.last.is_a?(Hash)
  set(:rescue_all, true) and return if args.include?(:all)
  imbue(:rescued_errors, args)
end

.reset!Object



32
33
34
35
36
37
38
39
# File 'lib/grape/api.rb', line 32

def reset!
  @settings  = Grape::Util::HashStack.new
  @route_set = Rack::Mount::RouteSet.new
  @endpoints = []
  @mountings = []
  @routes = nil
  reset_validations!
end

.route(methods, paths = ['/'], route_options = {}, &block) ⇒ Object

Defines a route that will be recognized by the Grape API.

Examples:

Defining a basic route.

class MyAPI < Grape::API
  route(:any, '/hello') do
    {:hello => 'world'}
  end
end

Parameters:

  • methods (HTTP Verb)

    One or more HTTP verbs that are accepted by this route. Set to ‘:any` if you want any verb to be accepted.

  • paths (String) (defaults to: ['/'])

    One or more strings representing the URL segment(s) for this route.



295
296
297
298
299
300
301
302
303
304
305
# File 'lib/grape/api.rb', line 295

def route(methods, paths = ['/'], route_options = {}, &block)
  endpoint_options = {
    :method => methods,
    :path => paths,
    :route_options => (@namespace_description || {}).deep_merge(@last_description || {}).deep_merge(route_options || {})
  }
  endpoints << Grape::Endpoint.new(settings.clone, endpoint_options, &block)

  @last_description = nil
  reset_validations!
end

.scope(name = nil, &block) ⇒ Object

Create a scope without affecting the URL.

Parameters:

  • name (Symbol) (defaults to: nil)

    Purely placebo, just allows to to name the scope to make the code more readable.



349
350
351
# File 'lib/grape/api.rb', line 349

def scope(name = nil, &block)
  nest(block)
end

.set(key, value) ⇒ Object

Set a configuration value for this namespace.

Parameters:

  • key (Symbol)

    The key of the configuration variable.

  • value (Object)

    The value to which to set the configuration variable.



62
63
64
# File 'lib/grape/api.rb', line 62

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.

Parameters:

  • middleware_class (Class)

    The class of the middleware you’d like to inject.



359
360
361
362
363
# File 'lib/grape/api.rb', line 359

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.

Examples:

API with legacy support.

class MyAPI < Grape::API
  version 'v2'

  get '/main' do
    {:some => 'data'}
  end

  version 'v1' do
    get '/main' do
      {:legacy => 'data'}
    end
  end
end


98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/grape/api.rb', line 98

def version(*args, &block)
  if args.any?
    options = args.pop if args.last.is_a? Hash
    options ||= {}
    options = {:using => :path}.merge!(options)

    raise ArgumentError, "Must specify :vendor option." if options[:using] == :header && !options.has_key?(:vendor)

    @versions = versions | args
    nest(block) do
      set(:version, args)
      set(:version_options, options)
    end
  end

  @versions.last unless @versions.nil?
end

Instance Method Details

#call(env) ⇒ Object



427
428
429
# File 'lib/grape/api.rb', line 427

def call(env)
  @route_set.call(env)
end