gpt4 book ai didi

ruby-on-rails - 如何使用 Ruby on Rails 为 REST API 生成自定义响应?

转载 作者:行者123 更新时间:2023-12-04 06:29:25 26 4
gpt4 key购买 nike

我正在 Rails 3 中实现 REST API。我们允许使用 JSON 和 XML 作为响应格式。

默认respond_with只要只需要返回请求的资源,就可以正常工作,例如:

def show
respond_with User.find(params[:id])
end

GET /users/30.xml

<?xml version="1.0" encoding="UTF-8"?>
<user>
<birthday type="date">2010-01-01</birthday>
<company-name>Company</company-name>
<email>email@test.com</email>
<id type="integer">30</id>
</user>

但是,我想得到以下标准化响应:
<?xml version="1.0" encoding="UTF-8"?>
<response>
<status>
<success type="boolean">true</success>
</status>
<result>
<user>
<birthday type="date">2010-01-01</birthday>
<company-name>Company</company-name>
<email>email@test.com</email>
<id type="integer">30</id>
</user>
</result>
</response>

我怎样才能达到这个结果?

我尝试了以下操作,使用自定义 Response 类
class Response

STATUS_CODES = {
:success => 0,
}

extend ActiveModel::Naming
include ActiveModel::Serializers::Xml
include ActiveModel::Serializers::JSON

attr_accessor :status
attr_accessor :result

def initialize(result = nil, status_code = :success)
@status = {
:success => (status_code == :success),
}
@result = result
end

def attributes
@attributes ||= { 'status' => nil, 'result' => nil }
end

end

并重新定义 respond_with我的方法 ApplicationController :
  def respond_with_with_api_responder(*resources, &block)
respond_with_without_api_responder(Response.new(resources), &block)
end

alias_method_chain :respond_with, :api_responder

但是,这不会产生预期的结果:
<?xml version="1.0" encoding="UTF-8"?>
<response>
<status>
<success type="boolean">true</success>
</status>
<result type="array">
<result>
<birthday type="date">2010-01-01</birthday>
<company-name>Company</company-name>
<email>email@test.com</email>
<id type="integer">30</id>
</result>
</result>
</response>

应该是什么 <user>现在又来了 <result> .当我返回一个数组作为结果时,情况变得更糟,然后我得到另一个 <result>层。如果我查看 JSON 响应,它看起来几乎没问题——但请注意,有一个数组 [] 过多地包装了用户资源。
GET /users/30.json

{"response":{"result":[{"user":{"birthday":"2010-01-01","company_name":"Company","email":"email@test.com"}}],"status":{"success":true}}}

知道这里发生了什么吗?如何获得所需的响应格式?我也尝试过写一个自定义 Responder类,但归结为重写 display内的方法 ActionController:Responder ,给了我完全相同的问题:
  def display(resource, given_options={})
controller.render given_options.merge!(options).merge!(format => Response.new(resource))
end

我相信问题不知何故隐藏在 ActiveModel 的序列化代码中,但我似乎无法弄清楚如何将资源包装在容器标签中并仍然实现正确序列化包装的资源。

有什么想法或想法吗?

最佳答案

这是我最后所做的:

  • 我摆脱了 Response 类。
  • 我向所有模型添加了 to_json 和 to_xml 方法:
    [:to_json, :to_xml].each do |method_name|
    define_method(method_name) do |options = {}|
    options ||= {}
    options[:only] ||= # some filtering
    super(options)
    end
    end
  • 我在 ApplicationController 中重新定义了 respond_with 方法:
    def api_respond_with(resources, &block)
    default_respond_with do |format|
    format.json { render :json => resources, :skip_types => true, :status => :ok }
    format.xml { render :xml => resources, :skip_types => true, :status => :ok }
    end
    end

    alias_method :default_respond_with, :respond_with
    alias_method :respond_with, :api_respond_with
  • 我用适当的方法编写了一个自定义中间件来添加所需的包装:
    class StandardizedResponseFilter

    def _call(env)
    status, headers, response = @app.call(env)
    if headers['Content-Type'].include? 'application/json'
    response.body = standardized_json_wrapping(response.body, env)
    elsif headers['Content-Type'].include? 'application/xml'
    response.body = standardized_xml_wrapping(response.body, env)
    end
    [status, headers, response]
    end

    end

  • 如果有人知道更好的方法,请随时发表评论。

    关于ruby-on-rails - 如何使用 Ruby on Rails 为 REST API 生成自定义响应?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5624077/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com