Class: Grape::Endpoint

Inherits:
Object
  • Object
show all
Extended by:
Forwardable, Testing::ClassMethods
Includes:
DSL::Headers, DSL::InsideRoute, DSL::Settings, Testing::RunBeforeEach
Defined in:
lib/grape/endpoint.rb,
lib/grape/endpoint/options.rb

Overview

An Endpoint is the proxy scope in which all routing blocks are executed. In other words, any methods on the instance level of this class may be called from inside a get, post, etc.

Defined Under Namespace

Classes: Options

Constant Summary

Constants included from DSL::InsideRoute

DSL::InsideRoute::MethodNotYetAvailable

Instance Attribute Summary collapse

Attributes included from DSL::Settings

#inheritable_setting

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Testing::ClassMethods

before_each, reset_before_each, run_before_each

Methods included from DSL::InsideRoute

#api_format, #body, #configuration, #content_type, #context, #error!, #http_version, #redirect, #return_no_content, #route, #sendfile, #status, #stream, #version

Methods included from DSL::Entity

#entity_class_for_obj, #present

Methods included from DSL::Declared

#declared

Methods included from DSL::Headers

#header

Methods included from DSL::Settings

#global_setting, #namespace_setting, #route_setting, #top_level_setting

Constructor Details

#initialize(new_settings, http_methods:, path:, api:, app: nil, params: {}, requirements: nil, anchor: true, **options) { ... } ⇒ Endpoint

Note:

This happens at the time of API definition, so in this context the

Create a new endpoint. endpoint does not know if it will be mounted under a different endpoint.

Parameters:

  • new_settings (InheritableSetting)

    settings to determine the params, validations, and other properties from.

  • http_methods (String or Array)

    which HTTP method(s) can be used to reach this endpoint.

  • path (String or Array)

    the path to this endpoint, within the current scope.

  • api (Grape::API)

    the API this endpoint belongs to. Exposed as #api.

  • app (#call, nil) (defaults to: nil)

    the Rack app or Grape API mounted at this endpoint; nil for a plain block endpoint. Exposed as #mounted_app.

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

    the declared params for this endpoint, keyed by name. Kept out of route_options and read via config.params.

  • requirements (Hash, nil) (defaults to: nil)

    regular-expression constraints for named path params. Read via config.requirements.

  • anchor (Boolean) (defaults to: true)

    whether the route anchors to the whole path (default true). Read via config.anchor.

  • options (Hash)

    attributes of this endpoint, normalized into a Grape::Endpoint::Options value object.

Options Hash (**options):

  • route_options (Hash)

Yields:

  • a block defining what your API should do when this endpoint is hit



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/grape/endpoint.rb', line 69

def initialize(new_settings, http_methods:, path:, api:, app: nil, params: {}, requirements: nil, anchor: true, **options, &block)
  self.inheritable_setting = new_settings.point_in_time_copy_for_endpoint

  @options = options
  @config = Options.new(http_methods:, path:, api:, app:, params:, requirements:, anchor:, **options)
  # +:app+ is still surfaced on the public options Hash for backwards
  # compatibility (e.g. grape-swagger); prefer the +mounted_app+ reader.
  @options[:app] = app if app

  @status = nil
  @stream = nil
  @body = nil
  @source = self.class.block_to_unbound_method(block)
  @before_filter_passed = false
  @options_route_enabled = false
  @endpoints = @config.app.endpoints if @config.app.respond_to?(:endpoints)
end

Instance Attribute Details

#endpointsObject (readonly)

Returns the value of attribute endpoints.



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

def endpoints
  @endpoints
end

#envObject (readonly)

Returns the value of attribute env.



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

def env
  @env
end

#optionsObject (readonly)

Returns the value of attribute options.



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

def options
  @options
end

#options_route_enabledObject

Returns the value of attribute options_route_enabled.



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

def options_route_enabled
  @options_route_enabled
end

#requestObject (readonly)

Returns the value of attribute request.



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

def request
  @request
end

#sourceObject (readonly)

Returns the value of attribute source.



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

def source
  @source
end

Class Method Details

.block_to_unbound_method(block) ⇒ Object



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

def block_to_unbound_method(block)
  return unless block

  define_method :temp_unbound_method, block
  method = instance_method(:temp_unbound_method)
  remove_method :temp_unbound_method
  method
end

Instance Method Details

#==(other) ⇒ Object Also known as: eql?



135
136
137
138
139
# File 'lib/grape/endpoint.rb', line 135

def ==(other)
  other.is_a?(self.class) &&
    config == other.config &&
    inheritable_setting == other.inheritable_setting
end

#call(env) ⇒ Object



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

def call(env)
  @prototype.dup.call!(env)
end

#call!(env) ⇒ Object



129
130
131
132
133
# File 'lib/grape/endpoint.rb', line 129

def call!(env)
  env[Grape::Env::API_ENDPOINT] = self
  @env = env
  @app.call(env)
end

#hashObject

Mirrors #==. The class stays out: #== admits a subclass instance through is_a?, and such a pair must hash alike. The block (#source) is not part of either, matching the long-standing duplicate-route check in DSL::Routing#route.



146
147
148
# File 'lib/grape/endpoint.rb', line 146

def hash
  [config, inheritable_setting].hash
end

#inherit_settings(settings) ⇒ Object

Update our settings from a given parent settings instance. Used when the endpoint's API is mounted under another one.

Parameters:



90
91
92
93
# File 'lib/grape/endpoint.rb', line 90

def inherit_settings(settings)
  inheritable_setting.inherit_route_params(settings)
  endpoints&.each { |e| e.inherit_settings(settings) }
end

#inspectObject

The purpose of this override is solely for stripping internals when an error occurs while calling an endpoint through an api. See https://github.com/ruby-grape/grape/issues/2398 Otherwise, it calls super.



153
154
155
156
157
# File 'lib/grape/endpoint.rb', line 153

def inspect
  return super unless env

  "#{self.class} in '#{route.origin}' endpoint"
end

#mount_in(router) ⇒ Object



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/grape/endpoint.rb', line 105

def mount_in(router)
  if endpoints
    compile!
    return endpoints.each { |e| e.mount_in(router) }
  end

  reset_routes!
  compile!
  routes.each do |route|
    router.append(route.apply(self))
    next if inheritable_setting.do_not_route_head? || route.request_method != Rack::GET

    router.append(route.to_head.apply(self))
  end
end

#mounted_appObject

The Rack app or Grape API mounted at this endpoint, or nil for a plain block endpoint. Prefer this over options[:app], which is retained only for backwards compatibility.



31
32
33
# File 'lib/grape/endpoint.rb', line 31

def mounted_app
  config.app
end

#namespaceObject



121
122
123
# File 'lib/grape/endpoint.rb', line 121

def namespace
  @namespace ||= inheritable_setting.namespace_path
end

#reset_routes!Object



99
100
101
102
103
# File 'lib/grape/endpoint.rb', line 99

def reset_routes!
  endpoints&.each(&:reset_routes!)
  @namespace = nil
  @routes = nil
end

#routesObject



95
96
97
# File 'lib/grape/endpoint.rb', line 95

def routes
  @routes ||= endpoints&.flat_map(&:routes) || to_routes
end