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, **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.

  • options (Hash)

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

Options Hash (**options):

  • path (String or Array)

    the path to this endpoint, within the current scope.

  • method (String or Array)

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

  • route_options (Hash)

Yields:

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



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/grape/endpoint.rb', line 51

def initialize(new_settings, **options, &block)
  self.inheritable_setting = new_settings.point_in_time_copy

  # now +namespace_stackable(:declared_params)+ contains all params defined for
  # this endpoint and its parents, but later it will be cleaned up,
  # see +reset_validations!+ in lib/grape/dsl/validations.rb
  inheritable_setting.route[:declared_params] = inheritable_setting.namespace_stackable[:declared_params].flatten
  inheritable_setting.route[:saved_validations] = inheritable_setting.namespace_stackable[:validations].dup

  inheritable_setting.namespace_stackable[:representations] ||= []
  inheritable_setting.namespace_inheritable[:default_error_status] ||= 500

  @options = options
  @options[:path] = Array(@options[:path])
  @options[:path] << '/' if @options[:path].empty?
  @options[:method] = Array(@options[:method])
  @config = Options.new(**options)

  @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



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

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?



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

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

#call(env) ⇒ Object



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

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

#call!(env) ⇒ Object



126
127
128
129
130
131
132
# File 'lib/grape/endpoint.rb', line 126

def call!(env)
  env[Grape::Env::API_ENDPOINT] = self
  @env = env
  # this adds the helpers only to the instance
  singleton_class.include(@helpers) if @helpers
  @app.call(env)
end

#inherit_settings(namespace_stackable) ⇒ Object

Update our settings from a given set of stackable parameters. Used when the endpoint’s API is mounted under another one.



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

def inherit_settings(namespace_stackable)
  parent_validations = namespace_stackable[:validations]
  inheritable_setting.route[:saved_validations].concat(parent_validations) if parent_validations.any?
  parent_declared_params = namespace_stackable[:declared_params]
  inheritable_setting.route[:declared_params].concat(parent_declared_params.flatten) if parent_declared_params.any?

  endpoints&.each { |e| e.inherit_settings(namespace_stackable) }
end

#inspectObject

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



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

def inspect
  return super unless env

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

#loggerObject

The logger configured on the API this endpoint belongs to. Available inside route handlers, before/after/after_validation/finally filters, and rescue_from blocks.



23
24
25
# File 'lib/grape/endpoint.rb', line 23

def logger
  config.for.logger
end

#mount_in(router) ⇒ Object



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

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.namespace_inheritable[:do_not_route_head] || route.request_method != Rack::GET

    route.dup.then do |head_route|
      head_route.convert_to_head_request!
      router.append(head_route.apply(self))
    end
  end
end

#namespaceObject



118
119
120
# File 'lib/grape/endpoint.rb', line 118

def namespace
  @namespace ||= Namespace.joined_space_path(inheritable_setting.namespace_stackable[:namespace])
end

#reset_routes!Object



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

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

#routesObject



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

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