C++ REST SDK in Visual Studio 2013

The C++ REST project provides a modern asynchronous C++ API for cloud-based client-server communication. It is available on codeplex and works with Visual Studio 2010 and 2012, but it is now distributed with Visual Studio 2013. The preview version of VS2013 deploys version 1.0 of the SDK. Since its release a new version of the SDK (v1.1.0) has been made available.

The following example shows how to retrieve and display some JSON content. I’m querying google using its REST API. Here is how a query (for a single result) may look:

https://ajax.googleapis.com/ajax/services/search/web?q=marius%20bancila&v=1.0&rsz=1

The result that we get is a JSON value. From this value I will only display the URL and the (un-formatted) title.

{
   "responseData":{
      "results":[
         {
            "GsearchResultClass":"GwebSearch",
            "unescapedUrl":"http://www.mariusbancila.ro/",
            "url":"http://www.mariusbancila.ro/",
            "visibleUrl":"www.mariusbancila.ro",
            "cacheUrl":"http://www.google.com/search?q\u003dcache:oFoVQN2DkeYJ:www.mariusbancila.ro",
            "title":"\u003cb\u003eMarius Bancila\u0026#39;s\u003c/b\u003e Blog",
            "titleNoFormatting":"Marius Bancila\u0026#39;s Blog",
            "content":"\u003cb\u003eMarius Bancila\u003c/b\u003e Tools, Visual Studio Add your comment. Visual Studio 2013   provides developers with the ability to sign in with a Microsoft account and \u003cb\u003e...\u003c/b\u003e"
         }
      ],
      "cursor":{
         "resultCount":"6,850",
         "pages":[
            {
               "start":"0",
               "label":1
            },
            {
               "start":"1",
               "label":2
            },
            {
               "start":"2",
               "label":3
            },
            {
               "start":"3",
               "label":4
            },
            {
               "start":"4",
               "label":5
            },
            {
               "start":"5",
               "label":6
            },
            {
               "start":"6",
               "label":7
            },
            {
               "start":"7",
               "label":8
            }
         ],
         "estimatedResultCount":"6850",
         "currentPageIndex":0,
         "moreResultsUrl":"http://www.google.com/search?oe\u003dutf8\u0026ie\u003dutf8\u0026source\u003duds\u0026start\u003d0\u0026hl\u003den\u0026q\u003dmarius+bancila",
         "searchResultTime":"0.16"
      }
   },
   "responseDetails":null,
   "responseStatus":200
}

There are several things that we must do:

  • create a http_client that maintains the connection to a HTTP service
  • send a HTTP GET request asynchronous and wait for the response
  • when the response is available check its status code and if all is right extract the JSON value from the body of the response message (the content type must be application/json)
  • when the json value is available display its content

The code looks like this:

#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
#include <cpprest/json.h>

#include <iostream>

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

using namespace std;

void print_search_results(json::value const & value)
{
   if(!value.is_null())
   {
      auto response = value[L"responseData"];
      auto results = response[L"results"];
      for(auto const & p : results)
      {
         auto o = p.second;
         auto url = o[L"url"];
         auto title = o[L"titleNoFormatting"];

         wcout << title.as_string() << endl << url.as_string() << endl << endl;
      }
   }
}

void search_and_print(wstring const & searchTerm, int resultsCount)
{
   http_client client(U("https://ajax.googleapis.com/ajax/services/search/web"));

   // build the query parameters
   auto query =  uri_builder()
      .append_query(L"q", searchTerm)
      .append_query(L"v", L"1.0")
      .append_query(L"rsz", resultsCount)
      .to_string();

   client
      // send the HTTP GET request asynchronous
      .request(methods::GET, query)
      // continue when the response is available
      .then([](http_response response) -> pplx::task<json::value>
      {
         // if the status is OK extract the body of the response into a JSON value
         // works only when the content type is application\json
         if(response.status_code() == status_codes::OK)
         {
            return response.extract_json();
         }

         // return an empty JSON value
         return pplx::task_from_result(json::value());
      })
      // continue when the JSON value is available
      .then([](pplx::task<json::value> previousTask)
      {
         // get the JSON value from the task and display content from it
         try
         {
            json::value const & v = previousTask.get();
            print_search_results(v);
         }
         catch (http_exception const & e)
         {
            wcout << e.what() << endl;
         }
      })
      .wait();
}

The following program retrieves 5 search results for “marius bancila”.

