@@ -14,6 +14,9 @@ class << self
1414 attr_reader :routes
1515 attr_reader :settings
1616 attr_writer :logger
17+ attr_reader :endpoints
18+ attr_reader :mountings
19+ attr_reader :instance
1720
1821 def logger ( logger = nil )
1922 if logger
@@ -26,11 +29,26 @@ def logger(logger = nil)
2629 def reset!
2730 @settings = Grape ::Util ::HashStack . new
2831 @route_set = Rack ::Mount ::RouteSet . new
32+ @endpoints = [ ]
33+ @mountings = [ ]
34+ end
35+
36+ def compile
37+ @instance = self . new
38+ end
39+
40+ def change!
41+ @instance = nil
2942 end
3043
3144 def call ( env )
45+ compile unless instance
46+ call! ( env )
47+ end
48+
49+ def call! ( env )
3250 logger . info "#{ env [ 'REQUEST_METHOD' ] } #{ env [ 'PATH_INFO' ] } "
33- route_set . freeze . call ( env )
51+ instance . call ( env )
3452 end
3553
3654 # Set a configuration value for this namespace.
@@ -49,7 +67,7 @@ def set(key, value)
4967 def imbue ( key , value )
5068 settings . imbue ( key , value )
5169 end
52-
70+
5371 # Define a root URL prefix for your entire
5472 # API.
5573 def prefix ( prefix = nil )
@@ -181,6 +199,7 @@ def helpers(&block)
181199 settings . stack . each do |s |
182200 m . send :include , s [ :helpers ] if s [ :helpers ]
183201 end
202+ change!
184203 m
185204 end
186205 end
@@ -212,11 +231,15 @@ def http_digest(options = {}, &block)
212231
213232 def mount ( mounts )
214233 mounts = { mounts => '/' } unless mounts . respond_to? ( :each_pair )
215-
216234 mounts . each_pair do |app , path |
217- next unless app . respond_to? ( :call )
218- route_set . add_route ( app ,
219- :path_info => compile_path ( path , false )
235+ if app . respond_to? ( :inherit_settings )
236+ app . inherit_settings ( settings . clone )
237+ end
238+
239+ endpoints << Grape ::Endpoint . new ( settings . clone ,
240+ :method => :any ,
241+ :path => path ,
242+ :app => app
220243 )
221244 end
222245 end
@@ -234,46 +257,19 @@ def mount(mounts)
234257 # end
235258 # end
236259 def route ( methods , paths = [ '/' ] , route_options = { } , &block )
237- methods = Array ( methods )
238-
239- paths = [ '/' ] if ! paths || paths == [ ]
240- paths = Array ( paths )
241-
242- endpoint = build_endpoint ( &block )
243-
244- route_options ||= { }
245-
246- methods . each do |method |
247- paths . each do |path |
248- prepared_path = prepare_path ( path )
249- path = compile_path ( path )
250- regex = Rack ::Mount ::RegexpWithNamedGroups . new ( path )
251- path_params = regex . named_captures . map { |nc | nc [ 0 ] } - [ 'version' , 'format' ]
252- path_params |= ( route_options [ :params ] || [ ] )
253- request_method = ( method . to_s . upcase unless method == :any )
254-
255- routes << Route . new ( route_options . merge ( {
256- :prefix => prefix ,
257- :version => settings [ :version ] ? settings [ :version ] . join ( '|' ) : nil ,
258- :namespace => namespace ,
259- :method => request_method ,
260- :path => prepared_path ,
261- :params => path_params } ) )
262-
263- route_set . add_route ( endpoint ,
264- :path_info => path ,
265- :request_method => request_method
266- )
267- end
268- end
260+ endpoints << Grape ::Endpoint . new ( settings . clone , {
261+ :method => methods ,
262+ :path => paths ,
263+ :route_options => ( route_options || { } )
264+ } , &block )
269265 end
270266
271267 def before ( &block )
272- settings . imbue ( :befores , [ block ] )
268+ imbue ( :befores , [ block ] )
273269 end
274270
275271 def after ( &block )
276- settings . imbue ( :afters , [ block ] )
272+ imbue ( :afters , [ block ] )
277273 end
278274
279275 def get ( paths = [ '/' ] , options = { } , &block ) ; route ( 'GET' , paths , options , &block ) end
@@ -311,7 +307,7 @@ def scope(name = nil, &block)
311307 # @param middleware_class [Class] The class of the middleware you'd like
312308 # to inject.
313309 def use ( middleware_class , *args )
314- settings . imbue ( :middleware , [ [ middleware_class , *args ] ] )
310+ imbue ( :middleware , [ [ middleware_class , *args ] ] )
315311 end
316312
317313 # Retrieve an array of the middleware classes
@@ -347,53 +343,27 @@ def nest(*blocks, &block)
347343 end
348344 end
349345
350- def build_endpoint ( &block )
351- # befores = aggregate_setting(:befores)
352- # afters = aggregate_setting(:afters)
353- # representations = settings[:representations] || {}
354-
355- # endpoint = Grape::Endpoint.generate({
356- # :befores => befores,
357- # :afters => afters,
358- # :representations => representations
359- # }, &block)
360- # endpoint.send :include, helpers
361- # b.run endpoint
362- # b.to_app
363- Grape ::Endpoint . new ( settings . clone , { } , &block )
364- end
365-
366346 def inherited ( subclass )
367347 subclass . reset!
368348 subclass . logger = logger . clone
369349 end
370350
371- def inherit ( other_stack )
372- # settings stack should know how to merge aggregate keys / values
373- # settings_stack.unshift *other_stack
374- # raise settings_stack.inspect
375- end
376-
377- def route_set
378- @route_set ||= Rack ::Mount ::RouteSet . new
351+ def inherit_settings ( other_stack )
352+ settings . prepend other_stack
379353 end
354+ end
380355
381- def prepare_path ( path )
382- parts = [ ]
383- parts << prefix if prefix
384- parts << ':version' if settings [ :version ] && settings [ :version_options ] [ :using ] == :path
385- parts << namespace . to_s if namespace
386- parts << path . to_s if path && '/' != path
387- parts . last << '(.:format)'
388- Rack ::Mount ::Utils . normalize_path ( parts . join ( '/' ) )
356+ def initialize
357+ @route_set = Rack ::Mount ::RouteSet . new
358+ self . class . endpoints . each do |endpoint |
359+ endpoint . mount_in ( @route_set )
389360 end
390361
391- def compile_path ( path , anchor = true )
392- endpoint_options = { }
393- endpoint_options [ :version ] = /#{ settings [ :version ] . join ( '|' ) } / if settings [ :version ]
362+ @route_set . freeze
363+ end
394364
395- Rack :: Mount :: Strexp . compile ( prepare_path ( path ) , endpoint_options , %w( / . ? ) , anchor )
396- end
365+ def call ( env )
366+ @route_set . call ( env )
397367 end
398368
399369 reset!
0 commit comments