Search code examples
rubyfaraday

Is there a way to serialize and deserialize a Faraday::Response without loosing any information?


I am trying to serialize a Faraday::Response instance without losing any information. I found the marshal_dump and marshal_load methods but they don't seem to keep the response.env.request details.

response = Faraday.get('https://google.com')
response.env.request_headers
#=> {"User-Agent"=>"Faraday v2.7.4"}

response2 = Faraday::Response.new
response2.marshal_load(response.marshal_dump)
response2.env.request_headers
#=> nil

response3 = Marshal.load(Marshal.dump(response))
response3.env.request_headers
#=> nil

How can I serialize everything so that upon deserializing, both objects contain the exact same data?


Solution

  • without losing any information

    In general this is not really possible. For instance the request has @on_complete_callbacks which are procs, and those can't be marshalled. On top - an object can reference other objects, and in some cases (e.g. anonymous classes) those also can't be marshalled.

    Faraday's marshal_dump is just this

    def marshal_dump
      finished? ? to_hash : nil
    end
    

    (source: https://www.rubydoc.info/github/lostisland/faraday/Faraday/Response#marshal_dump-instance_method)

    and to_hash is:

    def to_hash
      {
        status: env.status, body: env.body,
        response_headers: env.response_headers,
        url: env.url
      }
    end
    

    (source: https://www.rubydoc.info/github/lostisland/faraday/Faraday/Response#to_hash-instance_method)

    so, as you can see - the developers of Faraday made a decision that everything else it not that important.

    So, the shortcut "just serialize in a way that after deserialization it's exactly the same" is not possible, so you either need to:

    • implement your own object (e.g. wrapper) in which you can implement your own serialization, but you'll have to decide which data is important
    • or, reformulate your original problem you're trying to solve and try to look for other possible solutions (you're not sharing why you need that, so it's hard to help you with that).