int main(int argc, char *args[])
{
   search_and_print(L"marius bancila", 5);

   return 0;
}

The output looks like this:

Marius Bancila's Blog
http://www.mariusbancila.ro/

Marius Bancila (mariusbancila) on Twitter
https://twitter.com/mariusbancila

User Marius Bancila - Stack Overflow
http://stackoverflow.com/users/648078/marius-bancila

Marius Bancila profiles | LinkedIn
http://www.linkedin.com/pub/dir/Marius/Bancila

Marius Bancila Profiles | Facebook
https://www.facebook.com/public/Marius-Bancila

You can find documentation for the API and the SDK here.

13 Replies to “C++ REST SDK in Visual Studio 2013”

  1. Looking at the code I assume that by usage of .then() you are restricting the code to Windows platform, or there are some internal tricks to simulate it?

  2. @Bartosz Bielecki

    I could be wrong, but looking at the sources (which are freely available), then is a member function of class task, which is the type returned by request.

    The code:

    client.request(…).task(…) ;

    is simply chaining the calls. Not some compiler specific trick.

    I saw nothing in the sources that wouldn’t be compiled on any C++11 compliant compiler.

    P.S.: Sources:

    https://casablanca.codeplex.com/SourceControl/latest#Release/include/cpprest/http_client.h

    https://casablanca.codeplex.com/SourceControl/latest#Release/include/pplx/pplxtasks.h

  3. Hi Marius,

    I’m hoping you can help me. I was conflicted whether to use the latest releases with VS 2012 Express, or go for VS 2013 Express RC, which includes Casablanca – albeit the 1.0 version.

    So I went with VS 2013 RC. I am trying to run the example code from here:
    http://msdn.microsoft.com/en-us/library/jj950081(v=vs.120).aspx

    but am having fits with my C++ project finding the appropriate library and specific library files. I am following steps as outlined here: http://stackoverflow.com/questions/4066405/when-to-use-the-visual-studio-additional-dependencies

    for setting up additional dependencies in my project. My project can now find the header files, but I am getting errors because it either can’t find or can’t open the actual library files (going from memory, I think they are named something like “casablanca120”).

    Did you run into this issue with VS 2013 RC? Could you share with me how you set up your project under Configuration Properties –> Linker?

    Thank you for any help or guidance you can provide.

    Terry

  4. If you try a newer SDK with VS2013, even if you get the paths working, you won’t get it working, because the SDK does not have builds for VS2013 and your app will crash at runtime (http://casablanca.codeplex.com/workitem/49). If you use the SDK that comes with the Preview, then all paths should be set and the project should build. However, if that is not the case you can still set additional include and library directories as well as static library files to link with.

  5. create an application that calls the rest api from one computer and the other computer responds
    with a message using c++ REST sdk.. please help me .. give me a coding..

  6. Would you mind including a full sample project for download?

    I get build errors with this code. I think my project is screwed up. Maybe to do with unicode. (Probably because I have to set project settings manually as nuget doesnt seem to it for me).

    auto response = value[L”responseData”];

    error C2678: binary ‘[‘ : no operator found which takes a left-hand operand of type ‘const web::json::value’ (or there is no acceptable conversion)

  7. For anyone else having problems with compiling:
    auto response = value[L”responseData”];
    error C2678: binary ‘[‘ : no operator found which takes a left-hand operand of type ‘const web::json::value’ (or there is no acceptable conversion)

    There was a change in 2.0.0 that broke the above example. There is a good post below explaining what changed and how to get this code working with an updated API:
    http://casablanca.codeplex.com/discussions/565104

    Hope this helps someone!

  8. Hello
    Could you please help me with C++ REST webservices for stock trading
    Regards
    Abhsihek

  9. Hi,

    I’m getting this exception message:
    Content-Type must be application/json to extract (is: text/javascript)

    How can I set the content-type to application/json?

    I used .request(methods::GET, L””, query,L”application/json”) but it doesn’t work, an exception occurs with this message: “A GET or HEAD request should not have an entity body.”

    I’m working on VS2013.
    Any directions and welcome.

    Thanks,

    Edgar

  10. HI Marius,

    Need your help. Iam not able to get a proper link where I can get install cpprestsdk on ubutnu 14.04 . Getting below error while installing

    sudo apt-get install libcpprest-dev
    E: Unable to locate package libcpprest-dev

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.