@@ -8,34 +8,34 @@ module Grape
88 # on the instance level of this class may be called
99 # from inside a `get`, `post`, etc. block.
1010 class Endpoint
11- def self . generate ( options = { } , & block )
12- c = Class . new ( Grape :: Endpoint )
13- c . class_eval do
14- @block = block
15- @options = options
16- end
17- c
11+ attr_accessor :block , :options , :settings
12+ attr_reader :env , :request
13+
14+ def initialize ( settings , options = { } , & block )
15+ @settings = settings
16+ @block = block
17+ @options = options
1818 end
19-
20- class << self
21- attr_accessor :block , :options
19+
20+ def call ( env )
21+ dup . call! ( env )
2222 end
23-
24- def self . call ( env )
25- new . call ( env )
23+
24+ def call! ( env )
25+ builder = build_middleware
26+ builder . run lambda { |env | self . run ( env ) }
27+ builder . call ( env )
2628 end
27-
28- attr_reader :env , :request
29-
29+
3030 # The parameters passed into the request as
3131 # well as parsed from URL segments.
3232 def params
3333 @params ||= Hashie ::Mash . new . deep_merge ( request . params ) . deep_merge ( env [ 'rack.routing_args' ] || { } )
3434 end
35-
35+
3636 # The API version as specified in the URL.
3737 def version ; env [ 'api.version' ] end
38-
38+
3939 # End the request and display an error to the
4040 # end user with the specified message.
4141 #
@@ -44,7 +44,7 @@ def version; env['api.version'] end
4444 def error! ( message , status = 403 )
4545 throw :error , :message => message , :status => status
4646 end
47-
47+
4848 # Set or retrieve the HTTP status code.
4949 #
5050 # @param status [Integer] The HTTP Status Code to return for this request.
@@ -59,9 +59,9 @@ def status(status = nil)
5959 else
6060 200
6161 end
62- end
62+ end
6363 end
64-
64+
6565 # Set an individual header or retrieve
6666 # all headers that have been set.
6767 def header ( key = nil , val = nil )
@@ -109,7 +109,7 @@ def present(object, options = {})
109109 entity_class = options . delete ( :with )
110110
111111 object . class . ancestors . each do |potential |
112- entity_class ||= self . class . options [ :representations ] [ potential ]
112+ entity_class ||= ( settings [ :representations ] || { } ) [ potential ]
113113 end
114114
115115 if entity_class
@@ -121,24 +121,68 @@ def present(object, options = {})
121121 end
122122 end
123123
124- def call ( env )
124+ protected
125+
126+ def run ( env )
125127 @env = env
126128 @header = { }
127129 @request = Rack ::Request . new ( @env )
128130
129- run_filters self . class . options [ :befores ]
130- response_text = instance_eval &self . class . block
131- run_filters self . class . options [ :afters ]
131+ self . extend helpers
132+ run_filters befores
133+ response_text = instance_eval &self . block
134+ run_filters afters
132135
133136 [ status , header , [ body || response_text ] ]
134137 end
135138
136- protected
139+ def build_middleware
140+ b = Rack ::Builder . new
141+ b . use Grape ::Middleware ::Error ,
142+ :default_status => settings [ :default_error_status ] || 403 ,
143+ :rescue_all => settings [ :rescue_all ] ,
144+ :rescued_errors => settings [ :rescued_errors ] ,
145+ :format => settings [ :error_format ] || :txt ,
146+ :rescue_options => settings [ :rescue_options ] ,
147+ :rescue_handlers => settings [ :rescue_handlers ] || { }
148+
149+ b . use Rack ::Auth ::Basic , settings [ :auth ] [ :realm ] , &settings [ :auth ] [ :proc ] if settings [ :auth ] && settings [ :auth ] [ :type ] == :http_basic
150+ b . use Rack ::Auth ::Digest ::MD5 , settings [ :auth ] [ :realm ] , settings [ :auth ] [ :opaque ] , &settings [ :auth ] [ :proc ] if settings [ :auth ] && settings [ :auth ] [ :type ] == :http_digest
151+ b . use Grape ::Middleware ::Prefixer , :prefix => settings [ :root_prefix ] if settings [ :root_prefix ]
152+
153+ if settings [ :version ]
154+ b . use Grape ::Middleware ::Versioner . using ( settings [ :version_options ] [ :using ] ) , {
155+ :versions => settings [ :version ] ,
156+ :version_options => settings [ :version_options ]
157+ }
158+ end
159+
160+ b . use Grape ::Middleware ::Formatter , :default_format => settings [ :default_format ] || :json
161+
162+ aggregate_setting ( :middleware ) . each { |m | b . use *m }
163+
164+ b
165+ end
166+
167+ def helpers
168+ m = Module . new
169+ settings . stack . each { |frame | m . send :include , frame [ :helpers ] if frame [ :helpers ] }
170+ m
171+ end
172+
173+ def aggregate_setting ( key )
174+ settings . stack . inject ( [ ] ) do |aggregate , frame |
175+ aggregate += ( frame [ key ] || [ ] )
176+ end
177+ end
137178
138179 def run_filters ( filters )
139180 ( filters || [ ] ) . each do |filter |
140181 instance_eval &filter
141182 end
142183 end
184+
185+ def befores ; aggregate_setting ( :befores ) end
186+ def afters ; aggregate_setting ( :afters ) end
143187 end
144188end
0 commit comments