1

現在、Api::V1 と Api::V2 という 2 つの API 名前空間があります。

私は V2 を一度に実装するのではなく、時間をかけてゆっくりと実装する予定です。ただし、その一部が存在するため、クライアントがすべての HTTP 要求を V2 URL に送信し、その特定のエンドポイントがまだ実装されていない場合はサーバーに処理させることができればと思います。

V2 コントローラーにアクションがない場合、V2 要求を V1 コントローラーにルーティングする方法はありますか?

簡単な例:

ルート:

namespace :api do
    namespace :v1 do
        resources :items, only: [:index]
    end
    namespace :v2 do
        resources :items, only: :create
    end
end

次のエンドポイントが生成されます。

  1. /api/v1/items を取得
  2. POST /api/v2/items

V2 コントローラーにはまだこのメソッドがないため、GET 要求を /api/v2/items に送信し、Api::V1:ItemsController#index を呼び出すことが目標です。

4

2 に答える 2

1
namespace :api do

    namespace :v1, path: "v2" do
        # All endpoints that are on v1 of API
    end

    namespace :v2 do
        # All endpoints that are on v2 of API
    end

end

ここで rake ルートを実行すると、ルート「api/v2/___#_____」にすべて一致することがわかりますが、一番上のブロックのものは Api::V1 アクションを呼び出し、一番下のブロックのものは Api::V2 アクションを呼び出すので、これらのエンドポイントを実装するときに、それらを上から下に移動する必要があります

于 2016-08-10T19:37:02.253 に答える
0

バージョン管理された API もあります。私はまだ次のバージョンにぶつかっていません。しかし、私がやろうとしていることを共有したいと思いました。これは少し毛むくじゃらかもしれません。そして、これはあなたよりも私にとって(私の計画を熟考するために)役立つと感じています. では、申し訳ありません。しかし、ここに行く...

始める前に、私はコントローラーのアクションに対して別の種類のアプローチをとっていることを言っておく必要があります。私のアプリでは、コントローラーのアクションを、私が「マネージャー」と呼ぶ単純な古い Ruby オブジェクトに委譲するのが好きです。すべてのコントローラーには「manager_base」があります。したがって、私のコントローラーには次のようなものがあります。

class ApplicationController < ActionController::Base

  private

  def do_action(action=nil)
    action ||= caller[0][/`.*'/][1..-2]
    manager.send("manage_#{action}", self, cookies, request)
  end

  def manager
    base = self.class.name.split('::')
    base.pop
    base << "#{controller_name.camelize}Managers::ManagerBase"
    base.join('::').constantize
  end

end 

class Api::V1::FooController < ApplicationController

  def index
    do_action
    render_result
  end

end

そして、私も持っています:

class ManagerBase
  class << self

    def manage_index(controller, cookies, request)
      sub_out("Index", controller, cookies, request)             
    end

    def manage(controller, cookies, request)
      new(controller, cookies, request).manage
    end

  private

    def sub_out(method, controller, cookies, request)
      sub_manager(method).manage(controller, cookies, request)   
    end

  end # Class Methods

  def initialize(controller, cookies, request)
    @controller = controller
    @cookies = cookies
    @request = request
  end

end

class Api::V1::FooManagers::ManagerBase < ManagerBase
  class << self

    private

    def sub_manager(method)
      "Api::V1::FooManagers::#{method}Manager".constantize
    end  

  end # Class Methods
end

class Api::V1::FooManagers::IndexManager < Api::V1::FooManagers::ManagerBase
  def manage
    ... do stuff
  end
end

弾むボールをたどると、私のアプリケーション フローは次のようになります。

  • index呼び出されるApi::V1::FooController
  • indexdo_action( から継承) を呼び出し、さらに ( からも継承)ApplicationControllerを呼び出すmanagerApplicationController
  • managerApi::V1::FooManagers::ManagerBaseクラスを返します
  • do_actionそれから電話manage_indexするApi::V1::FooManagers::ManagerBase
  • manage_indexsub_out次に呼び出す呼び出しsub_manager
  • sub_managerを返しますApi::V1::FooManagers::IndexManager
  • sub_outそれから電話manageするApi::V1::FooManagers::IndexManager
  • manage(クラス メソッド - ManagerBase から継承) の新しいインスタンスを作成し、新しいインスタンスで(インスタンス メソッド) をApi::V1::FooManagers::IndexManager呼び出します。manage

明らかかもしれないし、そうでないかもしれませんが、私が Api::V2 に移行すると、マネージャーの Api::V1 バージョンに「フック」する機会が 2 つあります (これは、V1 コントローラー メソッドを使用するのと同じです - あなたの元の質問)。

まず、まだ実装していない場合は、最後に実装されたバージョンの(つまり)にフォールバックするApi::V2::FooManagers::ManagerBaseことができます。その場合、すべてのサブ マネージャー ( など) を使用します。ApplicationController.managerManagerBaseApi::V1::FooManagers::ManagerBaseApi::V1::FooManagerIndexManager

第 2 に、 を実装しApi::V2::FooManagers::ManagerBaseたがまだ実装していない場合、にフォールバックさApi::V2::FooManagers::IndexManagerせることができます。Api::V2::FooManagers#sub_managerApi::V1::FooManagers::IndexManager

わかりました、もうやめます。これを大声で考える機会をありがとう。まったく役に立たない、ホットな混乱である場合はお詫び申し上げます。

于 2016-08-09T23:08:40.010 に答える