Skip to content
This repository has been archived by the owner on Feb 22, 2024. It is now read-only.

allow multiple versioning strategies simultaneously #26

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
26 changes: 26 additions & 0 deletions README.markdown
Expand Up @@ -117,6 +117,32 @@ MyApi::Application.routes.draw do
end 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 ### 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 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
Expand Down
2 changes: 1 addition & 1 deletion gemfiles/Rails-3.0.lock
@@ -1,5 +1,5 @@
PATH PATH
remote: /Users/bploetz/workspace/versionist remote: /Volumes/Extra/htdocs/versionist
specs: specs:
versionist (0.3.1) versionist (0.3.1)
rails (~> 3.0) rails (~> 3.0)
Expand Down
2 changes: 1 addition & 1 deletion gemfiles/Rails-3.1.lock
@@ -1,5 +1,5 @@
PATH PATH
remote: /Users/bploetz/workspace/versionist remote: /Volumes/Extra/htdocs/versionist
specs: specs:
versionist (0.3.1) versionist (0.3.1)
rails (~> 3.0) rails (~> 3.0)
Expand Down
2 changes: 1 addition & 1 deletion gemfiles/Rails-3.2.lock
@@ -1,5 +1,5 @@
PATH PATH
remote: /Users/bploetz/workspace/versionist remote: /Volumes/Extra/htdocs/versionist
specs: specs:
versionist (0.3.1) versionist (0.3.1)
rails (~> 3.0) rails (~> 3.0)
Expand Down
10 changes: 6 additions & 4 deletions lib/versionist/routing.rb
Expand Up @@ -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, "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) raise ArgumentError, ":defaults must be a Hash" if config.has_key?(:defaults) && !config[:defaults].is_a?(Hash)
if config.has_key?(:header) if config.has_key?(:header)
return configure_header(config, &block) configure_header(config, &block)
elsif config.has_key?(:path) end
return configure_path(config, &block) if config.has_key?(:path)
elsif config.has_key?(:parameter) configure_path(config, &block)
end
if config.has_key?(:parameter)
configure_parameter(config, &block) configure_parameter(config, &block)
end end
end end
Expand Down
2 changes: 1 addition & 1 deletion lib/versionist/versioning_strategy/base.rb
Expand Up @@ -10,7 +10,7 @@ def initialize(config={})
raise ArgumentError, "you must pass a configuration Hash" if config.nil? || !config.is_a?(Hash) raise ArgumentError, "you must pass a configuration Hash" if config.nil? || !config.is_a?(Hash)
@config = config @config = config
@config.symbolize_keys! @config.symbolize_keys!
if @config.has_key?(:default) if @config.delete(:default)
@default = true @default = true
else else
@default = false @default = false
Expand Down
32 changes: 32 additions & 0 deletions spec/api_routing_spec.rb
Expand Up @@ -632,6 +632,38 @@
end end
end 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 end
end end
Expand Down
13 changes: 8 additions & 5 deletions spec/versioning_strategy/base_spec.rb
Expand Up @@ -24,9 +24,12 @@


@base2 = Versionist::VersioningStrategy::Base.new({"default" => true}) @base2 = Versionist::VersioningStrategy::Base.new({"default" => true})
@base2.default?.should == true @base2.default?.should == true
# symbolize_keys! should be called end
@base2.config.should_not == {"default" => true}
@base2.config.should == {:default => true} 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 end


it "should add self to Versionist::Configuration.versioning_strategies" do it "should add self to Versionist::Configuration.versioning_strategies" do
Expand Down Expand Up @@ -63,8 +66,8 @@


context "==" do context "==" do
before :each do before :each do
@base = Versionist::VersioningStrategy::Base.new({:default => false}) @base = Versionist::VersioningStrategy::Base.new({:path => 'V1'})
@equal_base = Versionist::VersioningStrategy::Base.new({:default => false}) @equal_base = Versionist::VersioningStrategy::Base.new({:path => 'V1'})
end end


it "should return true if passed an equal object" do it "should return true if passed an equal object" do
Expand Down