现在我有两个API命名空间,Api :: V1和Api :: V2
我计划随着时间的推移慢慢实施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
将产生以下端点:
目标是向/ api / v2 / items发送一个GET请求并让它调用Api :: V1:ItemsController #index,因为V2控制器还没有这个方法。
答案 0 :(得分: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操作,因此在实施这些端点时,您必须将它们从顶部移动到底部
答案 1 :(得分: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
index
调用do_action
(继承自ApplicationController
),后者又调用manager
(也继承自ApplicationController
)manager
返回Api::V1::FooManagers::ManagerBase
类do_action
然后在manage_index
Api::V1::FooManagers::ManagerBase
manage_index
拨打sub_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时,我有两个机会来勾选&#39;回到我的经理的Api :: V1版本(这相当于使用我的V1控制器方法 - 你原来的问题)。
首先,如果我尚未实施Api::V2::FooManagers::ManagerBase
,我可以让ApplicationController.manager
回到ManagerBase
的最后一个实施版本(即Api::V1::FooManagers::ManagerBase
)。在这种情况下,我将使用所有Api::V1::FooManager
子管理员(例如IndexManager
)。
其次,如果我已实施Api::V2::FooManagers::ManagerBase
但尚未实施Api::V2::FooManagers::IndexManager
,那么我可以让Api::V2::FooManagers#sub_manager
回退到Api::V1::FooManagers::IndexManager
。
好的,我现在要停下来。感谢您有机会大声思考。道歉,如果它是一个完全无用的,热的混乱。