API Versioning (Ruby on Rails)


One day, I am in the company that needs a different API Versioning that you can find in Google or blogs. You can find that you should do the versioning via Header. But what if somebody ask you that they want a versioning in Rails like this:

    
  localhost:3000/api/v1.0.0/users 
  
  

I having problem with using dot (.) because Rails is not supporting period in routing. Then, I ended up with this solution:

config/routes.rb

       

  scope "v:api_version", module: "v2", as: "v2", constraints: { api_version: /2(\.[01234]?)/ } do # /2(\.[01234]?)/ we use /2 because it is for v2
    resources :users, only: [:create]
  end
       
 

app/controllers/api/v2/users


       

  def index
    @user = User.all  
    
    respond_to do |format|
      format.json { render "api/v#{api_version.major}/#{api_version.minor}/accounts/show", status: 200, location: @users }
    end
  end

  private    
    def api_version
      @api_version ||= begin
        if params[:api_version].include?(".")
        major, minor = params[:api_version].split('.', 2).map(&:to_i)
        else # If no period after Major version then define minor as zero.
          major, minor = params[:api_version].to_i, 0.to_i
        end
        OpenStruct.new(major: major, minor: minor || 0)
      end
    end
       
 

And now in view, make sure you defined it as Major.Minor.Patch. But in my example, it is just major.minor. So, you should define your views like this:
       
app/views/api/
             /v1
                /0
                /1
             /v2
                /0
                /1
       
 
And now you can write your views in jbuilder in this example:
       
  json.extract! @users,
                   :first_name, :last_name
 
 

No comments:

Post a Comment