@@ -10,6 +10,7 @@ module Grape
1010 class API
1111 class << self
1212 attr_reader :route_set
13+ attr_reader :structure
1314
1415 def logger
1516 @logger ||= Logger . new ( $STDOUT)
@@ -159,7 +160,7 @@ def http_basic(options = {}, &block)
159160
160161 def http_digest ( options = { } , &block )
161162 options [ :realm ] ||= "API Authorization"
162- options [ :opaque ] ||= "secret"
163+ options [ :opaque ] ||= "secret"
163164 auth :http_digest , options , &block
164165 end
165166
@@ -192,6 +193,39 @@ def route(methods, paths, &block)
192193 )
193194 end
194195 end
196+
197+ # create API structure
198+ ( version || [ :default ] ) . each { |v |
199+
200+ ms = [ ]
201+ methods . each { |m |
202+ paths . each { |p |
203+ ms << {
204+ :method => m ,
205+ :path => p . to_s
206+ }
207+ }
208+ }
209+
210+ if namespace == '/'
211+ if structure [ v ] . is_a? ( Hash )
212+ structure [ v ] [ :default ] ||= ( structure [ v ] [ :default ] || { } ) . merge ( structure [ v ] )
213+ if ( structure [ v ] [ :default ] . is_a? ( Hash ) )
214+ structure [ v ] [ :default ] = [ structure [ v ] [ :default ] , ms ]
215+ else
216+ structure [ v ] [ :default ] |= ms
217+ end
218+ else
219+ structure [ v ] ||= [ ]
220+ structure [ v ] |= ms
221+ end
222+ else
223+ structure [ v ] = { :default => structure [ v ] } if structure [ v ] . is_a? ( Array )
224+ structure [ v ] ||= { }
225+ structure [ v ] [ namespace [ 1 ..namespace . length - 1 ] . to_s ] = ms
226+ end
227+ }
228+
195229 end
196230
197231 def get ( *paths , &block ) ; route ( 'GET' , paths , &block ) end
@@ -238,6 +272,12 @@ def middleware
238272 settings_stack . inject ( [ ] ) { |a , s | a += s [ :middleware ] if s [ :middleware ] ; a }
239273 end
240274
275+ # API structure contains a hash of API versions to API methods.
276+ # If the API is not versioned, the hash contains a single :current key.
277+ def structure
278+ @structure ||= { }
279+ end
280+
241281 protected
242282
243283 # Execute first the provided block, then each of the
@@ -264,7 +304,7 @@ def build_endpoint(&block)
264304 :format => settings [ :error_format ] || :txt ,
265305 :rescue_options => settings [ :rescue_options ]
266306 b . use Rack ::Auth ::Basic , settings [ :auth ] [ :realm ] , &settings [ :auth ] [ :proc ] if settings [ :auth ] && settings [ :auth ] [ :type ] == :http_basic
267- b . use Rack ::Auth ::Digest ::MD5 , settings [ :auth ] [ :realm ] , settings [ :auth ] [ :opaque ] , &settings [ :auth ] [ :proc ] if settings [ :auth ] && settings [ :auth ] [ :type ] == :http_digest
307+ b . use Rack ::Auth ::Digest ::MD5 , settings [ :auth ] [ :realm ] , settings [ :auth ] [ :opaque ] , &settings [ :auth ] [ :proc ] if settings [ :auth ] && settings [ :auth ] [ :type ] == :http_digest
268308 b . use Grape ::Middleware ::Prefixer , :prefix => prefix if prefix
269309 b . use Grape ::Middleware ::Versioner , :versions => ( version if version . is_a? ( Array ) ) if version
270310 b . use Grape ::Middleware ::Formatter , :default_format => default_format || :json
@@ -284,7 +324,7 @@ def inherited(subclass)
284324 def route_set
285325 @route_set ||= Rack ::Mount ::RouteSet . new
286326 end
287-
327+
288328 def compile_path ( path )
289329 parts = [ ]
290330 parts << prefix if prefix
0 commit comments