Class: Grape::Endpoint
- Includes:
- 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.
Instance Attribute Summary collapse
-
#block ⇒ Object
Returns the value of attribute block.
-
#env ⇒ Object
readonly
Returns the value of attribute env.
-
#headers ⇒ Object
readonly
Returns the value of attribute headers.
-
#options ⇒ Object
Returns the value of attribute options.
-
#params ⇒ Object
readonly
Returns the value of attribute params.
-
#request ⇒ Object
readonly
Returns the value of attribute request.
-
#source ⇒ Object
Returns the value of attribute source.
Attributes included from DSL::Settings
#inheritable_setting, #top_level_setting
Class Method Summary collapse
- .before_each(new_setup = false, &block) ⇒ Object
-
.generate_api_method(method_name, &block) ⇒ Proc
private
Create an UnboundMethod that is appropriate for executing an endpoint route.
Instance Method Summary collapse
- #call(env) ⇒ Object
- #call!(env) ⇒ Object
- #compile_path(prepared_path, anchor = true, requirements = {}) ⇒ Object
-
#endpoints ⇒ Object
Return the collection of endpoints within this endpoint.
-
#initialize(new_settings, options = {}, &block) ⇒ Endpoint
constructor
A new instance of Endpoint.
- #method_name ⇒ Object
- #mount_in(route_set) ⇒ Object
- #namespace ⇒ Object
- #prepare_path(path) ⇒ Object
- #prepare_routes ⇒ Object
- #prepare_routes_path_params(path) ⇒ Object
- #prepare_routes_requirements ⇒ Object
- #require_option(options, key) ⇒ Object
- #reset_routes! ⇒ Object
- #routes ⇒ Object
Methods included from DSL::InsideRoute
#body, #content_type, #cookies, #declared, #entity_class_for_obj, #error!, #header, #present, #redirect, #route, #status, #version
Methods included from DSL::Settings
#api_class_setting, #get_or_set, #global_setting, #namespace_end, #namespace_inheritable, #namespace_inheritable_to_nil, #namespace_setting, #namespace_stackable, #namespace_start, #route_end, #route_setting, #unset, #unset_api_class_setting, #unset_global_setting, #unset_namespace_inheritable, #unset_namespace_setting, #unset_namespace_stackable, #unset_route_setting, #within_namespace
Constructor Details
#initialize(new_settings, options = {}, &block) ⇒ Endpoint
Returns a new instance of Endpoint.
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 |
# File 'lib/grape/endpoint.rb', line 51 def initialize(new_settings, = {}, &block) require_option(, :path) require_option(, :method) self.inheritable_setting = new_settings.point_in_time_copy route_setting(:saved_declared_params, namespace_stackable(:declared_params)) route_setting(:saved_validations, namespace_stackable(:validations)) namespace_stackable(:representations, []) unless namespace_stackable(:representations) namespace_inheritable(:default_error_status, 500) unless namespace_inheritable(:default_error_status) @options = @options[:path] = Array([:path]) @options[:path] << '/' if [:path].empty? @options[:method] = Array([:method]) @options[:route_options] ||= {} if block_given? @source = block @block = self.class.generate_api_method(method_name, &block) end end |
Instance Attribute Details
#block ⇒ Object
Returns the value of attribute block.
9 10 11 |
# File 'lib/grape/endpoint.rb', line 9 def block @block end |
#env ⇒ Object (readonly)
Returns the value of attribute env.
10 11 12 |
# File 'lib/grape/endpoint.rb', line 10 def env @env end |
#headers ⇒ Object (readonly)
Returns the value of attribute headers.
10 11 12 |
# File 'lib/grape/endpoint.rb', line 10 def headers @headers end |
#options ⇒ Object
Returns the value of attribute options.
9 10 11 |
# File 'lib/grape/endpoint.rb', line 9 def @options end |
#params ⇒ Object (readonly)
Returns the value of attribute params.
10 11 12 |
# File 'lib/grape/endpoint.rb', line 10 def params @params end |
#request ⇒ Object (readonly)
Returns the value of attribute request.
10 11 12 |
# File 'lib/grape/endpoint.rb', line 10 def request @request end |
#source ⇒ Object
Returns the value of attribute source.
9 10 11 |
# File 'lib/grape/endpoint.rb', line 9 def source @source end |
Class Method Details
.before_each(new_setup = false, &block) ⇒ Object
15 16 17 18 19 20 21 22 23 24 25 |
# File 'lib/grape/endpoint.rb', line 15 def before_each(new_setup = false, &block) if new_setup == false if block_given? @before_each = block else return @before_each end else @before_each = new_setup end end |
.generate_api_method(method_name, &block) ⇒ Proc
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Create an UnboundMethod that is appropriate for executing an endpoint route.
The unbound method allows explicit calls to +return+ without raising a +LocalJumpError+. The method will be removed, but a +Proc+ reference to it will be returned. The returned +Proc+ expects a single argument: the instance of +Endpoint+ to bind to the method during the call.
40 41 42 43 44 45 46 47 48 |
# File 'lib/grape/endpoint.rb', line 40 def generate_api_method(method_name, &block) if instance_methods.include?(method_name.to_sym) || instance_methods.include?(method_name.to_s) fail NameError.new("method #{method_name.inspect} already exists and cannot be used as an unbound method name") end define_method(method_name, &block) method = instance_method(method_name) remove_method(method_name) proc { |endpoint_instance| method.bind(endpoint_instance).call } end |
Instance Method Details
#call(env) ⇒ Object
183 184 185 |
# File 'lib/grape/endpoint.rb', line 183 def call(env) dup.call!(env) end |
#call!(env) ⇒ Object
187 188 189 190 191 192 193 194 195 196 197 198 |
# File 'lib/grape/endpoint.rb', line 187 def call!(env) extend helpers env['api.endpoint'] = self if [:app] [:app].call(env) else builder = build_middleware builder.run lambda { |arg| run(arg) } builder.call(env) end end |
#compile_path(prepared_path, anchor = true, requirements = {}) ⇒ Object
176 177 178 179 180 181 |
# File 'lib/grape/endpoint.rb', line 176 def compile_path(prepared_path, anchor = true, requirements = {}) = {} [:version] = /#{namespace_inheritable(:version).join('|')}/ if namespace_inheritable(:version) .merge!(requirements) Rack::Mount::Strexp.compile(prepared_path, , %w( / . ? ), anchor) end |
#endpoints ⇒ Object
Return the collection of endpoints within this endpoint. This is the case when an Grape::API mounts another Grape::API.
202 203 204 205 206 207 208 |
# File 'lib/grape/endpoint.rb', line 202 def endpoints if [:app] && [:app].respond_to?(:endpoints) [:app].endpoints else nil end end |
#method_name ⇒ Object
81 82 83 84 85 86 87 |
# File 'lib/grape/endpoint.rb', line 81 def method_name [[:method], Namespace.joined_space(namespace_stackable(:namespace)), (namespace_stackable(:mount_path) || []).join('/'), [:path].join('/') ].join(' ') end |
#mount_in(route_set) ⇒ Object
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/grape/endpoint.rb', line 99 def mount_in(route_set) if endpoints endpoints.each do |e| e.mount_in(route_set) end else @routes = nil routes.each do |route| methods = [route.route_method] if !namespace_inheritable(:do_not_route_head) && route.route_method == 'GET' methods << 'HEAD' end methods.each do |method| route_set.add_route(self, { path_info: route.route_compiled, request_method: method }, route_info: route) end end end end |
#namespace ⇒ Object
172 173 174 |
# File 'lib/grape/endpoint.rb', line 172 def namespace @namespace ||= Namespace.joined_space_path(namespace_stackable(:namespace)) end |
#prepare_path(path) ⇒ Object
167 168 169 170 |
# File 'lib/grape/endpoint.rb', line 167 def prepare_path(path) path_settings = inheritable_setting.to_hash[:namespace_stackable].merge(inheritable_setting.to_hash[:namespace_inheritable]) Path.prepare(path, namespace, path_settings) end |
#prepare_routes ⇒ Object
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/grape/endpoint.rb', line 145 def prepare_routes [:method].map do |method| [:path].map do |path| prepared_path = prepare_path(path) anchor = [:route_options].fetch(:anchor, true) path = compile_path(prepared_path, anchor && ![:app], prepare_routes_requirements) request_method = (method.to_s.upcase unless method == :any) Route.new([:route_options].clone.merge( prefix: namespace_inheritable(:root_prefix), version: namespace_inheritable(:version) ? namespace_inheritable(:version).join('|') : nil, namespace: namespace, method: request_method, path: prepared_path, params: prepare_routes_path_params(path), compiled: path, settings: inheritable_setting.route.except(:saved_declared_params, :saved_validations) )) end end.flatten end |
#prepare_routes_path_params(path) ⇒ Object
130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/grape/endpoint.rb', line 130 def prepare_routes_path_params(path) path_params = {} # named parameters in the api path regex = Rack::Mount::RegexpWithNamedGroups.new(path) named_params = regex.named_captures.map { |nc| nc[0] } - %w(version format) named_params.each { |named_param| path_params[named_param] = '' } # route parameters declared via desc or appended to the api declaration route_params = [:route_options][:params] path_params.merge! route_params if route_params path_params end |
#prepare_routes_requirements ⇒ Object
122 123 124 125 126 127 128 |
# File 'lib/grape/endpoint.rb', line 122 def prepare_routes_requirements endpoint_requirements = [:route_options][:requirements] || {} all_requirements = (namespace_stackable(:namespace).map(&:requirements) << endpoint_requirements) all_requirements.reduce({}) do |base_requirements, single_requirements| base_requirements.merge!(single_requirements) end end |
#require_option(options, key) ⇒ Object
77 78 79 |
# File 'lib/grape/endpoint.rb', line 77 def require_option(, key) fail Grape::Exceptions::MissingOption.new(key) unless .key?(key) end |
#reset_routes! ⇒ Object
93 94 95 96 97 |
# File 'lib/grape/endpoint.rb', line 93 def reset_routes! endpoints.map(&:reset_routes!) if endpoints @namespace = nil @routes = nil end |
#routes ⇒ Object
89 90 91 |
# File 'lib/grape/endpoint.rb', line 89 def routes @routes ||= endpoints ? endpoints.collect(&:routes).flatten : prepare_routes end |