我可以减少 ruby 哈希序列化中的重复吗?

Can I reduce duplication in the serialization of a ruby hash?

我有一个哈希格式

{com: 1234, users: [{nid: 3, sets: [1,2,3,4]}, {nid: 4, sets: [5,6,7,8]}]}

我正在发送到远程服务器。我正在使用 HTTParty gem 来执行此操作。代码如下所示

class Api
    include HTTParty
    attr_accessor :headers

    def initialize
      @headers = { 'Content-Type' => 'application/json' }
    end
    
    def post_com(hsh)
      response = self.class.post('some_url', query: hsh, headers: headers, format: :plain)
    end
end

当我做的时候

api = Api.new.post_com({com: 1234, users: [{nid: 3, sets: [1,2,3,4]}, {nid: 4, sets: [5,6,7,8]}]}

在远程服务器上,正在以下列格式发送散列

POST "/some_url?com=1234&users[][nid]=3&users[][sets][]=1&users[][sets][]=2&users[][sets][]=3&users[][sets][]=4&users[][nid]=4&users[][sets][]=5&users[][sets][]=6&users[][sets][]=7&users[][sets][]=8

这意味着对于集合中的每个条目,都会发送重复的字符 users[][sets][]。在操作中,集合中可以有很多条目,结果是服务器拒绝 post 字符太多。

无论如何我可以将散列序列化以减少重复。例如,如果我只是做

{com: 1234, users: [{nid: 3, sets: [1,2,3,4]}, {nid: 4, sets: [5,6,7,8]}]}.to_json

我收到

"{\"com\":1234,\"users\":[{\"nid\":3,\"sets\":[1,2,3,4]},{\"nid\":4,\"sets\":[5,6,7,8]}]}"

字符少得多。

HTTPParty,默认情况下,将 :query 哈希转换为它所谓的 'rails style query parameters':

For a query:
get '/', query: {selected_ids: [1,2,3]}

The default query string looks like this:
/?selected_ids[]=1&selected_ids[]=2&selected_ids[]=3

由于您正在执行 POST,因此 possible/preferable 在请求正文中而不是在查询字符串中发送您的哈希值。

def post_com(hsh)
  self.class.post('some_url', body: hsh.to_json, headers: headers, format: :plain)
end

这样做的好处是它不会对有效负载进行任何转换,而且查询字符串长度限制也不适用。

郑重声明,您可以像这样禁用默认 'rails style' 编码:

class Api
  include HTTParty
  disable_rails_query_string_format

  ...
end

您还可以通过将 Proc 传递给 query_string_normalizer 来滚动您自己的自定义查询字符串规范化器。