C++如何调用RESTful API?cpprestsdk (Casablanca)使用教程【网络编程】

cpprestsdk是C++调用RESTful API最成熟跨平台方案,支持异步、HTTP客户端、JSON解析和URI处理;推荐vcpkg安装,Windows用cpprestsdk:x64-windows,Linux/macOS用x64-linux/x64-osx;示例通过http_client发起GET请求并解析JSON响应。

用 C++ 调用 RESTful API,cpprestsdk(Casablanca) 是目前最成熟、跨平台、原生支持异步的官方推荐方案。它封装了 HTTP 客户端、JSON 解析、URI 处理等能力,无需手动拼接 HTTP 报文或解析 JSON 字符串。

安装 cpprestsdk(Windows / Linux / macOS)

官方推荐通过 vcpkg 管理依赖,避免编译复杂性:

  • Windows(Visual Studio):vcpkg install cpprestsdk:x64-windows,然后在 CMake 或 VS 项目中启用 vcpkg 集成
  • Linux/macOS:vcpkg install cpprestsdk:x64-linux(或 x64-osx),导出为 system port 或使用 -DCMAKE_TOOLCHAIN_FILE

若需源码编译,注意开启 BUILD_TESTS=OFFBUILD_SAMPLES=OFF 加速构建,并确保已安装 OpenSSL、Boost(部分版本可选)、CMake 3.15+。

发起 GET 请求并解析 JSON 响应

以下是最简可用示例:获取 https://httpbin.org/get 并打印 query 参数回显:

#include 
#include 
#include 

using namespace web;
using namespace web::http;
using namespace web::http::client;
using json = web::json::value;

int main() {
    http_client client(U("https://httpbin.org"));
    auto resp = client.request(methods::GET, U("/get")).get();
    
    if (resp.status_code() == status_codes::OK) {
        auto body = resp.extract_json().get();
        std::wcout << L"Origin: " << body[U("origin")].as_string() << std::endl;
    }
}

关键点:

  • http_client 构造时传入 base URI(不含路径),路径在 request() 中指定
  • get() 是同步阻塞调用;如需异步,用 then() 链式处理
  • extract_json() 自动识别 Content-Type 并解析;失败会抛异常,建议加 try/catch

发送 POST 请求(JSON Body + Headers)

向 API 提交结构化数据,例如登录请求:

json::value creds;
creds[U("username")] = json::value::string(U("alice"));
creds[U("password")] = json::value::string(U("secret123"));

http_request req(methods::POST);
req.set_request_uri(U("/login"));
req.set_body(creds);
req.headers().add(U("Content-Type"), U("application/json"));
req.headers().add(U("User-Agent"), U("MyCppApp/1.0"));

auto resp = client.request(req).get();

注意细节:

  • http_request 手动构造更灵活,适合设置 header、body、method 组合
  • JSON 字符串值必须用 json::value::string() 包装,不能直接写 L"xxx"
  • 中文等 Unicode 字符默认 UTF-8 编码,无需额外转码

错误处理与超时控制

网络请求必须考虑失败场景。cpprestsdk 默认无超时,需显式配置:

http_client_config config;
config.set_timeout(std::chrono::seconds(10)); // 全局超时
http_client client(U("https://api.example.com"), config);

try {
    auto resp = client.request(methods::GET, U("/data")).get();
    if (resp.status_code() >= 400) {
        auto err = resp.extract_string().get();
        std::wcerr << L"HTTP Error " << resp.status_code() << L": " << err << std::endl;
    }
} catch (const http_exception& e) {
    std::wcerr << L"Network or protocol error: " << e.what() << std::endl;
} catch (const std::exception& e) {
    std::wcerr << L"General error: " << e.what() << std::endl;
}

常见异常类型:

  • http_exception:连接失败、DNS 解析失败、SSL 握手失败等底层错误
  • std::exception 及其子类:JSON 解析失败、内存不足、URI 格式错误等
  • HTTP 状态码 4xx/5xx 不抛异常,需手动检查 status_code()

基本上就这些。cpprestsdk 上手略重于 curl + jsoncpp 组合,但胜在统一抽象、线程安全、异步友好,适合中大型 C++ 网络客户端项目。实际使用中记得始终处理异常、设置合理超时、验证 JSON 字段存在性(用 has_field()),避免崩溃。