33
44module Grape
55 class API
6+ module Helpers ; end
7+
68 class << self
79 attr_reader :route_set
810
@@ -13,6 +15,7 @@ def reset!
1315 end
1416
1517 def call ( env )
18+ puts "#{ env [ 'REQUEST_METHOD' ] } #{ env [ 'PATH_INFO' ] } "
1619 route_set . freeze . call ( env )
1720 end
1821
@@ -41,13 +44,37 @@ def prefix(prefix = nil)
4144 prefix ? set ( :root_prefix , prefix ) : settings [ :root_prefix ]
4245 end
4346
44- def version ( new_version = nil )
45- new_version ? set ( :version , new_version ) : settings [ :version ]
47+ def version ( * new_versions , & block )
48+ new_versions . any? ? nest ( block ) { set ( :version , new_versions ) } : settings [ :version ]
4649 end
4750
4851 def default_format ( new_format = nil )
4952 new_format ? set ( :default_format , new_format . to_sym ) : settings [ :default_format ]
5053 end
54+
55+ # Add helper methods that will be accessible from any
56+ # endpoint within this namespace (and child namespaces).
57+ #
58+ # class ExampleAPI
59+ # helpers do
60+ # def current_user
61+ # User.find_by_id(params[:token])
62+ # end
63+ # end
64+ # end
65+ def helpers ( &block )
66+ if block_given?
67+ m = settings_stack . last [ :helpers ] || Module . new
68+ m . class_eval &block
69+ set ( :helpers , m )
70+ else
71+ m = Module . new
72+ settings_stack . each do |s |
73+ m . send :include , s [ :helpers ] if s [ :helpers ]
74+ end
75+ m
76+ end
77+ end
5178
5279 def auth ( type = nil , options = { } , &block )
5380 if type
@@ -73,7 +100,7 @@ def route_set
73100 def compile_path ( path )
74101 parts = [ ]
75102 parts << prefix if prefix
76- parts << version if version
103+ parts << ': version' if version
77104 parts << namespace if namespace
78105 parts << path
79106 Rack ::Mount ::Utils . normalize_path ( parts . join ( '/' ) )
@@ -87,13 +114,18 @@ def route(method, path_info, &block)
87114 end
88115
89116 def build_endpoint ( &block )
117+
90118 b = Rack ::Builder . new
91119 b . use Grape ::Middleware ::Error
92120 b . use Rack ::Auth ::Basic , settings [ :auth ] [ :realm ] , &settings [ :auth ] [ :proc ] if settings [ :auth ] && settings [ :auth ] [ :type ] == :http_basic
93121 b . use Grape ::Middleware ::Prefixer , :prefix => prefix if prefix
94- b . use Grape ::Middleware ::Versioner if version
122+ b . use Grape ::Middleware ::Versioner , :versions => ( version if version . is_a? ( Array ) ) if version
95123 b . use Grape ::Middleware ::Formatter , :default_format => default_format || :json
96- b . run Grape ::Endpoint . new ( &block )
124+
125+ endpoint = Grape ::Endpoint . new ( &block )
126+ endpoint . send :extend , helpers
127+ b . run endpoint
128+
97129 b . to_app
98130 end
99131
@@ -105,12 +137,26 @@ def delete(path_info = '', &block); route('DELETE', path_info, &block) end
105137
106138 def namespace ( space = nil , &block )
107139 if space || block_given?
140+ nest ( block ) do
141+ set ( :namespace , space . to_s ) if space
142+ end
143+ else
144+ Rack ::Mount ::Utils . normalize_path ( settings_stack . map { |s | s [ :namespace ] } . join ( '/' ) )
145+ end
146+ end
147+
148+ # Execute first the provided block, then each of the
149+ # block passed in. Allows for simple 'before' setups
150+ # of settings stack pushes.
151+ def nest ( *blocks , &block )
152+ blocks . reject! { |b | b . nil? }
153+ if blocks . any?
108154 settings_stack << { }
109- set ( :namespace , space . to_s ) if space
110155 instance_eval &block
156+ blocks . each { |b | instance_eval &b }
111157 settings_stack . pop
112158 else
113- Rack :: Mount :: Utils . normalize_path ( settings_stack . map { | s | s [ :namespace ] } . join ( '/' ) )
159+ instance_eval & block
114160 end
115161 end
116162
0 commit comments