TL; DR:制作API。需要针对不同版本的不同字段。教导我,聪明的人。
我目前正在尝试找出制作版本化API的最佳方法。也就是说,我希望有一个/api/v1/projects.json
的URL,它将显示包含大量字段的项目列表,并api/v2/projects.json
显示包含单独字段的项目列表。
我一直在考虑这个问题大约15分钟,这可能意味着一切都错了。目前我已经在app/models/project.rb
文件中找到了这个:
def self.api_fields
{
:v1 => ["name"],
:v2 => ["name", "tickets_count"]
}
end
然后我可以在我的API控制器(api/v1/projects_controller.rb
)中使用它,如下所示:
def index
respond_with(Project.all(:select => Project.api_fields[:v1]))
end
这很棒,按照我的意愿行事,但可能有更好的方法。那是你的任务!与我分享您的API制作智慧之山。
如果您想出一个解决方案,也可以让我使用方法来处理模型对象的实例,例如tickets_count
方法上的Project
方法,那么
奖励积分。
答案 0 :(得分:1)
正如评论:
你有看过这些吗?
http://devoh.com/posts/2010/04/simple-api-versioning-in-rails
Best practices for API versioning?
devoh.com建议在路由级别拆分版本,这似乎是一个好主意:
map.namespace(:v1) do |v1|
v1.resources :categories
v1.resources :products
end
map.namespace(:v2) do |v2|
v2.resources :categories, :has_many => :products
end
然后你可以使用不同的控制器来返回不同的字段。
答案 1 :(得分:1)
我同意polarblau
您应该为不同版本的API提供多个控制器。所以,我的目标是这个问题的奖励点。
我认为要归档调用#tickets_count
的功能,您必须覆盖模型的#as_json
和#to_xml
方法。我想你必须这样做:
<强> API / V1 / projects_controller.rb 强>
def index
respond_with Project.all, :api_version => :v1
end
<强> project.rb 强>
class Project < ActiveRecord::Base
API_FIELDS = {
:v1 => { :only => [:name] },
:v2 => { :only => [:name], :methods => [:tickets_count] }
}
def as_json(options = {})
options.merge! API_FIELDS[options[:api_version]]
super
end
def to_xml(options = {}, &block)
options.merge! API_FIELDS[options[:api_version]]
super
end
end
但是,如果你不介意控制器中的混乱,我认为在控制器的:only
调用中指定:methods
和respond_with
也可能是一个好主意,因为你不必覆盖那些#as_json
和#to_xml
方法。
答案 2 :(得分:0)
问题是,如您所知,无论您公开什么,都允许最终客户端创建直接依赖关系。话虽如此,如果您将模型直接暴露给世界,例如http://domain.com/products.json,无论何时更改产品型号,您都可以选择有限的选项:
如果我们希望采用第二种方法,我们可以做到以下几点:
class Project < ActiveRecord::Base
end
class PublicProject
def to_json(version = API_VERSION)
self.send("load_#{version}_project").to_json
end
private
def load_v1_project
project = load_v2_project
# logic that transforms a current project in a project that v1 users can understand
end
def load_v2_project
Project.find...
end
end
希望它有所帮助。
答案 3 :(得分:0)
在/ api / v1的路由中安装Sinatra应用程序以处理您的API调用。使您更容易添加新API,并且在您弃用它之前仍然可以向后兼容。