Using Casablanca to Consume a REST API 1

download Using Casablanca to Consume a REST API 1

of 5

Transcript of Using Casablanca to Consume a REST API 1

  • 8/19/2019 Using Casablanca to Consume a REST API 1

    1/9

     Articles » Web Development » Web Services » General

    NNiisshh NNiisshhaanntt, 6 Jun 2013 CPOL

    Using Casablanca to consume a REST API

    The article walks through using the Casablanca REST API library to consume a REST web servicefrom C++ code

    Introduction

    Casablanca is the quasi-official C++ REST library from Microsoft published as an open sourceproject on CodePlex. And I say "quasi" as it does not come with Visual C++ by default, but for allyou know that may change in future. The VC++ team has backed it strongly and has recommendedusing it for all your REST access requirements.

    Casablanca - C++ REST SDK (CodePlex)

    Casablanca allows you to write native code to access REST services and uses an asynchronousapproach to consuming HTTP and JSON based services. There are extensions that allow you towrite Windows 8 store applications in Casablanca, but you can use it in desktop apps as well. Thecode is written in a portable manner, so you can use it from Linux too, should you want to.

    This article quickly demonstrates a skeletal ASP.NET MVC 4 REST web service that is consumedby C++ code that uses Casablanca to do the four common HTTP operations - GET, POST, PUT,and DELETE. It also shows how to parse and create JSON, and also how to use the PPLextensions to write asynchronous code.

    The skeletal web service

    I wanted to keep the example simple, so this service uses a very simple business object called

    Member.

    public class Member

    {

    public int Id { get; set; }

    public string Name { get; set; }

    public string Sport { get; set; }

    }

    Instead of reading and witting from an actual database or backend, I have a mock storage class

    that can add, edit, fetch, and delete Member objects.

    4.86 (12 votes)

  • 8/19/2019 Using Casablanca to Consume a REST API 1

    2/9

    public class Members

    {

    private Collection members = new Collection();

    private int nextId = 1;

    public Member Add(string name, string sport)

      {

    var member = new Member()

      {

      Id = nextId++,

      Name = name,

      Sport = sport

      };

      members.Add(member);

    return member;

      }

    public IEnumerable GetAll()

      {

    return members;

      }

    public Member Get(int id)

      {

    return members.FirstOrDefault(m => m.Id == id);

      }

    public Member Update(int id, string name, string sport)

      {

    var item = Get(id);

    if (item != null)

      {

      item.Name = name;

      item.Sport = sport;

    return item;

      }

    return null;

      }

    public bool Delete(int id)

      {

    var item = Get(id);

    if (item != null)

      {

      members.Remove(item);

    return true;

      }

    return false;

      }

    }

     And here's the controller.

    public class ValuesController : ApiController

    {

    static ValuesController()

      {

      members.Add("Nish", "Tennis");

      members.Add("Andrew", "Baseball");

  • 8/19/2019 Using Casablanca to Consume a REST API 1

    3/9

    // . . .

      }

    private static Members members = new Members();

    // GET api/values

    public IEnumerable Get()

      {return members.GetAll();

      }

    // GET api/values/id 

    public Member Get(int id)

      {

    return members.Get(id);

      }

    // POST api/values

    public int Post(dynamic data)  {

    return members.Add((string)data.name, (string)data.sport).Id;

      }

    // PUT api/values/id 

    public Member Put(int id, dynamic data)

      {

    return members.Update(id, (string)data.name,

    (string)data.sport);

      }

    // DELETE api/values/id 

    public bool Delete(int id)

      {

    return members.Delete(id);

      }

    }

    Making GET calls and parsing JSON

    Typically, these are the include files you'd need to use Casablanca.

    #include

    #include

    #include

    Here's the C++ version of the business object.

    class Member

    {

    public:

    int Id;

      std::wstring Name;

      std::wstring Sport;

    void Display()

      {

      std::wcout

  • 8/19/2019 Using Casablanca to Consume a REST API 1

    4/9

    enum FieldValue {Id, Name, Sport };

    class MemberGenerator

    {

      std::map fieldMap;

      Member member;

    public:

      MemberGenerator()

      {

      fieldMap[L"Id"] = FieldValue::Id;

      fieldMap[L"Name"] = FieldValue::Name;

      fieldMap[L"Sport"] = FieldValue::Sport;

      }

    void SetField(std::wstring name, json::value value)

      {

    switch(fieldMap[name])

      {

    case FieldValue::Id:

    member.Id = value.as_integer();

    break;

    case FieldValue::Name:

    member.Name = value.as_string();

    break;

    case FieldValue::Sport:

    member.Sport = value.as_string();break;

      }

      }

      Member GetMemberFromJson(json::value jsonValue)

      {

    for(auto iterInner = jsonValue.cbegin(); iterInner !=

    jsonValue.cend(); ++iterInner)

      {

    const json::value &propertyName = iterInner->first;

    const json::value &propertyValue = iterInner->second;

      SetField(propertyName.as_string(), propertyValue);

      }

    return member;

      }

    };

    I wish C++ had reflection the way C# has (or rather .NET has). That'd have made writing this mucheasier and cleaner. But this is close enough and is probably better from a performance perspective.

    The GetMemberFromJson gets a json::value object as its argument. Thejson::value class is basically a C++ abstraction over a JSON value. In my example, this willbe a composite JSON value that contains the properties of the Member object. Using cbeginand cend, we iterate through the composite object. The iterator is an std::vector of anstd::pair of json::value objects. The pair represents the property name and itsassociated value. The SetField method then looks up the property name and for eachproperty, we know the type and thus call one of the as_xxx() methods which converts theJSON value into the requested type. Obviously, a more real world scenario would have multi-levelnested business objects, so you'd need a more involved conversion framework, but I wouldimagine that the core approach would remain very similar to what I did there.

    Here's the code that does a GGEETT call to get all objects. This is basically the implementation for GGEETT aappii//vvaalluueess.

    pplx::task GetAll()

  • 8/19/2019 Using Casablanca to Consume a REST API 1

    5/9

    {

    return pplx::create_task([]

      {

    http_client client(L"http://localhost:5540/api/values");

    return client.request(methods::GET);

      }).then([](http_response response)

      {if(response.status_code() == status_codes::OK)

      {

    return response.extract_json();

      }

    return pplx::create_task([] { return json::value(); });

      }).then([](json::value jsonValue)

      {

    if(jsonValue.is_null())

    return;

      MemberGenerator generator;

    for(auto iterArray = jsonValue.cbegin(); iterArray !=

    jsonValue.cend(); ++iterArray)

      {

    const json::value &arrayValue = iterArray->second;

      auto member = generator.GetMemberFromJson(arrayValue);

    member.Display();

      }

      });}

    The http_client class, rather unsurprisingly named, is the core class that handles the HTTPconnection to the web service. The request method sends the HTTP request asynchronously,and I've specified this to be a GGEETT request. The continuation gets an http_response objectthat represents the response from the server. (These methods and types are so lucidly named that I feel like an idiot repeating things. I mean saying things like - the http_response class represents an HTTP response. Oh well! ) It's got methods to get the body, headers, status code, etc. Once I

    verify that the response code was 200, I call the extract_json method, also asynchronous.

    When that's completed, the continuation receives a json::value object. In this case, I knowit's an array of JSON values representing Member objects, and so I iterate through the list andextract the Member objects using my object conversion class. Here's the code that does a GGEETTaappii//vvaalluueess//iidd call.

    pplx::task Get(int id)

    {

    return pplx::create_task([id]

      {

      std::wstringstream ws;

      ws

  • 8/19/2019 Using Casablanca to Consume a REST API 1

    6/9

    if(jsonValue.is_null())

    return;

      MemberGenerator generator;

      auto member = generator.GetMemberFromJson(jsonValue);

      member.Display();

    });

    }

    It's quite similar except the URL now includes the id to fetch and the JSON response is for a single

    Member object.

    Submitting a POST

    Here's code showing how to PPOOSSTT data to the service.

    pplx::task Post()

    {

    return pplx::create_task([]

      {

      json::value postData;

      postData[L"name"] = json::value::string(L"Joe Smith");

      postData[L"sport"] = json::value::string(L"Baseball");

      http_client client(L"http://localhost:5540/api/values");

    return client.request(methods::POST, L"",

    postData.to_string().c_str(), L"application/json");

    }).then([](http_response response)

      {

    if(response.status_code() == status_codes::OK)

      {

    auto body = response.extract_string();

    std::wcout

  • 8/19/2019 Using Casablanca to Consume a REST API 1

    7/9

      ws

  • 8/19/2019 Using Casablanca to Consume a REST API 1

    8/9

    References

    Setting VC++ up to use CasablancaCasablanca on CodePlex

    HistoryJJuunnee 66tthh,, 22001133 - Article published

    License

    This article, along with any associated source code and files, is licensed under The Code ProjectOpen License (CPOL)

    Share

     About the Author 

    NNiisshh NNiisshhaanntt is a Software Architect/Consultant based out of CCoolluummbbuuss,, OOhhiioo. He has over 16years of software industry experience in various roles including LLeeaadd SSooffttwwaarree AArrcchhiitteecctt,PPrriinncciippaall SSooffttwwaarree EEnnggiinneeeerr, and PPrroodduucctt MMaannaaggeerr. Nish is a recipient of the annualMMiiccrroossoofftt VViissuuaall CC++++ MMVVPP Award since 2002 (14 consecutive awards as of 2015).

    Nish is an industry acknowledged expert in the Microsoft technology stack. He authoredC++/CLI in Action for Manning Publications in 2005, and had previously co-authoredExtending MFC Applications with the .NET Framework for Addison Wesley in 2003. In addition,

    he has over 140 published technology articles on CodeProject.com and another 250+ blogarticles on hisWordPress blog. Nish is vastly experienced in team management, mentoring teams, anddirecting all stages of software development.

    CCoonnttaacctt NNiisshh : You can reach Nish on his google email id vvooiiddnniisshh.

    WWeebbssiittee aanndd BBlloogg

    www.voidnish.comvoidnish.wordpress.com

    NNiisshh NNiisshhaanntt

    United States

  • 8/19/2019 Using Casablanca to Consume a REST API 1

    9/9

    Permalink | Advertise | Privacy | Terms of Use | MobileWeb03 | 2.8.160304.1 | Last Updated 6 Jun 2013 Select Language ▼

     Article Copyright 2013 by Nish NishantEverything else Copyright © CodeProject, 1999-2016

    You may also be interested in...

    ConsumingGoogle Maps APIRest Services in.NET

    The MicrosoftCloud Platform for Developers

    Consuming Cross-Domain WCFREST Serviceswith jQuery usingJSONP

    Game On: Intel®Edison with theXadow WearableKit

    Create RESTfulWCF Service API:Step By StepGuide

    Building ModernWeb Apps with ASP.NET MVC 6

    Comments and Discussions

    55 mmeessssaaggeess have been posted for this article Visit hhttttpp::////wwwwww..ccooddeepprroojjeecctt..ccoomm//AArrttiicclleess//660033881100//UUssiinngg--CCaassaabbllaannccaa--ttoo--ccoonnssuummee--aa--RREESSTT--AAPPII to post and view comments on thisarticle, or click hheerree to get a print view with messages.