首页 > 代码库 > C++ REST SDK的基本用法

C++ REST SDK的基本用法

  微软开发了一个开源跨平台的http库--C++ REST SDK(http://casablanca.codeplex.com/),又名卡萨布兰卡Casablanca,有个电影也叫这个名字,也许这个库的作者很喜欢这个电影吧。从REST SDK这个名字可以看出它是处理rest API的,对REST不了解的童鞋可以点这里和这里,由于REST API的请求支持application/x-www-form-urlencoded、application/json、application/octet-stream等多种编码方式,REST API的返回值都是json形式,很方便返回对象。Casablanca采用c++11开发,集成了PPL和asio,支持异步数据流和web socket,用起来很方便。下面来看看官方的一个例子吧:

#include <cpprest\http_client.h>#include <cpprest\filestream.h>using namespace utility;using namespace web;using namespace web::http;using namespace web::http::client;using namespace concurrency;void TestRequest(){	auto fileStream = std::make_shared<concurrency::streams::ostream>();	pplx::task<void> requestTask = concurrency::streams::fstream::open_ostream(U("result.html")).then([=](concurrency::streams::ostream outFile){		*fileStream = outFile;		http_client client(U("http://www.bing.com/"));		uri_builder builder(U("/search"));		builder.append_query(U("q"), U("Casablanca CodePlex"));		return client.request(methods::GET, builder.to_string());	})	.then([=](http_response response)	{		return response.body().read_to_end(fileStream->streambuf());	}).then([=](size_t len){		return fileStream->close();	});	try	{		requestTask.wait();	}	catch (const std::exception& e)	{		cout << e.what() << endl;	}}

  这个例子把从bing.com上查询“Casablanca CodePlex”的内容保存到一个本地文件result.html中,用到了ppl的串行任务。启用了四个异步任务,第一个任务是打开一个文件流,接着,发起了第二个任务,用于发起一个查询请求,然后,第三个任务等待请求的响应,并将响应的结果输入到文件中去,第四个任务是关闭文件流。要注意rest sdk的字符相关的入参是宽字符(wchr_t)。这种处理http的方式让我们处理http的流程变得很清晰,有点小清新^_^,不过,这对于不太熟悉ppl用法的童鞋可能有点难接受,没关系,让我来简化一下,简化成同步方式,看得就更清楚了。

void TestRequest(){    auto fileStream = std::make_shared<concurrency::streams::ostream>();    concurrency::streams::ostream outFile = concurrency::streams::fstream::open_ostream(U("result11.html")).get();    *fileStream = outFile;    http_client client(L"http://www.bing.com/");    uri_builder builder(L"/search");    builder.append_query(L"q", L"Casablanca CodePlex");    http_response response = client.request(methods::GET, builder.to_string()).get();    response.body().read_to_end(fileStream->streambuf()).get();    fileStream->close().get();}

  注意上面的get()方法会阻塞等待异步线程完成操作。这样简化之后就能更清晰的看到如何使用rest sdk了,下面来说说发起http操作的几个对象。 http_client代表客户端,需要它发起http请求。rest api一般是基于一个基本URL增加了一些URL,比如上例中的search,还有可能有一些url参数,这时,我们就需要uri_builder来做这些拼接url和参数的事情,用起来很简单。

uri_builder builder;builder.append_path(L"search"); //添加URLbuilder.append_query(L"q", L"Casablanca CodePlex"); //添加url参数

  待url和参数准备好之后就可以发起请求了,请求方式可以用methods::GET和methods::POST等方式。

client.request(methods::GET, builder.to_string()).get();

  上面的例子中并没有request body,有时候我们发起http请求还需要request body,一般是json或者二进制格式,来看一个post json格式的request body的例子,rest sdk提供了json对象来解析json,用起来也很方便:

uri_builder builder;builder.append_path(L"/test");json::value obj;obj[L"Count"] = json::value::number(6);obj[L"Version"] = json::value::string(L"1.0");client.request(methods::POST, builder.to_string(), obj.serialize(), L"application/json");

  如果request body为二进制格式的话,这样发请求就可以了:

wchar_t buf[48] = {};http_response response = client.request(methods::POST, builder.to_string(), buf/*L""*/, L"application/octet-stream").get();

  请求发起之后就等http响应了,rest api返回的结果都是json格式的,所以我们需要解析json对象,rest sdk提供了http_response对象来处理响应。假设http响应的结果是这样的:

{    "result":"service failed"    "error_code": 400}

  http响应的处理:

if (response.status_code() == status_codes::OK){    try    {        result = true;        const json::value& jv = response.extract_json().get();        const web::json::object& jobj = jv.as_object();        auto result = jobj.at(L"result").as_string();        auto access_code = result.as_object().at(L"error_code").as_string();        wcout << result<<" "<< access_code << endl;    }    catch (const std::exception& e)    {        cout << e.what() << endl;    }}

  用wcout输出宽字符时需要做一个初始化,否则可能输出不了内容。

wcout.imbue(locale("chs"));//本地化

  我们还可以设置相关的http属性,http_client默认的超时时间是30秒,我们也可以自己设置超时时间:

http_client_config config;config.set_timeout(utility::seconds(90)); //设置为90秒超时http_client client(URL, config);


总结:可以看到C++ REST SDK的用法是很简单的,uri的解析和拼接,json的处理,请求和响应的处理都有相应的对象,我们用起来就很省心了。微软提供的C++ REST SDK真是个好东西,值得我们深入去研究。

C++ REST SDK的基本用法