lib/grape/api.rb in grape-0.12.0 vs lib/grape/api.rb in grape-0.13.0
- old
+ new
@@ -1,49 +1,62 @@
module Grape
- # The API class is the primary entry point for
- # creating Grape APIs.Users should subclass this
- # class in order to build an API.
+ # The API class is the primary entry point for creating Grape APIs. Users
+ # should subclass this class in order to build an API.
class API
include Grape::DSL::API
class << self
attr_reader :instance
+
+ # A class-level lock to ensure the API is not compiled by multiple
+ # threads simultaneously within the same process.
LOCK = Mutex.new
+ # Clears all defined routes, endpoints, etc., on this API.
def reset!
@route_set = Rack::Mount::RouteSet.new
@endpoints = []
@routes = nil
reset_validations!
end
+ # Parses the API's definition and compiles it into an instance of
+ # Grape::API.
def compile
@instance ||= new
end
+ # Wipe the compiled API so we can recompile after changes were made.
def change!
@instance = nil
end
+ # This is the interface point between Rack and Grape; it accepts a request
+ # from Rack and ultimately returns an array of three values: the status,
+ # the headers, and the body. See [the rack specification]
+ # (http://www.rubydoc.info/github/rack/rack/master/file/SPEC) for more.
def call(env)
LOCK.synchronize { compile } unless instance
call!(env)
end
+ # A non-synchronized version of ::call.
def call!(env)
instance.call(env)
end
# Create a scope without affecting the URL.
#
- # @param name [Symbol] Purely placebo, just allows to name the scope to make the code more readable.
+ # @param _name [Symbol] Purely placebo, just allows to name the scope to
+ # make the code more readable.
def scope(_name = nil, &block)
within_namespace do
nest(block)
end
end
+ # (see #cascade?)
def cascade(value = nil)
if value.nil?
inheritable_setting.namespace_inheritable.keys.include?(:cascade) ? !!namespace_inheritable(:cascade) : true
else
namespace_inheritable(:cascade, value)
@@ -82,20 +95,23 @@
@routes = nil
end
end
+ # Builds the routes from the defined endpoints, effectively compiling
+ # this API into a usable form.
def initialize
@route_set = Rack::Mount::RouteSet.new
add_head_not_allowed_methods_and_options_methods
self.class.endpoints.each do |endpoint|
endpoint.mount_in(@route_set)
end
@route_set.freeze
end
+ # Handle a request. See Rack documentation for what `env` is.
def call(env)
result = @route_set.call(env)
result[1].delete(Grape::Http::Headers::X_CASCADE) unless cascade?
result
end
@@ -166,10 +182,12 @@
end
end
end
end
+ # Allows definition of endpoints that ignore the versioning configuration
+ # used by the rest of your API.
def without_versioning(&_block)
old_version = self.class.namespace_inheritable(:version)
old_version_options = self.class.namespace_inheritable(:version_options)
self.class.namespace_inheritable_to_nil(:version)
@@ -179,9 +197,11 @@
self.class.namespace_inheritable(:version, old_version)
self.class.namespace_inheritable(:version_options, old_version_options)
end
+ # Allows definition of endpoints that ignore the root prefix used by the
+ # rest of your API.
def without_root_prefix(&_block)
old_prefix = self.class.namespace_inheritable(:root_prefix)
self.class.namespace_inheritable_to_nil(:root_prefix)