Skip to content

Commit 915c2e2

Browse files
author
Michael Bleigh
committed
Merge pull request ruby-grape#93 from dblock/frontier-routes-2
frontier: restored api routes functionality
2 parents 4de9620 + 886fbf6 commit 915c2e2

File tree

3 files changed

+121
-103
lines changed

3 files changed

+121
-103
lines changed

lib/grape/api.rb

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ def middleware
324324

325325
# An array of API routes.
326326
def routes
327-
@routes ||= []
327+
@routes ||= prepare_routes
328328
end
329329

330330
def versions
@@ -333,6 +333,14 @@ def versions
333333

334334
protected
335335

336+
def prepare_routes
337+
routes = []
338+
endpoints.each do |endpoint|
339+
routes.concat(endpoint.routes)
340+
end
341+
routes
342+
end
343+
336344
# Execute first the provided block, then each of the
337345
# block passed in. Allows for simple 'before' setups
338346
# of settings stack pushes.
@@ -364,7 +372,6 @@ def initialize
364372
self.class.endpoints.each do |endpoint|
365373
endpoint.mount_in(@route_set)
366374
end
367-
368375
@route_set.freeze
369376
end
370377

lib/grape/endpoint.rb

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -25,36 +25,47 @@ def initialize(settings, options = {}, &block)
2525

2626
options[:route_options] ||= {}
2727
end
28+
29+
def routes
30+
@routes ||= prepare_routes
31+
end
2832

2933
def mount_in(route_set)
3034
if options[:app] && options[:app].respond_to?(:endpoints)
3135
options[:app].endpoints.each{|e| e.mount_in(route_set)}
3236
else
33-
options[:method].each do |method|
34-
options[:path].each do |path|
35-
prepared_path = prepare_path(path)
36-
path = compile_path(prepared_path, !options[:app])
37-
regex = Rack::Mount::RegexpWithNamedGroups.new(path)
38-
path_params = regex.named_captures.map { |nc| nc[0] } - [ 'version', 'format' ]
39-
path_params |= (options[:route_options][:params] || [])
40-
request_method = (method.to_s.upcase unless method == :any)
41-
42-
# routes << Route.new(route_options.merge({
43-
# :prefix => prefix,
44-
# :version => settings[:version] ? settings[:version].join('|') : nil,
45-
# :namespace => namespace,
46-
# :method => request_method,
47-
# :path => prepared_path,
48-
# :params => path_params})
49-
# )
50-
51-
route_set.add_route(self,
52-
:path_info => path,
53-
:request_method => request_method
54-
)
55-
end
37+
routes.each do |route|
38+
route_set.add_route(self,
39+
:path_info => route.route_compiled,
40+
:request_method => route.route_method
41+
)
42+
end
43+
end
44+
end
45+
46+
def prepare_routes
47+
routes = []
48+
options[:method].each do |method|
49+
options[:path].each do |path|
50+
prepared_path = prepare_path(path)
51+
path = compile_path(prepared_path, !options[:app])
52+
regex = Rack::Mount::RegexpWithNamedGroups.new(path)
53+
path_params = regex.named_captures.map { |nc| nc[0] } - [ 'version', 'format' ]
54+
path_params |= (options[:route_options][:params] || [])
55+
request_method = (method.to_s.upcase unless method == :any)
56+
routes << Route.new(options[:route_options].clone.merge({
57+
:prefix => settings[:root_prefix],
58+
:version => settings[:version] ? settings[:version].join('|') : nil,
59+
:namespace => namespace,
60+
:method => request_method,
61+
:path => prepared_path,
62+
:params => path_params,
63+
:compiled => path,
64+
})
65+
)
5666
end
5767
end
68+
routes
5869
end
5970

6071
def prepare_path(path)

spec/grape/api_spec.rb

Lines changed: 78 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -699,84 +699,84 @@ def hello
699699
end
700700
end
701701

