Exctract body and JSON from same response

Jan 20, 2015 at 8:25 AM
Hi,

I have a problem that I would like some help to figure out.

I have a http_response that will include JSON that I will perform two different actions on. The first is to just take the JSON / body unmodified (VERY important) and resend it encapsulated, and the second is to extract the JSON fields into a C++ object of the same response.

My first idea was to use extract_json() and serialize the json::value to get the body that I will resend but quickly found out that will mess up the order of the JSON-fields. I therefore used an istream of the body and read it to a string that I resend encapsulated (works) and then used the extract_json() method. This however will invoke several exceptions because I am only allowed to extract the body once due to optimizations.

I really need to find a solution for this. Changing REST Api is not a solution at this point, and I really find the Casablanca library to be the best C++ REST Api out there.

Thanks for any help!
Jan 20, 2015 at 5:48 PM
Hi Pettor,

There are two solutions that quickly come to mind. One we have the ability to turn on our JSON library to guarantee ordering of name value pairs in objects, web::json::keep_object_element_order(...). However please be aware this is a global switch and will affect all JSON objects in your process. With this you could follow the approach you mention with calling extract_json().

Another option without changing the global ordering setting is to get the body of the response as a string using http_response::extract_string(true). Then you can resend the string, and construct a json::value from the string using json::value::parse(...). The reason you are seeing an exception when trying to call extract_json() after having read from the underlying stream is because the reading from the stream and the extract_* functions are destructive. When possible they make optimizations to avoid copying the response body.

Steve
Jan 22, 2015 at 7:21 AM
Thank you Stevetgates!

The second solution is actually perfect. Now I can send the body and whenever I please parse the JSON.

Btw, using string_t as a replacement to std::string isn't going to cause any problems? I really think the convertion-tools, UTF8-features and cross-platform capabilites of string_t is useful!
Jan 22, 2015 at 5:49 PM
Hi Pettor,

The utility::string_t type is dependent on the platform. On Windows it is a std::wstring containing UTF-16. On Linux a std::string containing UTF-8. If you want it to be of a certain type you can convert to the desired type, using any of the library's string utility functions. Take a look in the utility::conversions namespace.

Steve