5

私はすでにいくつかの質問があり、this is a open issue regarding AMS not handling namespaces too efficiently(このバージョン管理のアプローチで使用されています)があることを知っていますが、現在の制約内で正しいトラックにいることを確認したいと思いました。active_model_serializersでAPIのバージョン管理を実装する正しい方法

今私はRailsの5とAMS 0.10.1を使用していますので、私は次のようでした:

# config/initializers/active_model_serializer.rb 
ActiveModelSerializers.config.serializer_lookup_enabled = false 

(とにかく動作しませんでした)デフォルトのシリアライザの検索を無効にします。

# app/controllers/application_controller.rb 
class ApplicationController < ActionController::API 
    def get_serializer(resource, options = {}) 
    unless options[:each_serializer] || options[:serializer] then 
     serializer = (self.class.name.gsub("Controller","").singularize + "Serializer").constantize 
     resource.respond_to?(:to_ary) ? options[:each_serializer] = serializer : options[:serializer] = serializer 
    end 
    super(resource, options) 
    end 
end 

デフォルトでシリアライザの検出方法を上書きする。私のコントローラとシリアライザは、このようなものです:今

# app/controllers/api/v2/api_controller.rb 
module Api::V2 
    class ApiController < ApplicationController 
    ... 

# app/controllers/api/v2/users_controller.rb 
module Api::V2 
    class UsersController < ApiController 
    ... 

# app/serializers/api/v2/user_serializer.rb 
module Api::V2 
    class UserSerializer < ActiveModel::Serializer 
    ...  

ActiveModel::Serializer.serializer_for(object)のようなものは動作しませんので、私はまた、サルはAPIのバージョンを設定するexample.metadata[:api_version]を使用して私の要求仕様にパッチを適用する必要がありました例がそれを設定しなかった場合には、各テストの前に、エラーを発生させてください。だから、

  1. が文書化され、より良い方法はありますか?
  2. これは間違いなく正しいですか?
  3. 私はこのアプローチでさらに問題に直面していますか?
  4. どうすれば改善できますか?

答えて

0

のようなAPIコントローラ何かの内側に、私はより良い方法を発見していないので、どこにも文書化もなく、どちらも、また、正しいと思えると私はそれを使用してしばらくした後、問題に直面していない、これが表示されますAPIのバージョニングに適したアプローチです。

とにかく、このアプローチを使用して、APIの古いサポートされているバージョンの動作を変更しないように注意してください。慎重にテストし、クライアントに非推奨版を通知し、古いバージョンの削除をサポートします。

5

ここにいるのは大丈夫です。私は同じアプローチを使用しており、私のアプリケーションでうまく動作します。私の実装では

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 

私は:彼がしたどこでこれは私がリソースごとに異なるシリアライザを指定するために使用するものは非常に似たアプローチを

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

説明ライアンベイツからここにオリジナルのアイデアを選びましたapi/controllers/api/v3/serializer内のシリアライザを使用します。だから、あなたは、APIエンドポイントの多くを持っている場合は、リソースでそれらを整理しようと大した

をシリアライザクラスとコントローラクラス

ない、これはより明確であるので、あなたが本当にget_serializerを持っている必要があることを確認してくださいバージョニングれていませんが。私は別のファイルのconfig/API/V1/routes.rbを...

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

にそれらを分割するように、私のconfig/routes.rbを、私は約700のリソースを持ってもinflections.rb初期化子

内で行うと便利です
ActiveSupport::Inflector.inflections(:en) do |inflect| 
    inflect.acronym 'API' 
end 

私にとっては、最も重要な問題は、テストの対象範囲を広げることです。私は仕様を好むし、正しいステータスコード200,201、...をチェックするjson_schemaを使用した正しい息子の出力

もしあなたが認証を行う必要があれば、トークンベースの認証とJWT - JSON Webトークンを使用することをお勧めします。私の実装では、私は2つのトークンを使用しています。 POSTとPATCHを実行しているときに読みとりトークンが1つあります(多分必要かもしれません)。したがって、この

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

ありがとうございました!私は物事を少し乾燥させるためにそれをしました。 'get_serializer'は常にAMSによって呼び出され、定義された規約に従わない場合は' render json:@object、serializer:Namespaced :: Unconventional :: ObjectSerializer'を使うだけです。 –

関連する問題