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
# 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] = [] unless inheritable_setting.namespace_stackable[:representations]
  inheritable_setting.namespace_inheritable[:default_error_status] = 500 unless inheritable_setting.namespace_inheritable[:default_error_status]

  @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
end

Instance Attribute Details

#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

#call(env) ⇒ Object



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

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

#call!(env) ⇒ Object



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

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

#endpointsObject

Return the collection of endpoints within this endpoint. This is the case when an Grape::API mounts another Grape::API.



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

def endpoints
  @endpoints ||= options[:app].respond_to?(:endpoints) ? options[:app].endpoints : nil
end

#equals?(endpoint) ⇒ Boolean

Returns:

  • (Boolean)


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

def equals?(endpoint)
  (options == endpoint.options) && (inheritable_setting.to_hash == endpoint.inheritable_setting.to_hash)
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.



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

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.



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

def inspect
  return super unless env

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

#mount_in(router) ⇒ Object



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

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 unless !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



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

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

#reset_routes!Object



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

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

#routesObject



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

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