ruby-on-rails - Web 应用程序中的 API 版本控制

标签 ruby-on-rails ruby api architecture application-design

我目前正在为一个新网站设计版本化的 API。我了解如何为路由命名空间,但我一直坚持在模型中实现版本化方法的最佳方式。

下面的代码示例使用的是rails框架,但是事情的原理在大多数web框架之间应该是一致的。

目前的路线看起来像这样:

MyApp::Application.routes.draw do
  namespace :api do
    namespace :v1 do
      resources :products, :only => [:index, :show]
    end
  end
end

和 Controller :

class Api::V1::ProductsController < V1Controller
  respond_to :json, :xml

  def index
    respond_with @products = Product.scoped
  end

  def show
    respond_with @product = Product.find(params[:id])
  end
end

很明显,我们只是在此处公开 Product 上可用的属性,如果您只打算拥有一个版本的 API,则此解决方案非常有效。当您想要发布 V2 并且 V2 需要重新实现产品名称的显示方式(同时保持与 V1 的向后兼容性 - 至少在短期内)时会发生什么?

据我所知,您有几个选择...

  1. 立即放弃对 V1 的支持并处理后果(最糟糕的解决方案)
  2. 您开始覆盖 to_[format] 方法(我很确定您使用 as_[format] 这样做,但那不是重点)以包含一个新属性... name_2 - 这似乎同样愚蠢
  3. 实现某种代理类,负责只公开我们需要的方法
  4. 让 View 处理创建版本化 Controller 的某种散列,并在...上调用to[format]

三和四是我唯一认为有意义的……三看起来像:

# model
class Api::V1::Product < Struct.new(:product)
  def to_json
    attributes.to_json
  end

  def to_xml
    attributes.to_xml
  end

private
  def attributes
    {:name => product.name} # add all the attributes you want to expose
  end
end

# Controller
class Api::V1::ProductsController < V1Controller
  respond_to :json, :xml

  def show
    respond_with @product = Api::V1::Product.new(Product.find(params[:id]))
  end
end

其他人过去做过什么?

最佳答案

您可以为每个版本部署一个应用,而不是一个应用服务于 V1、V2 和 V...。一个应用将回答 api.domain.com/v1,然后另一个应用将回答 api.domain.com/v2,依此类推。

这就是面向服务的应用程序的最佳组织方式,每个服务都应该隔离,独立部署。

从单个应用程序提供所有版本违背了面向服务设计的目的,因为每次您对一项服务进行更改时,您都需要针对所有版本进行测试和部署。

关于ruby-on-rails - Web 应用程序中的 API 版本控制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6797468/

相关文章:

ruby-on-rails - Ruby map/collect 在大型 Mongoid 集合上运行缓慢

css - rails/Heroku : custom fonts working in local but not on Heroku

mysql - PG::InvalidColumnReference:按关联表排序时出现错误

ruby - Jekyll 服务错误:找不到 gem jekyll (>= 0.a) (Gem::GemNotFoundException

ios - 如何在通话期间在 iPhone 上显示信息屏幕

ruby-on-rails - Bundler::GemNotFound:在任何源中都找不到 rake-10.3.2

Ruby 文件完整路径

ruby-on-rails - 从散列中的 ruby​​ 字符串编写 javascript 函数

java - 如何使用 json 对象从上下文位于 mainactivity 的对话框的 editText 发送数据?

api - slice ,groupBy []数组