diff --git a/README.markdown b/README.markdown index 995a64e..0ddc455 100644 --- a/README.markdown +++ b/README.markdown @@ -117,6 +117,32 @@ MyApi::Application.routes.draw do end ``` +### Using Multiple Strategies + +It is possible to combine two or more of the above strategies. One +example of when you might want to support multiple strategies +simultaneously is if you have an API that supports JSONP. Your preferred +strategy might be for users of the API to set a header, but since JSONP +doesn't support setting custom headers, you also need to support either +:path or :parameter. + +Example: + +```ruby +MyApi::Application.routes.draw do + api_version(:module => 'V2', :header => 'API-VERSION', :parameter => "version", :value => 'v2', :path => 'v2') do + match '/foos.(:format)' => 'foos#index', :via => :get + match '/foos_no_format' => 'foos#index', :via => :get + resources :bars + end +end +``` + +Caveat: If you are using :header and :parameter, they need to share the +same value. For this reason, if you use mupltiple strategies, you will +probably want to set a custom header instead of using an Accept mime +type. + ### Default Version If a request is made to your API without specifying a specific version, by default a RoutingError (i.e. 404) will occur. You can optionally configure Versionist to diff --git a/gemfiles/Rails-3.0.lock b/gemfiles/Rails-3.0.lock index 45d2abd..00483d9 100644 --- a/gemfiles/Rails-3.0.lock +++ b/gemfiles/Rails-3.0.lock @@ -1,5 +1,5 @@ PATH - remote: /Users/bploetz/workspace/versionist + remote: /Volumes/Extra/htdocs/versionist specs: versionist (0.3.1) rails (~> 3.0) diff --git a/gemfiles/Rails-3.1.lock b/gemfiles/Rails-3.1.lock index d687218..ff234c1 100644 --- a/gemfiles/Rails-3.1.lock +++ b/gemfiles/Rails-3.1.lock @@ -1,5 +1,5 @@ PATH - remote: /Users/bploetz/workspace/versionist + remote: /Volumes/Extra/htdocs/versionist specs: versionist (0.3.1) rails (~> 3.0) diff --git a/gemfiles/Rails-3.2.lock b/gemfiles/Rails-3.2.lock index 27a7ebc..b5b4d45 100644 --- a/gemfiles/Rails-3.2.lock +++ b/gemfiles/Rails-3.2.lock @@ -1,5 +1,5 @@ PATH - remote: /Users/bploetz/workspace/versionist + remote: /Volumes/Extra/htdocs/versionist specs: versionist (0.3.1) rails (~> 3.0) diff --git a/lib/versionist/routing.rb b/lib/versionist/routing.rb index ef4f005..5e07064 100644 --- a/lib/versionist/routing.rb +++ b/lib/versionist/routing.rb @@ -14,10 +14,12 @@ def api_version(config, &block) raise ArgumentError, "you must specify :header, :path, or :parameter in configuration Hash passed to api_version" if !config.has_key?(:header) && !config.has_key?(:path) && !config.has_key?(:parameter) raise ArgumentError, ":defaults must be a Hash" if config.has_key?(:defaults) && !config[:defaults].is_a?(Hash) if config.has_key?(:header) - return configure_header(config, &block) - elsif config.has_key?(:path) - return configure_path(config, &block) - elsif config.has_key?(:parameter) + configure_header(config, &block) + end + if config.has_key?(:path) + configure_path(config, &block) + end + if config.has_key?(:parameter) configure_parameter(config, &block) end end diff --git a/lib/versionist/versioning_strategy/base.rb b/lib/versionist/versioning_strategy/base.rb index c0443ac..f0f626b 100644 --- a/lib/versionist/versioning_strategy/base.rb +++ b/lib/versionist/versioning_strategy/base.rb @@ -10,7 +10,7 @@ def initialize(config={}) raise ArgumentError, "you must pass a configuration Hash" if config.nil? || !config.is_a?(Hash) @config = config @config.symbolize_keys! - if @config.has_key?(:default) + if @config.delete(:default) @default = true else @default = false diff --git a/spec/api_routing_spec.rb b/spec/api_routing_spec.rb index 0152673..2b1c3ce 100644 --- a/spec/api_routing_spec.rb +++ b/spec/api_routing_spec.rb @@ -632,6 +632,38 @@ end end end + + context "multi strategy" do + before :each do + TestApi::Application.routes.draw do + api_version({:module => mod, :header => "API-VERSION", :parameter => "version", :path => ver, :value => ver, :default => true}) do + match '/foos.(:format)' => 'foos#index', :via => :get + end + end + end + + it "should route to the correct controller when header matches" do + @headers["HTTP_API_VERSION"] = ver + get "/foos.json", nil, @headers + assert_response 200 + assert_equal 'application/json', response.content_type + assert_equal ver, response.body + end + + it "should route to the correct controller when path matches" do + get "/#{ver}/foos.json", nil, @headers + assert_response 200 + assert_equal 'application/json', response.content_type + assert_equal ver, response.body + end + + it "should route to the correct controller when parameter matches" do + get "/foos.json?version=#{ver}", nil, @headers + assert_response 200 + assert_equal 'application/json', response.content_type + assert_equal ver, response.body + end + end end end end diff --git a/spec/versioning_strategy/base_spec.rb b/spec/versioning_strategy/base_spec.rb index c59b5d3..916251e 100644 --- a/spec/versioning_strategy/base_spec.rb +++ b/spec/versioning_strategy/base_spec.rb @@ -24,9 +24,12 @@ @base2 = Versionist::VersioningStrategy::Base.new({"default" => true}) @base2.default?.should == true - # symbolize_keys! should be called - @base2.config.should_not == {"default" => true} - @base2.config.should == {:default => true} + end + + it "should call symbolize_keys" do + @base2 = Versionist::VersioningStrategy::Base.new({"foo" => true}) + @base2.config.should_not == {"foo" => true} + @base2.config.should == {:foo => true} end it "should add self to Versionist::Configuration.versioning_strategies" do @@ -63,8 +66,8 @@ context "==" do before :each do - @base = Versionist::VersioningStrategy::Base.new({:default => false}) - @equal_base = Versionist::VersioningStrategy::Base.new({:default => false}) + @base = Versionist::VersioningStrategy::Base.new({:path => 'V1'}) + @equal_base = Versionist::VersioningStrategy::Base.new({:path => 'V1'}) end it "should return true if passed an equal object" do