Skip to content

Commit 10dd57b

Browse files
author
Michael Bleigh
committed
Waypoint commit. Y U FAILING, API MOUNTING?
1 parent 1e9def6 commit 10dd57b

File tree

6 files changed

+253
-167
lines changed

6 files changed

+253
-167
lines changed

lib/grape/api.rb

Lines changed: 48 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -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!

lib/grape/endpoint.rb

Lines changed: 66 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,78 @@ def initialize(settings, options = {}, &block)
1515
@settings = settings
1616
@block = block
1717
@options = options
18+
19+
raise ArgumentError, "Must specify :path option." unless options.key?(:path)
20+
options[:path] = Array(options[:path])
21+
options[:path] = ['/'] if options[:path].empty?
22+
23+
raise ArgumentError, "Must specify :method option." unless options.key?(:method)
24+
options[:method] = Array(options[:method])
25+
26+
options[:route_options] ||= {}
27+
end
28+
29+
def mount_in(route_set)
30+
options[:method].each do |method|
31+
options[:path].each do |path|
32+
prepared_path = prepare_path(path)
33+
path = compile_path(path, !options[:app])
34+
regex = Rack::Mount::RegexpWithNamedGroups.new(path)
35+
path_params = regex.named_captures.map { |nc| nc[0] } - [ 'version', 'format' ]
36+
path_params |= (options[:route_options][:params] || [])
37+
request_method = (method.to_s.upcase unless method == :any)
38+
39+
# routes << Route.new(route_options.merge({
40+
# :prefix => prefix,
41+
# :version => settings[:version] ? settings[:version].join('|') : nil,
42+
# :namespace => namespace,
43+
# :method => request_method,
44+
# :path => prepared_path,
45+
# :params => path_params})
46+
# )
47+
48+
route_set.add_route(self,
49+
:path_info => path,
50+
:request_method => request_method
51+
)
52+
end
53+
end
54+
end
55+
56+
def prepare_path(path)
57+
parts = []
58+
parts << settings[:root_prefix] if settings[:root_prefix]
59+
parts << ':version' if settings[:version] && settings[:version_options][:using] == :path
60+
parts << namespace.to_s if namespace
61+
parts << path.to_s if path && '/' != path
62+
parts.last << '(.:format)'
63+
Rack::Mount::Utils.normalize_path(parts.join('/'))
64+
end
65+
66+
def namespace
67+
Rack::Mount::Utils.normalize_path(settings.stack.map{|s| s[:namespace]}.join('/'))
68+
end
69+
70+
def compile_path(path, anchor = true)
71+
endpoint_options = {}
72+
endpoint_options[:version] = /#{settings[:version].join('|')}/ if settings[:version]
73+
74+
Rack::Mount::Strexp.compile(prepare_path(path), endpoint_options, %w( / . ? ), anchor)
1875
end
1976

2077
def call(env)
2178
dup.call!(env)
2279
end
2380

2481
def call!(env)
25-
builder = build_middleware
26-
builder.run lambda{|env| self.run(env) }
27-
builder.call(env)
82+
if options[:app]
83+
$stderr.puts env.inspect
84+
options[:app].call(env)
85+
else
86+
builder = build_middleware
87+
builder.run options[:app] || lambda{|env| self.run(env) }
88+
builder.call(env)
89+
end
2890
end
2991

3092
# The parameters passed into the request as
@@ -138,6 +200,7 @@ def run(env)
138200

139201
def build_middleware
140202
b = Rack::Builder.new
203+
141204
b.use Grape::Middleware::Error,
142205
:default_status => settings[:default_error_status] || 403,
143206
:rescue_all => settings[:rescue_all],

lib/grape/middleware/versioner/path.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,4 @@ def before
3939
end
4040
end
4141
end
42-
end
42+
end

0 commit comments

Comments
 (0)