702-
# context "routes" do
703-
# describe "empty api structure" do
704-
# it "returns an empty array of routes" do
705-
# subject.routes.should == []
706-
# end
707-
# end
708-
# describe "single method api structure" do
709-
# before(:each) do
710-
# subject.get :ping do
711-
# 'pong'
712-
# end
713-
# end
714-
# it "returns one route" do
715-
# subject.routes.size.should == 1
716-
# route = subject.routes[0]
717-
# route.route_version.should be_nil
718-
# route.route_path.should == "/ping(.:format)"
719-
# route.route_method.should == "GET"
720-
# end
721-
# end
722-
# describe "api structure with two versions and a namespace" do
723-
# class TwitterAPI < Grape::API
724-
# # version v1
725-
# version 'v1', :using => :path
726-
# get "version" do
727-
# api.version
728-
# end
729-
# # version v2
730-
# version 'v2', :using => :path
731-
# prefix 'p'
732-
# namespace "n1" do
733-
# namespace "n2" do
734-
# get "version" do
735-
# api.version
736-
# end
737-
# end
738-
# end
739-
# end
740-
# it "should return versions" do
741-
# TwitterAPI::versions.should == [ 'v1', 'v2' ]
742-
# end
743-
# it "should set route paths" do
744-
# TwitterAPI::routes.size.should >= 2
745-
# TwitterAPI::routes[0].route_path.should == "/:version/version(.:format)"
746-
# TwitterAPI::routes[1].route_path.should == "/p/:version/n1/n2/version(.:format)"
747-
# end
748-
# it "should set route versions" do
749-
# TwitterAPI::routes[0].route_version.should == 'v1'
750-
# TwitterAPI::routes[1].route_version.should == 'v2'
751-
# end
752-
# it "should set a nested namespace" do
753-
# TwitterAPI::routes[1].route_namespace.should == "/n1/n2"
754-
# end
755-
# it "should set prefix" do
756-
# TwitterAPI::routes[1].route_prefix.should == 'p'
757-
# end
758-
# end
759-
# describe "api structure with additional parameters" do
760-
# before(:each) do
761-
# subject.get 'split/:string', { :params => [ "token" ], :optional_params => [ "limit" ] } do
762-
# params[:string].split(params[:token], (params[:limit] || 0).to_i)
763-
# end
764-
# end
765-
# it "should split a string" do
766-
# get "/split/a,b,c.json", :token => ','
767-
# last_response.body.should == '["a","b","c"]'
768-
# end
769-
# it "should split a string with limit" do
770-
# get "/split/a,b,c.json", :token => ',', :limit => '2'
771-
# last_response.body.should == '["a","b,c"]'
772-
# end
773-
# it "should set route_params" do
774-
# subject.routes.size.should == 1
775-
# subject.routes[0].route_params.should == [ "string", "token" ]
776-
# subject.routes[0].route_optional_params.should == [ "limit" ]
777-
# end
778-
# end
779-
# end
702+
context "routes" do
703+
describe "empty api structure" do
704+
it "returns an empty array of routes" do
705+
subject.routes.should == []
706+
end
707+
end
708+
describe "single method api structure" do
709+
before(:each) do
710+
subject.get :ping do
711+
'pong'
712+
end
713+
end
714+
it "returns one route" do
715+
subject.routes.size.should == 1
716+
route = subject.routes[0]
717+
route.route_version.should be_nil
718+
route.route_path.should == "/ping(.:format)"
719+
route.route_method.should == "GET"
720+
end
721+
end
722+
describe "api structure with two versions and a namespace" do
723+
class TwitterAPI < Grape::API
724+
# version v1
725+
version 'v1', :using => :path
726+
get "version" do
727+
api.version
728+
end
729+
# version v2
730+
version 'v2', :using => :path
731+
prefix 'p'
732+
namespace "n1" do
733+
namespace "n2" do
734+
get "version" do
735+
api.version
736+
end
737+
end
738+
end
739+
end
740+
it "should return versions" do
741+
TwitterAPI::versions.should == [ 'v1', 'v2' ]
742+
end
743+
it "should set route paths" do
744+
TwitterAPI::routes.size.should >= 2
745+
TwitterAPI::routes[0].route_path.should == "/:version/version(.:format)"
746+
TwitterAPI::routes[1].route_path.should == "/p/:version/n1/n2/version(.:format)"
747+
end
748+
it "should set route versions" do
749+
TwitterAPI::routes[0].route_version.should == 'v1'
750+
TwitterAPI::routes[1].route_version.should == 'v2'
751+
end
752+
it "should set a nested namespace" do
753+
TwitterAPI::routes[1].route_namespace.should == "/n1/n2"
754+
end
755+
it "should set prefix" do
756+
TwitterAPI::routes[1].route_prefix.should == 'p'
757+
end
758+
end
759+
describe "api structure with additional parameters" do
760+
before(:each) do
761+
subject.get 'split/:string', { :params => [ "token" ], :optional_params => [ "limit" ] } do
762+
params[:string].split(params[:token], (params[:limit] || 0).to_i)
763+
end
764+
end
765+
it "should split a string" do
766+
get "/split/a,b,c.json", :token => ','
767+
last_response.body.should == '["a","b","c"]'
768+
end
769+
it "should split a string with limit" do
770+
get "/split/a,b,c.json", :token => ',', :limit => '2'
771+
last_response.body.should == '["a","b,c"]'
772+
end
773+
it "should set route_params" do
774+
subject.routes.size.should == 1
775+
subject.routes[0].route_params.should == [ "string", "token" ]
776+
subject.routes[0].route_optional_params.should == [ "limit" ]
777+
end
778+
end
779+
end
780780

781781
describe ".rescue_from klass, block" do
782782
it 'should rescue Exception' do

0 commit comments

Comments
 (0)