Class: Grape::Endpoint
- Inherits:
-
Object
- Object
- Grape::Endpoint
- 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)
-
- (Object) block
Returns the value of attribute block.
-
- (Object) env
readonly
Returns the value of attribute env.
-
- (Object) options
Returns the value of attribute options.
-
- (Object) request
readonly
Returns the value of attribute request.
-
- (Object) settings
Returns the value of attribute settings.
-
- (Object) source
Returns the value of attribute source.
Class Method Summary (collapse)
-
+ (Proc) generate_api_method(method_name, &block)
private
Create an UnboundMethod that is appropriate for executing an endpoint route.
Instance Method Summary (collapse)
-
- (Object) body(value = nil)
Allows you to define the response body as something other than the return value.
- - (Object) call(env)
- - (Object) call!(env)
- - (Object) compile_path(prepared_path, anchor = true, requirements = {})
-
- (Object) content_type(val)
Set response content-type.
-
- (Object) cookies
Set or get a cookie.
-
- (Object) declared(params, options = {}, declared_params = settings[:declared_params])
A filtering method that will return a hash consisting only of keys that have been declared by a
paramsstatement. -
- (Object) error!(message, status = 403)
End the request and display an error to the end user with the specified message.
-
- (Object) header(key = nil, val = nil)
Set an individual header or retrieve all headers that have been set.
-
- (Object) headers
Retrieves all available request headers.
-
- (Endpoint) initialize(settings, options = {}, &block)
constructor
A new instance of Endpoint.
- - (Object) mount_in(route_set)
- - (Object) namespace
-
- (Object) params
The parameters passed into the request as well as parsed from URL segments.
- - (Object) prepare_path(path)
- - (Object) prepare_routes
-
- (Object) present(*args)
Allows you to make use of Grape Entities by setting the response body to the serializable hash of the entity provided in the
:withoption. -
- (Object) redirect(url, options = {})
Redirect to a new url.
-
- (Object) route
Returns route information for the current request.
- - (Object) routes
-
- (Object) status(status = nil)
Set or retrieve the HTTP status code.
-
- (Object) version
The API version as specified in the URL.
Constructor Details
- (Endpoint) initialize(settings, options = {}, &block)
A new instance of Endpoint
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/grape/endpoint.rb', line 35 def initialize(settings, = {}, &block) @settings = settings if block_given? method_name = [ [:method], Namespace.joined_space(settings), settings.gather(:mount_path).join("/"), Array([:path]).join("/") ].join(" ") @source = block @block = self.class.generate_api_method(method_name, &block) end @options = raise Grape::Exceptions::MissingOption.new(:path) unless .key?(:path) [:path] = Array([:path]) [:path] = ['/'] if [:path].empty? raise Grape::Exceptions::MissingOption.new(:method) unless .key?(:method) [:method] = Array([:method]) [:route_options] ||= {} end |
Instance Attribute Details
- (Object) block
Returns the value of attribute block
7 8 9 |
# File 'lib/grape/endpoint.rb', line 7 def block @block end |
- (Object) env (readonly)
Returns the value of attribute env
8 9 10 |
# File 'lib/grape/endpoint.rb', line 8 def env @env end |
- (Object) options
Returns the value of attribute options
7 8 9 |
# File 'lib/grape/endpoint.rb', line 7 def @options end |
- (Object) request (readonly)
Returns the value of attribute request
8 9 10 |
# File 'lib/grape/endpoint.rb', line 8 def request @request end |
- (Object) settings
Returns the value of attribute settings
7 8 9 |
# File 'lib/grape/endpoint.rb', line 7 def settings @settings end |
- (Object) source
Returns the value of attribute source
7 8 9 |
# File 'lib/grape/endpoint.rb', line 7 def source @source end |
Class Method Details
+ (Proc) generate_api_method(method_name, &block)
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.
24 25 26 27 28 29 30 31 32 |
# File 'lib/grape/endpoint.rb', line 24 def generate_api_method(method_name, &block) if instance_methods.include?(method_name.to_sym) || instance_methods.include?(method_name.to_s) raise 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
- (Object) body(value = nil)
Allows you to define the response body as something other than the return value.
303 304 305 306 307 308 309 |
# File 'lib/grape/endpoint.rb', line 303 def body(value = nil) if value @body = value else @body end end |
- (Object) call(env)
154 155 156 |
# File 'lib/grape/endpoint.rb', line 154 def call(env) dup.call!(env) end |
- (Object) call!(env)
158 159 160 161 162 163 164 165 166 167 |
# File 'lib/grape/endpoint.rb', line 158 def call!(env) env['api.endpoint'] = self if [:app] [:app].call(env) else builder = build_middleware builder.run [:app] || lambda{|env| self.run(env) } builder.call(env) end end |
- (Object) compile_path(prepared_path, anchor = true, requirements = {})
147 148 149 150 151 152 |
# File 'lib/grape/endpoint.rb', line 147 def compile_path(prepared_path, anchor = true, requirements = {}) = {} [:version] = /#{settings[:version].join('|')}/ if settings[:version] .merge!(requirements) Rack::Mount::Strexp.compile(prepared_path, , %w( / . ? ), anchor) end |
- (Object) content_type(val)
Set response content-type
277 278 279 |
# File 'lib/grape/endpoint.rb', line 277 def content_type(val) header('Content-Type', val) end |
- (Object) cookies
Set or get a cookie
289 290 291 |
# File 'lib/grape/endpoint.rb', line 289 def @cookies ||= Cookies.new end |
- (Object) declared(params, options = {}, declared_params = settings[:declared_params])
A filtering method that will return a hash
consisting only of keys that have been declared by a
params statement.
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 |
# File 'lib/grape/endpoint.rb', line 181 def declared(params, = {}, declared_params = settings[:declared_params]) [:include_missing] = true unless .key?(:include_missing) unless declared_params raise ArgumentError, "Tried to filter for declared parameters but none exist." end if params.is_a? Array params.map do |param| declared(param || {}, , declared_params) end else declared_params.inject({}) do |hash, key| key = { key => nil } unless key.is_a? Hash key.each_pair do |parent, children| output_key = [:stringify] ? parent.to_s : parent.to_sym if params.key?(parent) || [:include_missing] hash[output_key] = if children declared(params[parent] || {}, , Array(children)) else params[parent] end end end hash end end end |
- (Object) error!(message, status = 403)
End the request and display an error to the end user with the specified message.
220 221 222 |
# File 'lib/grape/endpoint.rb', line 220 def error!(, status=403) throw :error, :message => , :status => status end |
- (Object) header(key = nil, val = nil)
Set an individual header or retrieve all headers that have been set.
263 264 265 266 267 268 269 |
# File 'lib/grape/endpoint.rb', line 263 def header(key = nil, val = nil) if key val ? @header[key.to_s] = val : @header.delete(key.to_s) else @header end end |
- (Object) headers
Retrieves all available request headers.
272 273 274 |
# File 'lib/grape/endpoint.rb', line 272 def headers @headers ||= @request.headers end |
- (Object) mount_in(route_set)
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/grape/endpoint.rb', line 63 def mount_in(route_set) if endpoints endpoints.each { |e| e.mount_in(route_set) } else routes.each do |route| methods = [ route.route_method ] if ! settings[: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 |
- (Object) namespace
143 144 145 |
# File 'lib/grape/endpoint.rb', line 143 def namespace @namespace ||= Namespace.joined_space_path(settings) end |
- (Object) params
The parameters passed into the request as well as parsed from URL segments.
171 172 173 |
# File 'lib/grape/endpoint.rb', line 171 def params @params ||= @request.params end |
- (Object) prepare_path(path)
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/grape/endpoint.rb', line 122 def prepare_path(path) parts = [] parts << settings[:mount_path].to_s.split("/") if settings[:mount_path] parts << settings[:root_prefix].to_s.split("/") if settings[:root_prefix] uses_path_versioning = settings[:version] && settings[:version_options][:using] == :path namespace_is_empty = namespace && (namespace.to_s =~ /^\s*$/ || namespace.to_s == '/') path_is_empty = path && (path.to_s =~ /^\s*$/ || path.to_s == '/') parts << ':version' if uses_path_versioning if ! uses_path_versioning || (! namespace_is_empty || ! path_is_empty) parts << namespace.to_s if namespace parts << path.to_s if path format_suffix = '(.:format)' else format_suffix = '(/.:format)' end parts = parts.flatten.select { |part| part != '/' } Rack::Mount::Utils.normalize_path(parts.join('/') + format_suffix) end |
- (Object) prepare_routes
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 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 82 def prepare_routes routes = [] [:method].each do |method| [:path].each do |path| prepared_path = prepare_path(path) anchor = [:route_options][:anchor] anchor = anchor.nil? ? true : anchor endpoint_requirements = [:route_options][:requirements] || {} all_requirements = (settings.gather(:namespace).map(&:requirements) << endpoint_requirements) requirements = all_requirements.reduce({}) do |base_requirements, single_requirements| base_requirements.merge!(single_requirements) end path = compile_path(prepared_path, anchor && ![:app], requirements) regex = Rack::Mount::RegexpWithNamedGroups.new(path) path_params = {} # named parameters in the api path named_params = regex.named_captures.map { |nc| nc[0] } - [ '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) request_method = (method.to_s.upcase unless method == :any) routes << Route.new([:route_options].clone.merge({ :prefix => settings[:root_prefix], :version => settings[:version] ? settings[:version].join('|') : nil, :namespace => namespace, :method => request_method, :path => prepared_path, :params => path_params, :compiled => path, }) ) end end routes end |
- (Object) present(*args)
Allows you to make use of Grape Entities by setting
the response body to the serializable hash of the
entity provided in the :with option. This has the
added benefit of automatically passing along environment
and version information to the serialization, making it
very easy to do conditional exposures. See Entity docs
for more info.
326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 |
# File 'lib/grape/endpoint.rb', line 326 def present(*args) = args.count > 1 ? args. : {} key, object = if args.count == 2 && args.first.is_a?(Symbol) args else [nil, args.first] end entity_class = .delete(:with) # auto-detect the entity from the first object in the collection object_instance = object.respond_to?(:first) ? object.first : object object_instance.class.ancestors.each do |potential| entity_class ||= (settings[:representations] || {})[potential] end entity_class ||= object_instance.class.const_get(:Entity) if object_instance.class.const_defined?(:Entity) root = .delete(:root) representation = if entity_class = {:env => env} [:version] = env['api.version'] if env['api.version'] entity_class.represent(object, .merge()) else object end representation = { root => representation } if root representation = (@body || {}).merge({key => representation}) if key body representation end |
- (Object) redirect(url, options = {})
Redirect to a new url.
229 230 231 232 233 234 235 236 237 238 239 240 241 242 |
# File 'lib/grape/endpoint.rb', line 229 def redirect(url, = {}) = {:permanent => false }.merge() if [:permanent] status 301 else if env['HTTP_VERSION'] == 'HTTP/1.1' && request.request_method.to_s.upcase != "GET" status 303 else status 302 end end header "Location", url body "" end |
- (Object) route
Returns route information for the current request.
367 368 369 |
# File 'lib/grape/endpoint.rb', line 367 def route env["rack.routing_args"][:route_info] end |
- (Object) routes
59 60 61 |
# File 'lib/grape/endpoint.rb', line 59 def routes @routes ||= endpoints ? endpoints.collect(&:routes).flatten : prepare_routes end |
- (Object) status(status = nil)
Set or retrieve the HTTP status code.
247 248 249 250 251 252 253 254 255 256 257 258 259 |
# File 'lib/grape/endpoint.rb', line 247 def status(status = nil) if status @status = status else return @status if @status case request.request_method.to_s.upcase when 'POST' 201 else 200 end end end |
- (Object) version
The API version as specified in the URL.
213 |
# File 'lib/grape/endpoint.rb', line 213 def version; env['api.version'] end |