Using Casablanca To Consume A REST API 1
Using Casablanca To Consume A REST API 1
CPOL
Introduction
Casablanca is the quasi-official C++ REST library from Microsoft published as an open source
project on CodePlex. And I say "quasi" as it does not come with Visual C++ by default, but for all
you know that may change in future. The VC++ team has backed it strongly and has recommended
using 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 asynchronous
approach to consuming HTTP and JSON based services. There are extensions that allow you to
write Windows 8 store applications in Casablanca, but you can use it in desktop apps as well. The
code 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 consumed
by 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 PPL
extensions to write asynchronous code.
// . . .
}
private static Members members = new Members();
// GET api/values
public IEnumerable<Member> 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);
}
}
{
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 HTTP
connection to the web service. The request method sends the HTTP request asynchronously,
and I've specified this to be a G
GE
ETT request. The continuation gets an http_response object
that 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 know
it's an array of JSON values representing Member objects, and so I iterate through the list and
extract the Member objects using my object conversion class. Here's the code that does a G
GE
ETT
aappii//vvaalluueess//iidd call.
pplx::task<void> Get(int id)
{
return pplx::create_task([id]
{
std::wstringstream ws;
ws << L"http://localhost:5540/api/values/" << id;
http_client client(ws.str());
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;
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 P
PO
OS
STT data to the service.
pplx::task<int> 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 << L"Added new Id: " << body.get().c_str() <<
std::endl;
return std::stoi(body.get().c_str());
}
return 0;
});
}
The json::value class has overloaded [] operators, so you can use an array-like
syntax to set data. When making the request call, you need to specify P
PO
OS
STT, provide the data
to sent, and set the ccoonntteenntt--ttyyppee to aapppplliiccaattiioonn//jjssoonn. The web service returns back the ID of the
newly added object, so there's code there to parse that and return the int value.
References
Setting VC++ up to use Casablanca
Casablanca on CodePlex
History
JJuunnee 66tthh,, 22001133 - Article published
License
This article, along with any associated source code and files, is licensed under The Code Project
Open License (CPOL)
Share
About the Author
N ish N ishant
United States
N
Niisshh N
Niisshhaanntt is a Software Architect/Consultant based out of C
Coolluum
mbbuuss,, O
Ohhiioo. He has over 16
years of software industry experience in various roles including LLeeaadd S
Sooffttw
waarree A
Arrcchhiitteecctt,
P
Prriinncciippaall S
Sooffttw
waarree E
Ennggiinneeeerr, and P
Prroodduucctt M
Maannaaggeerr. Nish is a recipient of the annual
M
Miiccrroossoofftt V
Viissuuaall C
C++++ M
MV
VP
P Award since 2002 (14 consecutive awards as of 2015).
Nish is an industry acknowledged expert in the Microsoft technology stack. He authored
C++/CLI in Action for Manning Publications in 2005, and had previously co-authored
Extending 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+ blog
articles on his
WordPress blog. Nish is vastly experienced in team management, mentoring teams, and
directing all stages of software development.
C
Coonnttaacctt N
Niisshh : You can reach Nish on his google email id vvooiiddnniisshh.
W
Weebbssiittee aanndd B
Blloogg
www.voidnish.com
voidnish.wordpress.com
The Microsoft
Cloud Platform for
Developers
Create RESTful
WCF Service API:
Step By Step
Guide
Building Modern
Web Apps with
ASP.NET MVC 6
Select Language