Correct way to implement API versioning with active_model_serializers

前端 未结 2 622
执笔经年
执笔经年 2020-12-29 16:01

I know there are already some questions and also this is a open issue regarding AMS not handling namespaces too efficiently (which is used by this versioning approach) but I

相关标签:
2条回答
  • 2020-12-29 16:26

    I think what you have here is okay. I am using the same approach and it works fine for my application. I picked the original idea here from Ryan Bates where he did explains very similar approach

    http://railscasts.com/episodes/350-rest-api-versioning

    This is what I use to specify different serializers for each resource:

    module API
      module V3
        class AssetController < API::V3::ApiController
          def index
            render json: assets, status: :ok, each_serializer: API::V3::Serializers::AssetSerializer
          end
      end
    end
    

    In my implementation I am using serializers inside api/controllers/api/v3/serializers. So you are versioning serializers classes and controller classes

    Not sure that you really need to have get_serializer since this is more explicit but not a big deal

    If you have a lot of api endpoints try to organize them in resources. In my config/routes.rb I have about 700 resources so I split them into separate files config/api/v1/routes.rb...

    namespace :api, defaults: {format: 'json'} do
      namespace :v1
        resources :assets
      end
    end
    

    Also It is handy to do inside inflections.rb initializer

    ActiveSupport::Inflector.inflections(:en) do |inflect|
      inflect.acronym 'API'
    end
    

    For me I would say that the biggest important issue is to have good testing coverage. I prefer spec and check for correct status codes 200, 201,...etc and as well as the correct son output using json_schema

    If you need to do auth then I would suggest that you use token based auth and JWT - JSON Web Token. In my implementation I am using two tokens. One token for reading and different token when doing POST and PATCH (not sure it is needed maybe). so inside API controller something like this

    class ApiController < ActionController::Base
      skip_before_action :verify_authenticity_token, if: :json_request?
      before_action :authenticate
    
      protected
      def json_request?
        request.format.json?
      end
      if request.headers['X-Authorization']
        token = request.headers['X-Authorization']
        payload = JWT.decode(token, 'my_custom_key_to_check_if_key_has_been_tempered d_on_client_side')[0]
      end
    end
    
    0 讨论(0)
  • 2020-12-29 16:34

    Since I haven't found a better way, neither documented nor anywhere, it also seems to be correct and I haven't faced problems after a while using it, this appear to be a good approach for API versioning.

    Anyway, I advise caution using this approach to not change behaviour of older supported versions for your API. Test carefully and notify your clients for deprecations and support removal for old versions.

    0 讨论(0)
提交回复
热议问题