轨道3响应格式,并在接受头使用供应商的MIME类型版本 [英] rails 3 response format and versioning using vendor MIME type in the Accept header

查看:171
本文介绍了轨道3响应格式,并在接受头使用供应商的MIME类型版本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