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.



430
431
432
433
434
435
436
437
# File 'lib/grape/api.rb', line 430

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.



385
386
387
# File 'lib/grape/api.rb', line 385

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



327
328
329
# File 'lib/grape/api.rb', line 327

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

.after_validation(&block) ⇒ Object



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

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.



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

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



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

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'



154
155
156
# File 'lib/grape/api.rb', line 154

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

.default_error_formatter(new_formatter = nil) ⇒ Object

Specify a default error formatter.



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

def default_error_formatter(new_formatter = nil)
  new_formatter ? set(:default_error_formatter, new_formatter) : settings[:default_error_formatter]
end

.default_error_status(new_status = nil) ⇒ Object

Specify the default status code for errors.



159
160
161
# File 'lib/grape/api.rb', line 159

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



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

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



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

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, :xml, :txt, etc.



129
130
131
132
133
134
135
136
# File 'lib/grape/api.rb', line 129

def format(new_format = nil)
  if new_format
    set(:format, new_format.to_sym)
    set(:default_error_formatter, Grape::ErrorFormatter::Base.formatter_for(new_format, {}))
  else
    settings[:format]
  end
end

.formatter(content_type, new_formatter) ⇒ Object

Specify a custom formatter for a content-type.



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

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

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



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

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

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



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

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:

  • new_mod (Module) (defaults to: nil)

    optional module of methods to include

  • block (Block)

    optional block of methods to include



235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
# File 'lib/grape/api.rb', line 235

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.



269
270
271
272
# File 'lib/grape/api.rb', line 269

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

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



274
275
276
277
278
# File 'lib/grape/api.rb', line 274

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.



380
381
382
# File 'lib/grape/api.rb', line 380

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

.mount(mounts) ⇒ Object



280
281
282
283
284
285
286
287
288
289
290
291
292
293
# File 'lib/grape/api.rb', line 280

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



339
340
341
342
343
344
345
346
347
348
349
350
351
# File 'lib/grape/api.rb', line 339

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



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

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

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



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

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

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



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

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



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

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)


211
212
213
214
# File 'lib/grape/api.rb', line 211

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.



180
181
182
183
184
185
186
187
188
189
# File 'lib/grape/api.rb', line 180

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.



307
308
309
310
311
312
313
314
315
316
317
# File 'lib/grape/api.rb', line 307

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.



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

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.



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

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



439
440
441
# File 'lib/grape/api.rb', line 439

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