Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/api/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails Rails API版本控制-调用控制器操作(如果存在)?_Ruby On Rails_Api_Api Versioning - Fatal编程技术网

Ruby on rails Rails API版本控制-调用控制器操作(如果存在)?

Ruby on rails Rails API版本控制-调用控制器操作(如果存在)?,ruby-on-rails,api,api-versioning,Ruby On Rails,Api,Api Versioning,现在我有两个API名称空间,API::V1和API::V2 我计划随着时间的推移慢慢地实现V2,而不是一次性实现。但是,由于它的一部分已经存在,我希望客户端能够将所有HTTP请求发送到V2 URL,并在特定端点尚未实现的情况下让服务器处理它 如果V2控制器没有操作,是否有方法将V2请求路由到V1控制器 简单的例子: 路线: namespace :api do namespace :v1 do resources :items, only: [:index] end

现在我有两个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/v1/items
  • POST/api/v2/项目

  • 目标是向/api/v2/items发送一个GET请求,并让它调用api::V1:ItemsController#index,因为v2控制器还没有这个方法。

    我还有一个版本化的api。我还没有跳到下一个版本。但我想我会分享我的计划。这可能有点夸张。我有一种感觉,这对我(思考我的计划)比对你更有用。所以,很抱歉。但是,现在

    在开始之前,我应该说我对控制器的操作采取了不同的方法。在我的应用程序中,我喜欢将我的控制器操作委托给我称之为“管理器”的普通ruby对象。每个控制器都有一个“管理器库”。因此,在我的控制器中,我有如下内容:

    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 ApplicationController如果您在这里运行rake路由,您将看到它们都与路由“api/v2/__#u________________;”匹配,但是顶部块中的调用api::V1操作和底部块调用api::v2操作,因此在实现这些端点时,您必须将它们从顶部移动到底部!那是一个该死的计划!事实证明,在给api模块命名时,我可以通过使用:path选项来解决我的问题,现在我只需要将控制器操作从v1移动到v2,因为它们已经完成了。谢谢。我想是吧。我希望这不会给我带来麻烦。如何以及在何处使用:path选项?评论太多了,我把它作为一个答案发布了出来看看
    
    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
    
    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