The C++ REST SDK ("Casablanca")

The C++ REST SDK ("Casablanca")

Rate This
  • Comments 20

The C++ REST SDK (codename "Casablanca") has officially been released as an open source project on CodePlex (http://casablanca.codeplex.com).

We first announced Casablanca as an incubation project on Microsoft's DevLabs back in April of 2012. Since then we have had several releases and have seen library quickly evolve. As we added new features and received feedback from customers, it was evident that two separate entities were beginning to form. As a result, the "Casablanca" project on DevLabs has been separated into 2 different SDKs: the C++ REST SDK and the Azure SDK for C++.

 The first of the two SDKs being released is the C++ REST SDK. It includes tools to quickly write modern, asynchronous C++ code that connects with REST services. We take advantage of the power and productivity offered in C++11 while providing a cross-platform solution. We currently support Windows 7, Windows 8 (Windows store and desktop applications), and Linux.

 The main features in this SDK include:

  • Ability to create a connection to a server via a HTTP Client, send requests and handle response.
  • Support for construction and use of Uniform Resource Identifiers (URI).
  • Constructing, parsing and serializing JSON values.
  • Asynchronously reading/writing bytes to/from an underlying medium via Streams and Stream Buffers.

Let's look at some code to get a glimpse of the aforementioned features in action.

This first example is a simple application that uploads a file to an HTTP Server. 

#include <http_client.h>
#include<filestream.h>
#include <uri.h>

using namespace concurrency::streams;
using namespace web::http::client;
using namespace web::http;

int main()
{
  // Open stream to file.
  file_stream<unsigned char>::open_istream(L"myfile.txt").then([](basic_istream<unsigned char> fileStream)
  {
    // Make HTTP request with the file stream as the body.
    http_client client(L"http://www.myhttpserver.com");
    client.request(methods::PUT, L
"myfile", fileStream).then([fileStream](http_response response)
    {
      fileStream.close();
      // Perform actions here to inspect the HTTP response...
      if(response.status_code() == status_codes::OK)
      {
      }
    });
  });

  return 0;
}

We use the concurrency::streams::file_stream class to asynchronously read a file from disk. The constructor of the file stream returns a PPL task of a basic_istream.

Within the continuation we create an instance of http_client to represent the connection to the server. Using this instance we can now send requests. In this example we use the web::http::methods::PUT to specify the operation as an HTTP PUT request. We also include the name of the file and the file stream in our request. Finally, we capture the http_response in a continuation and perform the necessary actions to inspect if the request was successfully processed by the server.

This example illustrates how straight-forward writing a responsive client application that connects to a service can be.

Next we will demonstrate how to build a JSON value in memory and loop through its values.

#include <json.h>

int main()
{
  // Create a JSON object.
  json::value obj;
  obj[L
"key1"] = json::value::boolean(false);
  obj[L
"key2"] = json::value::number(44);
  obj[L
"key3"] = json::value::number(43.6);
  obj[L
"key4"] = json::value::string(U("str"));

  // Loop over each element in the object.
  for(auto iter = obj.cbegin(); iter != obj.cend(); ++iter)
  {
    // Make sure to get the value as const reference otherwise you will end up copying
    // the whole JSON value recursively which can be expensive if it is a nested object.
    const json::value &str = iter->first;
    const json::value &v = iter->second;

    // Perform actions here to process each string and value in the JSON object...
    wprintf(L"String:%s", str.as_string());
    wprintf(L
"Value:%s", v.to_string());
  }
  return 0;
}

In the C++ REST SDK all JSON values are represented by the web::json::value class. In the example we build our JSON object using the value factory functions. A JSON value can also be parsed from a stream using a constructor that takes a stream reference. Once we have our JSON value we can use the cbegin and cend methods to return read-only iterators for the value collection.

Including this simple yet powerful representation of JSON objects in the SDK, provides developers with a set of tools that are productive and compose well together.

Thanks for taking the time to read this post, we hope that everyone gets a chance to visit the project on CodePlex, we would love to hear your feedback.

Stay tuned for more updates about both the C++ REST SDK and the Azure SDK for C++. A special thanks to Steve Gates for reviewing this post and providing the code snippets.

  • This is amazing news for the C++ community. Congratulations and keep the good stuff coming!

  • Love it

  • cool! will play with this :-)

    but please, void main?? my eyes are hurting...

  • Why, with such generic headers as uri.h and file_stream.h, do you not namespace them, e.g.

    #include <casablanca/uri.h>

    etc.?

  • Using lambdas, this definitely looks awesome!

  • @TommyS: definitely int main -- thanks for noticing this! Fixed.

  • This is wonderful!

  • Next stop, submit for consideration to the Standard! Great news and kudos to all involved.

  • I expected someone up-to-date with C++11 to at least know that main must return int, not void.

  • This is very cool.  Any thoughts on Mac support?

  • Congratulations to the team - this has been a long time coming and a lot of work has gone into this....

    Fantastic :)

  • @Essentia, but human---eror can made by Manish Maheshwari. what do you think of yourselfff ????

  • Any idea what the dependencies are preventing this working with XP and Vista? Would love to use in my app which needs to support those platforms. Thank you.

  • @turquoiseowl: We did not test Casablanca on Vista extensively (unlike Windows 7 and Windows 8), so we cannot claim that it is supported at this point. We're not aware of any technical reasons why it would not work though.

    We're using the new Windows thread pool, which was introduced in Vista, which is why it won't work before we rewrite that code to use the "legacy" thread pool.

    We're keenly aware of the importance of the XP and Vista support, and will enable it as soon as we can.

  • Not useful to my company until it runs on OSX.

Page 1 of 2 (20 items) 12