HTTParty - JSON to strongly typed object
Question
Is it possible to have HTTParty deserialize the results from a GET to a strongly typed ruby object? For example
class Myclass
include HTTParty
end
x = Myclass.get('http://api.stackoverflow.com/1.0/questions?tags=HTTParty')
puts x.total
puts x.questions[0].title
Right now it deserializes it into a hash
puts x["total"]
My question is actually if HTTParty supports this OTB, not by installing additional gems.
Edit:
I'm still new to Ruby, but I recall that class fields are all private so they would need to be accessed through getter/setter methods. So maybe this question isn't a valid one?
Solution
It sounds like you want the return value of Myclass::get
to be an instance of Myclass
. If that's the case, you could cache the return value from the HTTP request and implement method_missing
to return values from that hash:
class Myclass
include HTTParty
attr_accessor :retrieved_values
def method_missing(method, *args, &block)
if retrieved_values.key?(method)
retrieved_values[method]
else
super
end
end
def self.get_with_massaging(url)
new.tap do |instance|
instance.retrieved_values = get_without_massaging(url)
end
end
class << self
alias_method :get_without_massaging, :get
alias_method :get, :get_with_massaging
end
end
This isn't exactly what you asked for, because it only works one level deep — i.e., x.questions[0].title
would need to be x.questions[0][:title]
x = Myclass.get('http://api.stackoverflow.com/1.0/questions?tags=HTTParty')
p x.total
p x.questions[0][:title]
Perhaps you could come up with some hybrid of this answer and Joshua Creek's to take advantage of OpenStruct.
I should also point out that all the method aliasing trickery isn't necessary if your method doesn't have to be named get
.
OTHER TIPS
If you are just wanting method syntax, you can use an open struct.
require 'httparty'
require 'ostruct'
result = HTTParty.get 'http://api.stackoverflow.com/1.0/questions?tags=HTTParty'
object = OpenStruct.new result
object.total # => 2634237
A possible downside is that this object is totally open such that if you invoke a nonexistent method on it, it will just return nil (if you invoke a setter, it will create both the setter and getter)