轨道3响应格式,并在接受头使用供应商的MIME类型版本 [英] rails 3 response format and versioning using vendor MIME type in the Accept header
问题描述
preamble:
我研究了如何版本的API,并发现了几个方法来做到这一点。我决定尝试彼得·威廉姆斯'建议,并创造了新的供应商MIME类型,指定版本和格式。我能找到没有明确写了这样做下面的导轨方式,所以我从几个地方拼凑起来的信息。我能得到它的工作,但有一些goofiness的方式渲染处理控件数组VS控件实例 respond_with
。
I investigated how to version an API and found several ways to do it. I decided to try peter williams' suggestion and created new vendor mime types to specify version and format. I could find no definitive write-up for doing this following "the rails way" so I pieced together info from several places. I was able to get it working, but there is some goofiness in the way the renderers handle Widget array vs Widget instance in respond_with
.
的基本步骤和放大器;问题:
我注册的MIME类型,并添加渲染器版本1的XML和JSON到ApplicationController中,渲染调用 to_myproj_v1_xml
和 to_myproj_v1_json
方法。 respond_with(@widget)
工作正常,但 respond_with(@widgets)
引发 HTTP / 1.1 500内部服务器错误
说,模板丢失。
I registered mime types and added renderers for version 1 in both xml and json to ApplicationController, the renderers call to_myproj_v1_xml
and to_myproj_v1_json
methods in the model. respond_with(@widget)
works fine but respond_with(@widgets)
throws an HTTP/1.1 500 Internal Server Error
saying that the "Template is missing".
解决方法:
模板丢失意味着没有渲染被称为无匹配的模板存在。偶然,我发现,它正在寻找一个类的方法,所以,我想出了code,低于该作品,但我不能与它真的很高兴。该goofiness大多在和相关 XML = obj.to_myproj_v1_xml(OBJ)
,并在模型中的重复。
"Template is missing" means that no render was called and no matching template exists. by accident, I discovered that it is looking for a class method... so I came up with the code below which works but I'm not really happy with it. The goofiness is mostly in and related to xml = obj.to_myproj_v1_xml(obj)
and the duplication in the model.
我的问题是 - 有没有人做过一个稍微干净的方式类似的事情
My question is - has anyone done anything similar in a slightly cleaner fashion?
- =更新code = -
配置/初始化/ mime_types.rb
Mime::Type.register 'application/vnd.com.mydomain.myproj-v1+xml', :myproj_v1_xml
Mime::Type.register 'application/vnd.com.mydomain.myproj-v1+json', :myproj_v1_json
应用/控制器/ application_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery
before_filter :authenticate
ActionController.add_renderer :myproj_v1_xml do |obj, options|
xml = obj.to_myproj_v1_xml
self.content_type ||= Mime::Type.lookup('application/vnd.com.mydomain.myproj-v1+xml')
self.response_body = xml
end
ActionController.add_renderer :myproj_v1_json do |obj, options|
json = obj.to_myproj_v1_json
self.content_type ||= Mime::Type.lookup('application/vnd.com.mydomain.myproj-v1+json')
self.response_body = json
end
end
应用/型号/ widget.rb
class Widget < ActiveRecord::Base
belongs_to :user
V1_FIELDS = [:version, :model, :description, :name, :id]
def to_myproj_v1_xml
self.to_xml(:only => V1_FIELDS)
end
def to_myproj_v1_json
self.to_json(:only => V1_FIELDS)
end
def as_myproj_v1_json
self.as_json(:only => V1_FIELDS)
end
end
应用/控制器/ widgets_controller.rb
class WidgetsController < ApplicationController
respond_to :myproj_v1_xml, :myproj_v1_json
def index
@widgets = @user.widgets
respond_with(@widgets)
end
def create
@widget = @user.widgets.create(params[:widget])
respond_with(@widget)
end
def destroy
@widget = @user.widgets.find(params[:id])
respond_with(@widget.destroy)
end
def show
respond_with(@widget = @user.widgets.find(params[:id]))
end
...
end
配置/初始化/ monkey_array.rb
class Array
def to_myproj_v1_json(options = {})
a = []
self.each { |obj| a.push obj.as_myproj_v1_json }
a.to_json()
end
def to_myproj_v1_xml(options = {})
a = []
self.each { |obj| a.push obj.as_myproj_v1_json } # yes this is json instead of xml. as_json returns a hash
a.to_xml()
end
end
更新:
找到了另一个解决方案,感觉好些,但仍然有点怪异(我还没有与猴子补丁完全舒适),可能是好的,但...基本构建移动从类方法 to_myproj_v1_json响应数据
来对阵列猴子补丁。这样,当有小工具的数组,它调用实例方法 as_myproj_v1_json
每个插件,并返回整个数组所需的格式。
Found another solution that feels better but still a little weird (I'm still not completely comfortable with monkey patches), probably ok though... basically moved building the response data from the class method to_myproj_v1_json
to a monkey patch on Array. This way when there is an Array of Widgets, it calls the instance method as_myproj_v1_json
on each Widget and returns the whole Array as desired format.
一个说明:
- as_json无关使用JSON格式,只需创建一个哈希值。加入(如果你不使用自定义MIME类型或as_json覆盖),然后将to_json哈希更改为JSON字符串自定义格式as_myproj_v1_json。
我已经更新下面的code是当前使用的,所以原来的问题可能没有意义。如果有人想显示为原来的问题和code是在回应固定的code我能做到这一点吧。
i have updated the code below to be what is currently used, so the original question may not make sense. if anyone wants the original question and code shown as was and fixed code in a response i can do that instead.
推荐答案
有关的答案:看这个问题: - )
For the answer: see the question :-)
在总之,有不同的解决方案,其中之一是在上面的问题:
In short, there are different solutions, of which one is in the question above:
- 猴子补丁阵列来实现,这将使(旧)V1 JSON回来的方法
这篇关于轨道3响应格式,并在接受头使用供应商的MIME类型版本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!