5

이미 질문이 있으며 this is a open issue regarding AMS not handling namespaces too efficiently (이 버전 관리 방식에서 사용됨)을 알고 있지만 현재 제약 조건 내에서 올바른 위치에 있는지 확인하고 싶습니다.active_model_serializers를 사용하여 API 버전 관리를 구현하는 올바른 방법

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

하지 않도록 기본 시리얼 조회 (어쨌든 작동하지 않았다) :

는 지금 내가 레일 5 AMS 0.10.1을 사용하고, 그래서 다음과 같은했다

# 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 내부의 serializer 사용 그래서 당신은 시리얼 클래스와 컨트롤러 클래스

당신이 정말로 자원을 구성하려고하면 API 엔드 포인트가 많은 경우이 더 명확하지만 큰 문제가

때문에 get_serializer을 할 필요가

확실하지 버전 관리된다 .

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

는 또한 inflections.rb 이니셜

안에 할 편리합니다 ... 내 설정/routes.rb에서 나는 약 700 자원이 그래서 별도의 파일 설정/API/V1/routes.rb로 분할
ActiveSupport::Inflector.inflections(:en) do |inflect| 
    inflect.acronym 'API' 
end 

나를 위해 나는 가장 중요한 중요한 문제는 좋은 테스트 범위를 갖는 것이라고 말하고 싶습니다. 내가 사양을 선호 올바른 상태 코드 200, 201, 확인 ...등등뿐만 아니라 올바른 아들 출력을 사용하여 json_schema

만약 당신이 토큰 기반 인증 및 JWT - JSON 웹 토큰을 사용하는 것이 좋습니다 것이 다음을 권 해드립니다. 내 구현에서는 두 개의 토큰을 사용하고 있습니다. 독서를위한 하나의 토큰과 POST 및 PATCH 수행시 다른 토큰 (필요하지 않을지 모름). 이

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' 만 사용해야합니다. –

관련 문제