【问题标题】:How can i return compressed json data in rails controller itself?如何在 Rails 控制器本身中返回压缩的 json 数据?
【发布时间】:2020-05-14 18:55:57
【问题描述】:

我有一个返回大量数据的 api,所以我想压缩这些数据并返回给客户端。 我知道NginxRack::deflater in application.rb 有一些方法。但我只想为这个特定的 api 响应压缩这些数据。(不想在 ngnix 中这样做)

我尝试过这个答案中提到的:https://stackoverflow.com/a/35758106/5925134。 我能够压缩但无法用压缩数据响应客户端。我试过这个,想以某种方式 response_to gz 作为响应类型。

Zlib::GzipWriter.open('public/huge_data.gz') { |gz| gz.write data.to_json }
    respond_to do |format|
      format.gz { render gz: {File.read('public/huge_data.gz') } }
    end

有没有办法将此压缩数据传递给客户端或任何其他方法?提前致谢

【问题讨论】:

  • 这似乎是一个愚蠢的差事。只需在 NGiNX 或 Rack 中设置它,然后客户端可以根据请求标头自动获取(或不)压缩响应。为应用程序的其余部分提供压缩响应并没有什么害处,所以我不明白为什么你会通过做一些属于应用程序的 Web 服务器层的事情来将事情变成 PITA。
  • 您也完全没有掌握 HTTP 中的 gz 压缩是如何工作的。 Gzip 编码由 Content-Encoding 标头设置,而不是通过请求 gz Content-Type。客户端实际上可以请求任何 Content-Type 并将其压缩,这一切都是透明地发生的,这就是重点。 tools.ietf.org/html/rfc2616#section-3.5
  • 我同意我可以在 Nginx 或 Rack 中完成,压缩和解压缩数据有其自身的成本。如果压缩、解压缩和数据传输的总时间少于仅数据传输而不压缩的时间怎么办?有很多 API 的响应很小,我们不需要压缩。
  • 我同意我可以在 nginx 中做到这一点,正如问题本身已经提到的那样
  • 如果你使用的是 catch,那么响应只会被压缩一次。这也是过早优化的一个大例子。

标签: ruby-on-rails rest api client


【解决方案1】:

我不推荐这样做,但如果你真的想手动压缩 JSON 响应,你会这样做:

class CompressedController < ApplicationController
  def test
    respond_to do |f|
      f.json do
        file = Tempfile.new
        json = JSON.generate(hello: 'World')
        Zlib::GzipWriter.open(file.path) { |gz| gz.write json }
        response.set_header('Content-Encoding', 'gzip')
        send_data file.read, type: :json, disposition: 'inline'
      end
    end
  end
end

这只是一个独立的最小示例。根据您的实际用例进行调整。

如果您真的想以合理的方式解决性能问题,请在 Web 服务器层上使用压缩以及 caching

【讨论】:

  • 感谢您的回答。我不是要实现它,而是想知道是否有办法。
猜你喜欢
  • 1970-01-01
  • 2014-03-10
  • 2019-04-13
  • 2011-01-20
  • 2019-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多