README.md in versioncake-2.5.0 vs README.md in versioncake-3.0.0
- old
+ new
@@ -27,23 +27,44 @@
## Install
```
gem install versioncake
+rails g versioncake:install
```
### Requirements
-| Version | Rails 3.2 Support? | Rails 4 Support? | Rails 4.1 Support? | [Rails API](https://github.com/rails-api/rails-api) 0.2 Support? |
-| ------- |:---------:| -------:| -------:| -------:|
-| [1.0](CHANGELOG.md#100-march-14-2013) | Yes | No | No | No |
-| [1.1](CHANGELOG.md#110-may-18-2013) | Yes | No | No | No |
-| [1.2](CHANGELOG.md#120-may-26-2013) | Yes | Yes | No | No |
-| [1.3](CHANGELOG.md#130-sept-26-2013) | Yes | Yes | No | No |
-| [>2.0](CHANGELOG.md#200-feb-6-2014) | Yes | Yes | Yes | No |
-| [>2.4](CHANGELOG.md#200-feb-6-2014) | Yes | Yes | Yes | Yes |
+| Version | Rails 3.2 Support? | Rails 4 Support? | Rails >4.1 Support? | Rails >5 Support? | [Rails API](https://github.com/rails-api/rails-api) 0.2 Support? |
+| -------:|:---------:| -------:| -------:| -------:| -------:|
+| [1.0](CHANGELOG.md#100-march-14-2013) | Yes | No | No | No | No |
+| [1.1](CHANGELOG.md#110-may-18-2013) | Yes | No | No | No | No |
+| [1.2](CHANGELOG.md#120-may-26-2013) | Yes | Yes | No | No | No |
+| [1.3](CHANGELOG.md#130-sept-26-2013) | Yes | Yes | No | No | No |
+| [>2.0](CHANGELOG.md#200-feb-6-2014) | Yes | Yes | Yes | No | No |
+| [>2.4](CHANGELOG.md#200-feb-6-2014) | Yes | Yes | Yes | No | Yes |
+| [>3.0](CHANGELOG.md) | Yes | Yes | Yes | Yes | Yes |
+## Upgrade v2.0 -> v3.0
+
+### Accept header name changes
+
+The default accept header was changed from 'X-API-Version' to 'API-Version'. If you require the 'X-' or some other variant, you can specify a custom strategy as outlined in Extraction Strategy section below.
+
+### Configuration changes
+
+Configuration is now done with an initializer-you can generate a default one with `rails g versioncake:install` and then modify the generated file to match your configuration.
+
+### Configuration changes
+
+The configuration options for Version Cake have changed:
+
+| Old Name | New Name |
+| -------------------------------------------- | ---------------------- |
+| config.versioncake.supported_version_numbers | config.resources |
+| config.versioncake.default_version | config.missing_version |
+
## Upgrade v1.* -> v2.0
### Filename changes
The major breaking change to require a bump to v2.0 was the order of the extensions. To avoid priority issues with the format (#14), the version number and the format have been swapped.
@@ -68,12 +89,17 @@
In this simple example we will outline the code that is introduced to support a change in a version.
### config/application.rb
```ruby
-config.versioncake.supported_version_numbers = (1...4)
-config.versioncake.extraction_strategy = :query_parameter # for simplicity
+VersionCake.setup do |config|
+ config.resources do |r|
+ r.resource %r{.*}, [], [], (1..4)
+ end
+ config.extraction_strategy = :query_parameter # for simplicity
+ config.missing_version = 4
+end
```
Often times with APIs, depending upon the version, different logic needs to be applied. With the following controller code, the initial value of @posts includes all Post entries.
But if the requested API version is three or greater, we're going to eagerly load the associated comments as well.
@@ -85,11 +111,11 @@
def index
# shared code for all versions
@posts = Post.scoped
# version 3 or greated supports embedding post comments
- if derived_version >= 3
+ if request_version >= 3
@posts = @posts.includes(:comments)
end
end
end
```
@@ -158,11 +184,11 @@
}
]
```
-When no version is specified, the latest version of the view is rendered. In this case, views/posts/index.json.v4.jbuilder.
+When no version is specified, the configured `missing_version` will be used to render a view. In this case, views/posts/index.json.v4.jbuilder.
#### http://localhost:3000/posts.json
```javascript
[
{
@@ -193,33 +219,41 @@
```
## How to use
### Configuration
-The configuration should be placed in your Rails projects `config/application.rb`. It is also suggested to enable different settings per environment, for example development and test can have extraction strategies that make it easier to develop or write test code.
+The configuration lives in `config/initializers/versioncake.rb`.
-#### Supported Versions
-You need to define the supported versions in your Rails application.rb file as `view_versions`. Use this config to set the range of supported API versions that can be served:
+#### Versioned Resources
+Each individual resource uri can be identified by a regular expression. For each one it can be customized to have obsolete, deprecated, supported versions.
```ruby
-config.versioncake.supported_version_numbers = [1,2,3,4,5] # or (1..5)
+ config.resources do |r|
+ # r.resource uri_regex, obsolete, deprecated, supported
+
+ # version 2 and 3 are still supported on users resource
+ r.resource %r{/users}, [1], [2,3], [4]
+
+ # all other resources only allow v4
+ r.resource %r{.*}, [1,2,3], [], [4]
+ end
```
#### Extraction Strategy
-You can also define the way to extract the version. The `view_version_extraction_strategy` allows you to set one of the default strategies or provide a proc to set your own. You can also pass it a prioritized array of the strategies.
+You can also define the way to extract the version. The `extraction_strategy` allows you to set one of the default strategies or provide a proc to set your own. You can also pass it a prioritized array of the strategies.
```ruby
-config.versioncake.extraction_strategy = :query_parameter # [:http_header, :http_accept_parameter]
+config.extraction_strategy = :query_parameter # [:http_header, :http_accept_parameter]
```
These are the available strategies:
Strategy | Description | Example
--- | --- | ---
:query_parameter | version in the url query parameter, for testing or to override for special case | `http://localhost:3000/posts.json?api_version=1` (This is the default.)
:path_parameter | version in the url path parameter | `api/v:api_version/`
-request_parameter | version that is sent in the body of the request | Good for testing.
-:http_header | Api version HTTP header | `X-API-Version: 1`
+:request_parameter | version that is sent in the body of the request | Good for testing.
+:http_header | Api version HTTP header | `API-Version: 1`
:http_accept_parameter | HTTP Accept header | `Accept: application/xml; version=1` [why do this?](http://blog.steveklabnik.com/posts/2011-07-03-nobody-understands-rest-or-http#i_want_my_api_to_be_versioned)
custom | takes the request object and must return an integer | lambda {|request| request.headers["HTTP_X_MY_VERSION"].to_i } or class ExtractorStrategy; def execute(request);end;end
If you use the path_parameter strategy with resources routes, you will want to setup your routes.rb config file to capture the api version. You can do that in a few ways. If you have just a few api routes you might specify the path directly like this:
```
@@ -234,20 +268,26 @@
#### Default Version
When no version is supplied by a client, the version rendered will be the latest version by default. If you want to override this to another version, set the following property:
```ruby
-config.versioncake.default_version = 4
+config.missing_version = 4
```
#### Version String
The extraction strategies use a default string key of `api_version`, but that can be changed:
```ruby
-config.versioncake.version_key = "special_version_parameter_name"
+config.version_key = "special_version_parameter_name"
```
+#### Version String
+If you do not wish to use the magic mapping of the version number to templates it can be disabled:
+```ruby
+config.rails_view_versioning = false
+```
+
### Version your views
When a client makes a request to your controller the latest version of the view will be rendered. The latest version is determined by naming the template or partial with a version number that you configured to support.
```
@@ -271,34 +311,44 @@
def index
# shared code for all versions
@posts = Post.scoped
# version 3 or greated supports embedding post comments
- if derived_version >= 3
+ if request_version >= 3
@posts = @posts.includes(:comments)
end
end
```
### Client requests
When a client makes a request it will automatically receive the latest supported version of the view. The client can also request for a specific version by one of the strategies configured by ``view_version_extraction_strategy``.
-### Unsupported Version Requests
+### Raised exceptions
-If a client requests a version that is no longer supported (is not included in the `config.versioncake.supported_version_numbers`), a `VersionCake::UnsupportedVersionError` will be raised. This can be handled using Rails `rescue_from` to return app specific messages to the client.
+These are the types of exceptions VersionCake will raise:
+|Exception type|Description|
+|--------------|-----------|
+|VersionCake::UnsupportedVersionError| The version is invalid, too high or too low for the resource.|
+|VersionCake::ObsoleteVersionError|The version is obsolete for the resource.|
+|VersionCake::MissingVersionError|If no `config.missing_version` is specified, this will be raised when no version is in the request.|
+
+### Handling Exceptions
+
+Handling exceptions can simply be done by using Rails `rescue_from` to return app specific messages to the client.
+
```ruby
class ApplicationController < ActionController::Base
...
rescue_from VersionCake::UnsupportedVersionError, :with => :render_unsupported_version
private
def render_unsupported_version
- headers['X-API-Version-Supported'] = 'false'
+ headers['API-Version-Supported'] = 'false'
respond_to do |format|
format.json { render json: {message: "You requested an unsupported version (#{requested_version})"}, status: :unprocessable_entity }
end
end
@@ -315,19 +365,19 @@
### Test configuration
Allowing more extraction strategies during testing can be helpful when needing to override the version.
```ruby
# config/environments/test.rb
-config.versioncake.extraction_strategy = [:query_parameter, :request_parameter, :http_header, :http_accept_parameter]
+config.extraction_strategy = [:query_parameter, :request_parameter, :http_header, :http_accept_parameter]
```
### Testing a specific version
One way to test a specific version for would be to stub the requested version in the before block:
```ruby
before do
- @controller.stubs(:requested_version).returns(3)
+ @controller.stubs(:request_version).returns(3)
end
```
You can also test a specific version through a specific strategy such query_parameter or request_parameter strategies (configured in test environment) like so:
```ruby
@@ -341,10 +391,10 @@
### Testing all supported versions
You can iterate over all of the supported version numbers by accessing the ```AppName::Application.config.versioncake.supported_version_numbers```.
```ruby
-AppName::Application.config.versioncake.supported_version_numbers.each do |supported_version|
+VersionCake.config.resources.first.supported_versions.each do |supported_version|
before do
@controller.stubs(:requested_version).returns(supported_version)
end
test "all versions render the correct template" do