A recent project required me to call some REST apis on a web server from my client application, which was written in C++. What I had to do was very simple, to I first started looking at the WinINet and WinHTTP API families. This quickly turned into me wanting to harm myself or someone else, so I decided to continue searching for a library to help out. I looked at cURLpp and it seemed okay, but then I stumbled across the C++ REST SDK code named Casablanca. Since I have been on a modern C++ kick lately and have been enjoying some of the new things Microsoft has added to the compilers (from the C++11/14 standards), I decided to give this Microsoft-created open-source SDK a look.
My first impressions are that the syntax is a bit complicated and the documentation is very near to non-existent. I was reduced to combing through the provided sample apps to try to figure out what I needed to do, but it wasn’t horribly difficult. A few hours had me on the way to some simple REST calls. My first task was to call one of my APIs with a PUT verb, providing a JSON document in the request body. The following example illustrates this. One interesting thing here is the .get() call that comes on a lot of the SDK objects. This function is what waits for the asynchronous web call to complete, and then returns the result from the call.
http_client cli( U("http://localhost:8080/myservlet") ); // PUT http://localhost:8080/myservlet/api/computerdata // ostringstream_t uri; uri << U("/api/computerdata"); value body = value::object(); body[U("id")] = value::string( U("COMPUTER") ); body[U("version")] = value::string( U("1.1.1.3") ); http_response response = cli.request( methods::PUT, uri.str(), body.serialize(), U("application/json") ).get(); if ( response.status_code() == status_codes::OK && response.headers().content_type() == U("application/json") ) { value json_response = response.extract_json().get(); ucout << json_response.serialize() << endl; } else { ucout << response.to_string() << endl; } }
The get call is even more simple, since it doesn't require creating a JSON request body...
http_client cli( U("http://localhost:8080/myservlet") ); // GET http://localhost:8080/myservlet/api/computerdata/COMPUTER // ostringstream_t uri; uri << U("/api/computerdata/COMPUTER"); http_response response = cli.request( methods::GET, uri.str() ).get(); if ( response.status_code() == status_codes::OK && response.headers().content_type() == U("application/json") ) { value json_response = response.extract_json().get(); ucout << json_response.serialize() << endl; } else { ucout << response.to_string() << endl; } }
These examples are incredibly simple, but illustrate some of the most basic uses of this SDK. The SDK includes a lot more powerful and complex operations, such as PPL tasks, which is a model for creating asynchronous operations that is based on C++11 stuff. The SDK can be easily included in your package from Visual Studio by using the NuGet package manager to include Casablanca in your project. It will set up all the include paths, etc. for you. The code, samples, and what documentation there is can be found at casablanca.codeplex.com.