<commit_before>API-Versions [![Build Status](https://secure.travis-ci.org/erichmenge/api-versions.png)](http://travis-ci.org/erichmenge/api-versions)
======================================================================================================================================

If you have multiple versions of an API in your Rails app, it is not very DRY to include the same resources over and over again.

Also, URL resources shouldn't change. Instead, API versions should be specified in the headers. The api-versions gem provides a nice DSL for this.

In your Gemfile:

  gem "api-versions", "~> 0.1.0"

In your routes.rb file:

    api vendor_string: "myvendor", default_version: 1 do      # You can leave default_version out,
                                                              # but if you do the first version used will become the default
      version 1 do
        cache as: 'v1' do
          resources :authorizations
        end
      end

      version 2 do
        inherit from: 'v1'
      end
    end

`rake routes` outputs:

    api_authorizations      GET    /api/authorizations(.:format)          api/v1/authorizations#index
                            POST   /api/authorizations(.:format)          api/v1/authorizations#create
    new_api_authorization   GET    /api/authorizations/new(.:format)      api/v1/authorizations#new
    edit_api_authorization  GET    /api/authorizations/:id/edit(.:format) api/v1/authorizations#edit
     api_authorization      GET    /api/authorizations/:id(.:format)      api/v1/authorizations#show
                            PUT    /api/authorizations/:id(.:format)      api/v1/authorizations#update
                            DELETE /api/authorizations/:id(.:format)      api/v1/authorizations#destroy
                            GET    /api/authorizations(.:format)          api/v2/authorizations#index
                            POST   /api/authorizations(.:format)          api/v2/authorizations#create
                            GET    /api/authorizations/new(.:format)      api/v2/authorizations#new
                            GET    /api/authorizations/:id/edit(.:format) api/v2/authorizations#edit
                            GET    /api/authorizations/:id(.:format)      api/v2/authorizations#show
                            PUT    /api/authorizations/:id(.:format)      api/v2/authorizations#update
                            DELETE /api/authorizations/:id(.:format)      api/v2/authorizations#destroy


Then the client simply sets the Accept header "application/vnd.myvendor+json;version=1". If no version is specified, the default version you set will be assumed.  You'll of course still need to copy all of your controllers over, even if they haven't changed from version to version.  At least you'll remove a bit of the mess in your routes file.

A more complicated example:

    api vendor_string: "myvendor", default_version: 1 do
      version 1 do
        cache as: 'v1' do
          resources :authorizations, only: :create
          resources :foo
          resources :bar
        end
      end

      version 2 do
        cache as: 'v2' do
          inherit from: 'v1'
          resources :my_new_resource
        end
      end

      # V3 has everything in V2, and everything in V1 as well by virtue of V1 being cached in V2.
      version 3 do
        inherit from: 'v2'
      end
    end

And finally `rake routes` outputs:

    api_authorizations        POST   /api/authorizations(.:format)           api/v1/authorizations#create
                api_foo_index GET    /api/foo(.:format)                      api/v1/foo#index
                              POST   /api/foo(.:format)                      api/v1/foo#create
                  new_api_foo GET    /api/foo/new(.:format)                  api/v1/foo#new<commit_msg>Add Ruby style markdown.<commit_after>API-Versions [![Build Status](https://secure.travis-ci.org/erichmenge/api-versions.png)](http://travis-ci.org/erichmenge/api-versions)
======================================================================================================================================

If you have multiple versions of an API in your Rails app, it is not very DRY to include the same resources over and over again.

Also, URL resources shouldn't change. Instead, API versions should be specified in the headers. The api-versions gem provides a nice DSL for this.

In your Gemfile:

  gem "api-versions", "~> 0.1.0"

In your routes.rb file:

``` ruby
    api vendor_string: "myvendor", default_version: 1 do      # You can leave default_version out,
                                                              # but if you do the first version used will become the default
      version 1 do
        cache as: 'v1' do
          resources :authorizations
        end
      end

      version 2 do
        inherit from: 'v1'
      end
    end
```

`rake routes` outputs:

    api_authorizations      GET    /api/authorizations(.:format)          api/v1/authorizations#index
                            POST   /api/authorizations(.:format)          api/v1/authorizations#create
    new_api_authorization   GET    /api/authorizations/new(.:format)      api/v1/authorizations#new
    edit_api_authorization  GET    /api/authorizations/:id/edit(.:format) api/v1/authorizations#edit
     api_authorization      GET    /api/authorizations/:id(.:format)      api/v1/authorizations#show
                            PUT    /api/authorizations/:id(.:format)      api/v1/authorizations#update
                            DELETE /api/authorizations/:id(.:format)      api/v1/authorizations#destroy
                            GET    /api/authorizations(.:format)          api/v2/authorizations#index
                            POST   /api/authorizations(.:format)          api/v2/authorizations#create
                            GET    /api/authorizations/new(.:format)      api/v2/authorizations#new
                            GET    /api/authorizations/:id/edit(.:format) api/v2/authorizations#edit
                            GET    /api/authorizations/:id(.:format)      api/v2/authorizations#show
                            PUT    /api/authorizations/:id(.:format)      api/v2/authorizations#update
                            DELETE /api/authorizations/:id(.:format)      api/v2/authorizations#destroy


Then the client simply sets the Accept header "application/vnd.myvendor+json;version=1". If no version is specified, the default version you set will be assumed.  You'll of course still need to copy all of your controllers over, even if they haven't changed from version to version.  At least you'll remove a bit of the mess in your routes file.

A more complicated example:

``` ruby
    api vendor_string: "myvendor", default_version: 1 do
      version 1 do
        cache as: 'v1' do
          resources :authorizations, only: :create
          resources :foo
          resources :bar
        end
      end

      version 2 do
        cache as: 'v2' do
          inherit from: 'v1'
          resources :my_new_resource
        end
      end

      # V3 has everything in V2, and everything in V1 as well by virtue of V1 being cached in V2.
      version 3 do
        inherit from: 'v2'
      end
    end
```

And finally `rake routes` outputs:

    api_authorizations        POST   /api/authorizations(.:format)           api/v1/authorizations#create
                api_foo_index GET    /api/foo(.:format)                      api/v1/foo#index
                              POST   /api/foo(.:format)                      api/v1/foo#create
                  new_api_foo GET    /api/foo/new(.:format)                  api/v1/foo#new
{'fraction_non_alphanumeric': 0.11498893085037114, 'fraction_numerical': 0.010418023180101576, 'mean_word_length': 1.930179320869897, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6042118', 'n_tokens_mistral': 2073, 'n_tokens_neox': 1992, 'n_words': 598}