Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

API versioning with rspec_api_documentation and apitome

We are using rspec_api_documentation and managed to generate the documentation for the 2 versions we have so far with the following code:

RspecApiDocumentation.configure do |config|
  config.docs_dir = Rails.root.join('doc', 'api', 'all')

  config.define_group :v1 do |config|
    config.filter = :v1
    config.docs_dir = Rails.root.join('doc', 'api', 'v1')
    config.api_name = 'API V1'
  end

  config.define_group :v2 do |config|
    config.filter = :v2
    config.docs_dir = Rails.root.join('doc', 'api', 'v2')
    config.api_name = 'API V2'
  end
end

We are using apitome to render these docs, however, we haven't been able to find a way to mount the routes for the 2 versions of the API 2 so far.

Any ideas?

like image 856
rebagliatte Avatar asked Nov 02 '15 19:11

rebagliatte


1 Answers

Answering my own question in case it helps others.

  1. Define your api versions as constants

    API_VERSIONS = [:v1, :v2]
    API_LAST_VERSION = API_VERSIONS.last
    
  2. Define document groups for each version and output json files on separate folders

    # spec/spec_helper.rb
    
    RspecApiDocumentation.configure do |config|
      config.format = :json
    
      API_VERSIONS.each do |version|
        config.define_group(version) do |config|
          config.filter = version
          config.docs_dir = Rails.root.join('doc', 'api', version.to_s)
        end
      end
    end
    
  3. Use the document groups when coding your specs

    # spec/acceptance/v1/users_spec.rb
    
    resource 'User' do
      post '/users' do
        example 'Identify a user', document: :v1 do
          # your v1 spec here
        end
      end
    end
    
    # spec/acceptance/v2/users_spec.rb
    
    resource 'User' do
      post '/users' do
        example 'Identify a user', document: :v2 do
          # your v2 spec here
        end
      end
    end
    
  4. Comment out doc_path and mount_at from config/initializers/apitome.rb

  5. Define a route constraint which sets them

    # lib/apitome_version.rb
    
    class ApitomeVersion
      def initialize(version)
        @path = "doc/api/#{ version }"
      end
    
      def matches?(request)
        # Load doc files from the right version folder
        Apitome.configuration.doc_path = @path
        # Mount all routes on the current request path (including simulated responses)
        Apitome.configuration.mount_at = request.path
        # Return a match
        true
      end
    end
    
  6. Mount your routes using that constraint, you can optionally set a default version

    # config/routes.rb
    
    Rails.application.routes.draw do
      # Mount documentation for each API version
      API_VERSIONS.each do |version|
        mount Apitome::Engine => "/api/docs/#{ version }",
          as: "apitome-#{ version }",
          constraints: ApitomeVersion.new(version)
      end
    
      # Optionally default to the last API version
      mount Apitome::Engine => '/api/docs',
        constraints: ApitomeVersion.new(API_LAST_VERSION)
    end
    
  7. Regenerate your documentation

    rake docs:generate
    
  8. Restart your server

like image 190
rebagliatte Avatar answered Oct 20 '22 12:10

rebagliatte