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: 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!]).freeze
Boolean =
Virtus::Attribute::Boolean

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.base_instanceObject

Returns the value of attribute base_instance.



12
13
14
# File 'lib/grape/api.rb', line 12

def base_instance
  @base_instance
end

.instancesObject

Returns the value of attribute instances.



12
13
14
# File 'lib/grape/api.rb', line 12

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



65
66
67
# File 'lib/grape/api.rb', line 65

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

.compile!Object



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

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.



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

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



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

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



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

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



29
30
31
32
33
34
# File 'lib/grape/api.rb', line 29

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:



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

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



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

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.



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

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



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

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



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

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



101
102
103
104
105
# File 'lib/grape/api.rb', line 101

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:



107
108
109
# File 'lib/grape/api.rb', line 107

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:



111
112
113
# File 'lib/grape/api.rb', line 111

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