Class: Grape::Endpoint

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
DSL::Headers, DSL::InsideRoute, DSL::Settings
Defined in:
lib/grape/endpoint.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.

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 DSL::InsideRoute

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

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

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



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/grape/endpoint.rb', line 60

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]

  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])

  @status = nil
  @stream = nil
  @body = nil
  @source = self.class.block_to_unbound_method(block)
  @before_filter_passed = false
  @endpoints = @options[:app].endpoints if @options[: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

#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

.before_each(new_setup = false, &block) ⇒ Object



20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/grape/endpoint.rb', line 20

def before_each(new_setup = false, &block)
  @before_each ||= []
  if new_setup == false
    return @before_each unless block

    @before_each << block
  elsif new_setup
    @before_each = [new_setup]
  else
    @before_each.clear
  end
end

.block_to_unbound_method(block) ⇒ Object



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

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

.run_before_each(endpoint) ⇒ Object



33
34
35
36
# File 'lib/grape/endpoint.rb', line 33

def run_before_each(endpoint)
  superclass.run_before_each(endpoint) unless self == Endpoint
  before_each.each { |blk| blk.call(endpoint) }
end

Instance Method Details

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



142
143
144
145
146
# File 'lib/grape/endpoint.rb', line 142

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

#call(env) ⇒ Object



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

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

#call!(env) ⇒ Object



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

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.



88
89
90
91
92
93
94
95
# File 'lib/grape/endpoint.rb', line 88

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.



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

def inspect
  return super unless env

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

#mount_in(router) ⇒ Object



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/grape/endpoint.rb', line 107

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



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

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

#reset_routes!Object



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

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

#routesObject



97
98
99
# File 'lib/grape/endpoint.rb', line 97

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