11require 'rack/mount'
22require 'rack/auth/basic'
3+ require 'logger'
34
45module Grape
56 class API
@@ -8,14 +9,18 @@ module Helpers; end
89 class << self
910 attr_reader :route_set
1011
12+ def logger
13+ @logger ||= Logger . new ( $STDOUT)
14+ end
15+
1116 def reset!
1217 @settings = [ { } ]
1318 @route_set = Rack ::Mount ::RouteSet . new
1419 @prototype = nil
1520 end
1621
1722 def call ( env )
18- puts "#{ env [ 'REQUEST_METHOD' ] } #{ env [ 'PATH_INFO' ] } "
23+ logger . info "#{ env [ 'REQUEST_METHOD' ] } #{ env [ 'PATH_INFO' ] } "
1924 route_set . freeze . call ( env )
2025 end
2126
@@ -30,6 +35,11 @@ def settings_stack
3035 @settings
3136 end
3237
38+ # Set a configuration value for this
39+ # namespace.
40+ #
41+ # @param key [Symbol] The key of the configuration variable.
42+ # @param value [Object] The value to which to set the configuration variable.
3343 def set ( key , value )
3444 @settings . last [ key . to_sym ] = value
3545 end
@@ -48,6 +58,9 @@ def version(*new_versions, &block)
4858 new_versions . any? ? nest ( block ) { set ( :version , new_versions ) } : settings [ :version ]
4959 end
5060
61+ # Specify the default format for the API's
62+ # serializers. Currently only `:json` is
63+ # supported.
5164 def default_format ( new_format = nil )
5265 new_format ? set ( :default_format , new_format . to_sym ) : settings [ :default_format ]
5366 end
@@ -76,6 +89,8 @@ def helpers(&block)
7689 end
7790 end
7891
92+ # Add an authentication type to the API. Currently
93+ # only `:http_basic` is supported.
7994 def auth ( type = nil , options = { } , &block )
8095 if type
8196 set ( :auth , { :type => type . to_sym , :proc => block } . merge ( options ) )
@@ -93,47 +108,34 @@ def http_basic(options = {}, &block)
93108 auth :http_basic , options , &block
94109 end
95110
96- def route_set
97- @route_set ||= Rack ::Mount ::RouteSet . new
98- end
99-
100- def compile_path ( path )
101- parts = [ ]
102- parts << prefix if prefix
103- parts << ':version' if version
104- parts << namespace if namespace
105- parts << path
106- Rack ::Mount ::Utils . normalize_path ( parts . join ( '/' ) )
107- end
108-
109- def route ( method , path_info , &block )
110- route_set . add_route ( build_endpoint ( &block ) ,
111- :path_info => Rack ::Mount ::Strexp . compile ( compile_path ( path_info ) ) ,
112- :request_method => method
113- )
114- end
115-
116- def build_endpoint ( &block )
117-
118- b = Rack ::Builder . new
119- b . use Grape ::Middleware ::Error
120- b . use Rack ::Auth ::Basic , settings [ :auth ] [ :realm ] , &settings [ :auth ] [ :proc ] if settings [ :auth ] && settings [ :auth ] [ :type ] == :http_basic
121- b . use Grape ::Middleware ::Prefixer , :prefix => prefix if prefix
122- b . use Grape ::Middleware ::Versioner , :versions => ( version if version . is_a? ( Array ) ) if version
123- b . use Grape ::Middleware ::Formatter , :default_format => default_format || :json
124-
125- endpoint = Grape ::Endpoint . generate ( &block )
126- endpoint . send :include , helpers
127- b . run endpoint
111+ # Defines a route that will be recognized
112+ # by the Grape API.
113+ #
114+ # @param methods [HTTP Verb(s)] One or more HTTP verbs that are accepted by this route. Set to `:any` if you want any verb to be accepted.
115+ # @param paths [String(s)] One or more strings representing the URL segment(s) for this route.
116+ # @param block [Proc] The code to be executed
117+ def route ( methods , paths , &block )
118+ methods = Array ( methods )
119+ paths = [ '/' ] if paths == [ ]
120+ paths = Array ( paths )
121+ endpoint = build_endpoint ( &block )
128122
129- b . to_app
123+ methods . each do |method |
124+ paths . each do |path |
125+ path = Rack ::Mount ::Strexp . compile ( compile_path ( path ) )
126+ route_set . add_route ( endpoint ,
127+ :path_info => path ,
128+ :request_method => ( method . to_s . upcase unless method == :any )
129+ )
130+ end
131+ end
130132 end
131133
132- def get ( path_info = '' , &block ) ; route ( 'GET' , path_info , &block ) end
133- def post ( path_info = '' , &block ) ; route ( 'POST' , path_info , &block ) end
134- def put ( path_info = '' , &block ) ; route ( 'PUT' , path_info , &block ) end
135- def head ( path_info = '' , &block ) ; route ( 'HEAD' , path_info , &block ) end
136- def delete ( path_info = '' , &block ) ; route ( 'DELETE' , path_info , &block ) end
134+ def get ( * paths , &block ) ; route ( 'GET' , paths , &block ) end
135+ def post ( * paths , &block ) ; route ( 'POST' , paths , &block ) end
136+ def put ( * paths , &block ) ; route ( 'PUT' , paths , &block ) end
137+ def head ( * paths , &block ) ; route ( 'HEAD' , paths , &block ) end
138+ def delete ( * paths , &block ) ; route ( 'DELETE' , paths , &block ) end
137139
138140 def namespace ( space = nil , &block )
139141 if space || block_given?
@@ -164,9 +166,39 @@ def nest(*blocks, &block)
164166 alias_method :resource , :namespace
165167 alias_method :resources , :namespace
166168
169+ protected
170+
171+ def build_endpoint ( &block )
172+ b = Rack ::Builder . new
173+ b . use Grape ::Middleware ::Error
174+ b . use Rack ::Auth ::Basic , settings [ :auth ] [ :realm ] , &settings [ :auth ] [ :proc ] if settings [ :auth ] && settings [ :auth ] [ :type ] == :http_basic
175+ b . use Grape ::Middleware ::Prefixer , :prefix => prefix if prefix
176+ b . use Grape ::Middleware ::Versioner , :versions => ( version if version . is_a? ( Array ) ) if version
177+ b . use Grape ::Middleware ::Formatter , :default_format => default_format || :json
178+
179+ endpoint = Grape ::Endpoint . generate ( &block )
180+ endpoint . send :include , helpers
181+ b . run endpoint
182+
183+ b . to_app
184+ end
185+
167186 def inherited ( subclass )
168187 subclass . reset!
169188 end
189+
190+ def route_set
191+ @route_set ||= Rack ::Mount ::RouteSet . new
192+ end
193+
194+ def compile_path ( path )
195+ parts = [ ]
196+ parts << prefix if prefix
197+ parts << ':version' if version
198+ parts << namespace if namespace
199+ parts << path
200+ Rack ::Mount ::Utils . normalize_path ( parts . join ( '/' ) )
201+ end
170202 end
171203
172204 reset!
0 commit comments