Class: Grape::API

Inherits:
Object
  • Object
show all
Extended by:
ActiveSupport::Autoload
Defined in:
lib/grape/api.rb,
lib/grape.rb,
lib/grape/api/helpers.rb,
lib/grape/api/instance.rb,
lib/grape/validations/validators/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 Classes: Boolean, Instance

Constant Summary collapse

NON_OVERRIDABLE =

Class methods that we want to call on the API rather than on the API object

(Class.new.methods + %i[call call! configuration compile! inherited]).freeze

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.base_instanceObject

Returns the value of attribute base_instance


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

def base_instance
  @base_instance
end

.instancesObject

Returns the value of attribute instances


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

def instances
  @instances
end

Class Method Details

.call(*args, &block) ⇒ Object

This is the interface point between Rack and Grape; it accepts a request from Rack and ultimately returns an array of three values: the status, the headers, and the body. See [the rack specification] (www.rubydoc.info/github/rack/rack/master/file/SPEC) for more. NOTE: This will only be called on an API directly mounted on RACK


67
68
69
# File 'lib/grape/api.rb', line 67

def call(*args, &block)
  instance_for_rack.call(*args, &block)
end

.compile!Object


126
127
128
129
# File 'lib/grape/api.rb', line 126

def compile!
  require 'grape/eager_load'
  instance_for_rack.compile! # See API::Instance.compile!
end

.configureObject

Configure an API from the outside. If a block is given, it'll pass a configuration hash to the block which you can use to configure your API. If no block is given, returns the configuration hash. The configuration set here is accessible from inside an API with `configuration` as normal.


52
53
54
55
56
57
58
59
60
# File 'lib/grape/api.rb', line 52

def configure
  config = @base_instance.configuration
  if block_given?
    yield config
    self
  else
    config
  end
end

.const_missing(*args) ⇒ Object

Alleviates problems with autoloading by tring to search for the constant


81
82
83
84
85
86
87
# File 'lib/grape/api.rb', line 81

def const_missing(*args)
  if base_instance.const_defined?(*args)
    base_instance.const_get(*args)
  else
    super
  end
end

.inherited(api, base_instance_parent = Grape::API::Instance) ⇒ Object

When inherited, will create a list of all instances (times the API was mounted) It will listen to the setup required to mount that endpoint, and replicate it on any new instance


23
24
25
26
27
# File 'lib/grape/api.rb', line 23

def inherited(api, base_instance_parent = Grape::API::Instance)
  api.initial_setup(base_instance_parent)
  api.override_all_methods!
  make_inheritable(api)
end

.initial_setup(base_instance_parent) ⇒ Object

Initialize the instance variables on the remountable class, and the base_instance an instance that will be used to create the set up but will not be mounted


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

def initial_setup(base_instance_parent)
  @instances = []
  @setup = []
  @base_parent = base_instance_parent
  @base_instance = mount_instance
end

.make_inheritable(api) ⇒ Object

Allows an API to itself be inheritable:


72
73
74
75
76
77
78
# File 'lib/grape/api.rb', line 72

def make_inheritable(api)
  # When a child API inherits from a parent API.
  def api.inherited(child_api)
    # The instances of the child API inherit from the instances of the parent API
    Grape::API.inherited(child_api, base_instance)
  end
end

.method_missing(method, *args, &block) ⇒ Object


117
118
119
120
121
122
123
124
# File 'lib/grape/api.rb', line 117

def method_missing(method, *args, &block)
  # If there's a missing method, it may be defined on the base_instance instead.
  if respond_to_missing?(method)
    base_instance.send(method, *args, &block)
  else
    super
  end
end

.mount_instance(**opts) ⇒ Object

The remountable class can have a configuration hash to provide some dynamic class-level variables. For instance, a descripcion could be done using: `desc configuration` if it may vary depending on where the endpoint is mounted. Use with care, if you find yourself using configuration too much, you may actually want to provide a new API rather than remount it.


93
94
95
96
97
98
99
# File 'lib/grape/api.rb', line 93

def mount_instance(**opts)
  instance = Class.new(@base_parent)
  instance.configuration = Grape::Util::EndpointConfiguration.new(opts[:configuration] || {})
  instance.base = self
  replay_setup_on(instance)
  instance
end

.new(*args, &block) ⇒ Object

Rather than initializing an object of type Grape::API, create an object of type Instance


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

def new(*args, &block)
  base_instance.new(*args, &block)
end

.override_all_methods!Object

Redefines all methods so that are forwarded to add_setup and be recorded


39
40
41
42
43
44
45
# File 'lib/grape/api.rb', line 39

def override_all_methods!
  (base_instance.methods - NON_OVERRIDABLE).each do |method_override|
    define_singleton_method(method_override) do |*args, &block|
      add_setup(method_override, *args, &block)
    end
  end
end

.replay_setup_on(instance) ⇒ Object

Replays the set up to produce an API as defined in this class, can be called on classes that inherit from Grape::API


103
104
105
106
107
# File 'lib/grape/api.rb', line 103

def replay_setup_on(instance)
  @setup.each do |setup_step|
    replay_step_on(instance, setup_step)
  end
end

.respond_to?(method, include_private = false) ⇒ Boolean

Returns:


109
110
111
# File 'lib/grape/api.rb', line 109

def respond_to?(method, include_private = false)
  super(method, include_private) || base_instance.respond_to?(method, include_private)
end

.respond_to_missing?(method, include_private = false) ⇒ Boolean

Returns:


113
114
115
# File 'lib/grape/api.rb', line 113

def respond_to_missing?(method, include_private = false)
  base_instance.respond_to?(method, include_private)
end