使HTTParty返回对象/类而不是JSON响应的最简单方法是什么?

时间:2016-01-21 05:30:39

标签: ruby-on-rails ruby ruby-on-rails-4 httparty

现在我打电话给:

def child(parent_id, child_id, params = {})
  if @api_token
    self.class.get("/parents/#{parent_id}/children/#{child_id}", query: params,
                      :headers=>{"Authorization"=>"Token token=#{@api_token}"})
  else
    self.class.get("/parents/#{parent_id}/children/#{child_id}", query: params)
  end
end

它直接从API返回JSON响应作为哈希。我是否有一种简单的方法来标准化响应,以便它解析JSON并生成一个类?

示例:

Original Response
--------
{'child' : { 'name' : 'John Doe', 'age' : 23 } }

Desired Response
--------
res.name # John Doe
res.age  # 23
res.class # APIClient::Child

2 个答案:

答案 0 :(得分:1)

可以通过传递给请求调用的自定义解析器来实现(但是我强烈建议不要这样做并保持现状)

您可以传递的解析器示例是

class InstanceParser < HTTParty::Parser
  def parse
    #assuming you always have a json in format { 'one_key_mapping_to_model' => data }        
    body_as_json = JSON.parse(body) #string parsed to json        

    model_class_name = body_as_json.keys.first # == 'one_key_mapping'       
    model_class_data = body_as_json[model_class_name] # == data
    class_instance = model_class_name.camelize.constantize.new(model_class_data) # will create new instance of OneKeyMapping

    class_instance
  end
end

然后在你的api通话中self.class.get("/parents/#{parent_id}/children/#{child_id}", query: params, parser: InstanceParser)

答案 1 :(得分:1)

将哈希传递给初始化程序。

class APIClient::Child
  attr_accessor :foo, :bar

  def initialize(hash = {})
    hash.each do |k,v|
      public_send("#{k}=", v)
    end
  end
end

然后在您的API客户端中,您将在响应和对象之间进行映射:

def child(parent_id, child_id, params = {})
  opts = { query: params }
  opts.merge!(:headers=>{"Authorization"=>"Token token=#{@api_token}"}) if @api_token
   begin 
    res = self.class.get("/parents/#{parent_id}/children/#{child_id}", opts)
    case response.code
      when 200
        APIClient::Child.new(res[:child])
      when 404
        # not found - raise some sort of error that the API client consumer 
        # can catch maybe?
      else
        # probably just log it since there is little we can do here.
    end      
   rescue HTTParty::Error
     # probaly just log it. Could be a connection error or something else.
   end
end

这可能不如您所希望的那么神奇,但如果不在HTTP请求和适合消费的对象之间进行映射,API客户端的作用是什么。在传递令牌和处理错误时,大多数的boooring样板代码都可以用于父类或模块。