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: