C++ REST SDK (代号 Casablanca) 是微软开发的一个跨平台 C++ 库,用于构建现代的、连接云服务的 C++ 应用程序。它提供了 HTTP 客户端/服务器、JSON 处理、WebSocket 支持、异步任务等功能,适合构建 RESTful 服务和客户端。
# 安装依赖
sudo apt-get install libboost-all-dev libssl-dev
# 从源码编译
git clone https://github.com/microsoft/cpprestsdk.git
cd cpprestsdk
mkdir build && cd build
cmake ..
cmake --build .
sudo make install
brew install cpprestsdk
vcpkg install cpprestsdk:x64-windows
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
#include <iostream>
using namespace web;
using namespace web::http;
using namespace web::http::client;
int main() {
// 创建 HTTP 客户端
http_client client(U("https://api.github.com"));
// 发送 GET 请求
client.request(methods::GET, U("/users/microsoft"))
.then([](http_response response) {
// 检查状态码
if (response.status_code() == status_codes::OK) {
// 读取响应体
return response.extract_json();
}
return pplx::task_from_result(json::value());
})
.then([](json::value jsonValue) {
// 解析 JSON
if (!jsonValue.is_null()) {
utility::string_t login = jsonValue.at(U("login")).as_string();
std::wcout << L"Login: " << login << std::endl;
utility::string_t html_url = jsonValue.at(U("html_url")).as_string();
std::wcout << L"URL: " << html_url << std::endl;
}
})
.wait(); // 等待异步操作完成
return 0;
}
#include <cpprest/http_client.h>
#include <iostream>
using namespace web;
using namespace web::http;
using namespace web::http::client;
int main() {
http_client client(U("https://httpbin.org/post"));
// 创建 JSON 请求体
json::value postData;
postData[U("name")] = json::value::string(U("Alice"));
postData[U("age")] = json::value::number(25);
postData[U("active")] = json::value::boolean(true);
// 发送 POST 请求
client.request(methods::POST, U(""), postData.to_string())
.then([](http_response response) {
if (response.status_code() == status_codes::OK) {
return response.extract_json();
}
return pplx::task_from_result(json::value());
})
.then([](json::value responseJson) {
// 打印响应
if (!responseJson.is_null()) {
std::wcout << responseJson.serialize() << std::endl;
}
})
.wait();
return 0;
}
#include <cpprest/http_client.h>
#include <iostream>
using namespace web;
using namespace web::http;
using namespace web::http::client;
int main() {
http_client client(U("https://jsonplaceholder.typicode.com/posts/1"));
// 创建更新数据
json::value updateData;
updateData[U("title")] = json::value::string(U("Updated Title"));
updateData[U("body")] = json::value::string(U("Updated body content"));
// 发送 PUT 请求
client.request(methods::PUT, U(""), updateData.to_string())
.then([](http_response response) {
if (response.status_code() == status_codes::OK) {
return response.extract_json();
}
return pplx::task_from_result(json::value());
})
.then([](json::value responseJson) {
std::wcout << L"Updated: " << responseJson.serialize() << std::endl;
})
.wait();
return 0;
}
#include <cpprest/http_client.h>
#include <iostream>
using namespace web;
using namespace web::http;
using namespace web::http::client;
int main() {
http_client client(U("https://jsonplaceholder.typicode.com/posts/1"));
// 发送 DELETE 请求
client.request(methods::DEL)
.then([](http_response response) {
std::wcout << L"Status Code: " << response.status_code() << std::endl;
return response.extract_string();
})
.then([](utility::string_t responseText) {
std::wcout << L"Response: " << responseText << std::endl;
})
.wait();
return 0;
}
#include <cpprest/json.h>
#include <iostream>
using namespace web;
using namespace web::json;
int main() {
// 创建 JSON 对象
json::value user;
user[U("id")] = json::value::number(1);
user[U("name")] = json::value::string(U("Alice"));
user[U("active")] = json::value::boolean(true);
// 创建 JSON 数组
json::value hobbies = json::value::array();
hobbies[0] = json::value::string(U("reading"));
hobbies[1] = json::value::string(U("coding"));
hobbies[2] = json::value::string(U("gaming"));
user[U("hobbies")] = hobbies;
// 序列化为字符串
utility::string_t jsonStr = user.serialize();
std::wcout << L"JSON: " << jsonStr << std::endl;
// 解析 JSON 字符串
json::value parsed = json::value::parse(jsonStr);
// 访问字段
utility::string_t name = parsed.at(U("name")).as_string();
int id = parsed.at(U("id")).as_integer();
bool active = parsed.at(U("active")).as_bool();
std::wcout << L"Name: " << name << std::endl;
std::wcout << L"ID: " << id << std::endl;
std::wcout << L"Active: " << (active ? L"Yes" : L"No") << std::endl;
// 遍历数组
if (parsed.has_field(U("hobbies")) && parsed.at(U("hobbies")).is_array()) {
json::array hobbiesArray = parsed.at(U("hobbies")).as_array();
std::wcout << L"Hobbies:" << std::endl;
for (const auto& hobby : hobbiesArray) {
std::wcout << L" - " << hobby.as_string() << std::endl;
}
}
return 0;
}
#include <cpprest/json.h>
#include <iostream>
using namespace web;
using namespace web::json;
int main() {
// 创建嵌套 JSON
json::value company;
company[U("name")] = json::value::string(U("TechCorp"));
// 嵌套地址对象
json::value address;
address[U("street")] = json::value::string(U("123 Tech Street"));
address[U("city")] = json::value::string(U("San Francisco"));
address[U("zip")] = json::value::string(U("94102"));
company[U("address")] = address;
// 嵌套员工数组
json::value employees = json::value::array();
json::value emp1;
emp1[U("id")] = json::value::number(1);
emp1[U("name")] = json::value::string(U("Alice"));
employees[0] = emp1;
json::value emp2;
emp2[U("id")] = json::value::number(2);
emp2[U("name")] = json::value::string(U("Bob"));
employees[1] = emp2;
company[U("employees")] = employees;
std::wcout << company.serialize() << std::endl;
// 访问嵌套字段
utility::string_t city = company.at(U("address")).at(U("city")).as_string();
std::wcout << L"City: " << city << std::endl;
return 0;
}
#include <cpprest/http_listener.h>
#include <cpprest/json.h>
#include <iostream>
using namespace web;
using namespace web::http;
using namespace web::http::experimental::listener;
void handle_get(http_request request) {
// 构造 JSON 响应
json::value response;
response[U("message")] = json::value::string(U("Hello, World!"));
response[U("status")] = json::value::string(U("success"));
// 发送响应
request.reply(status_codes::OK, response);
}
void handle_post(http_request request) {
// 读取请求体
request.extract_json()
.then([request](pplx::task<json::value> task) {
try {
json::value jsonData = task.get();
// 处理数据
utility::string_t name = jsonData.at(U("name")).as_string();
// 构造响应
json::value response;
response[U("greeting")] = json::value::string(
U("Hello, ") + name + U("!")
);
response[U("status")] = json::value::string(U("success"));
request.reply(status_codes::OK, response);
} catch (const std::exception& e) {
json::value error;
error[U("error")] = json::value::string(U("Invalid JSON"));
request.reply(status_codes::BadRequest, error);
}
}).wait();
}
int main() {
// 创建 HTTP 监听器
http_listener listener(U("http://localhost:8080/api"));
// 注册路由
listener.support(methods::GET, handle_get);
listener.support(methods::POST, handle_post);
try {
// 启动监听
listener.open().wait();
std::wcout << L"Server running at http://localhost:8080/api" << std::endl;
std::wcout << L"Press Enter to exit..." << std::endl;
std::cin.get();
// 停止监听
listener.close().wait();
} catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
return 0;
}
#include <cpprest/ws_client.h>
#include <iostream>
using namespace web;
using namespace web::websockets;
using namespace web::websockets::client;
int main() {
// 创建 WebSocket 客户端
websocket_callback_client client;
// 配置消息接收回调
client.set_message_handler([](const websocket_incoming_message& msg) {
utility::string_t message = msg.extract_string().get();
std::wcout << L"Received: " << message << std::endl;
});
// 连接到服务器
client.connect(U("ws://echo.websocket.org")).wait();
std::wcout << L"Connected to WebSocket server" << std::endl;
// 发送消息
websocket_outgoing_message msg;
msg.set_utf8_message("Hello from C++ REST SDK!");
client.send(msg).wait();
std::wcout << L"Message sent" << std::endl;
// 等待一会儿接收响应
std::this_thread::sleep_for(std::chrono::seconds(2));
// 关闭连接
client.close().wait();
std::wcout << L"Connection closed" << std::endl;
return 0;
}
#include <cpprest/http_client.h>
#include <iostream>
using namespace web;
using namespace web::http;
using namespace web::http::client;
int main() {
http_client client(U("https://httpbin.org/headers"));
// 创建请求
http_request request(methods::GET);
// 设置自定义请求头
request.headers().add(U("User-Agent"), U("C++ REST SDK Client"));
request.headers().add(U("Accept"), U("application/json"));
request.headers().add(U("X-Custom-Header"), U("CustomValue"));
// 添加认证头
utility::string_t auth = U("Bearer ") + U("your-token-here");
request.headers().add(U("Authorization"), auth);
// 发送请求
client.request(request)
.then([](http_response response) {
return response.extract_json();
})
.then([](json::value jsonValue) {
std::wcout << jsonValue.serialize() << std::endl;
})
.wait();
return 0;
}
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
#include <iostream>
#include <fstream>
using namespace web;
using namespace web::http;
using namespace web::http::client;
int main() {
http_client client(U("https://httpbin.org/post"));
// 创建文件流
concurrency::streams::fstream fileStream =
concurrency::streams::fstream::open_istream(
U("example.txt"),
std::ios::in
).get();
// 创建多部分表单数据
http_request request(methods::POST);
// 设置请求体为文件内容
request.set_body(fileStream);
request.headers().set_content_type(U("text/plain"));
// 发送请求
client.request(request)
.then([](http_response response) {
std::wcout << L"Status: " << response.status_code() << std::endl;
return response.extract_string();
})
.then([](utility::string_t responseText) {
std::wcout << L"Response: " << responseText << std::endl;
})
.wait();
fileStream.close().wait();
return 0;
}
#include <cpprest/http_client.h>
#include <iostream>
using namespace web;
using namespace web::http;
using namespace web::http::client;
int main() {
http_client client(U("https://jsonplaceholder.typicode.com"));
// 链式异步请求
client.request(methods::GET, U("/users/1"))
.then([](http_response response) {
return response.extract_json();
})
.then([&client](json::value userJson) {
// 获取第一个用户的 ID
utility::string_t userId = userJson.at(U("id")).as_string();
// 使用第一个用户的 ID 获取该用户的帖子
utility::string_t postsPath = U("/posts?userId=") + userId;
return client.request(methods::GET, postsPath);
})
.then([](http_response response) {
return response.extract_json();
})
.then([](json::value postsJson) {
// 打印所有帖子的标题
if (postsJson.is_array()) {
for (const auto& post : postsJson.as_array()) {
utility::string_t title = post.at(U("title")).as_string();
std::wcout << L"Title: " << title << std::endl;
}
}
})
.wait();
return 0;
}
#include <cpprest/http_client.h>
#include <cpprest/json.h>
#include <string>
#include <memory>
using namespace web;
using namespace web::http;
using namespace web::http::client;
class ApiClient {
private:
http_client client_;
utility::string_t base_url_;
public:
ApiClient(const utility::string_t& baseUrl)
: client_(baseUrl), base_url_(baseUrl) {}
// GET 请求
pplx::task<json::value> get(const utility::string_t& path) {
return client_.request(methods::GET, path)
.then([](http_response response) {
if (response.status_code() != status_codes::OK) {
throw std::runtime_error("HTTP Error");
}
return response.extract_json();
});
}
// POST 请求
pplx::task<json::value> post(
const utility::string_t& path,
const json::value& data) {
return client_.request(methods::POST, path, data)
.then([](http_response response) {
if (response.status_code() != status_codes::OK &&
response.status_code() != status_codes::Created) {
throw std::runtime_error("HTTP Error");
}
return response.extract_json();
});
}
// PUT 请求
pplx::task<json::value> put(
const utility::string_t& path,
const json::value& data) {
return client_.request(methods::PUT, path, data)
.then([](http_response response) {
if (response.status_code() != status_codes::OK) {
throw std::runtime_error("HTTP Error");
}
return response.extract_json();
});
}
// DELETE 请求
pplx::task<bool> del(const utility::string_t& path) {
return client_.request(methods::DEL, path)
.then([](http_response response) {
return response.status_code() == status_codes::OK;
});
}
};
int main() {
ApiClient api(U("https://jsonplaceholder.typicode.com"));
// 获取用户
api.get(U("/users/1"))
.then([](json::value user) {
std::wcout << L"User: " << user.serialize() << std::endl;
}).wait();
// 创建新帖子
json::value newPost;
newPost[U("title")] = json::value::string(U("My Post"));
newPost[U("body")] = json::value::string(U("Post body"));
newPost[U("userId")] = json::value::number(1);
api.post(U("/posts"), newPost)
.then([](json::value createdPost) {
std::wcout << L"Created: " << createdPost.serialize() << std::endl;
}).wait();
return 0;
}
| 类别 | 类/方法 | 说明 |
|---|---|---|
| HTTP 客户端 | http_client |
HTTP 客户端类 |
request() |
发送 HTTP 请求 | |
http_response |
HTTP 响应类 | |
extract_json() |
提取 JSON 响应 | |
| JSON 处理 | json::value |
JSON 值类 |
parse() |
解析 JSON 字符串 | |
serialize() |
序列化为字符串 | |
json::array() |
创建 JSON 数组 | |
| HTTP 方法 | methods::GET |
GET 请求 |
methods::POST |
POST 请求 | |
methods::PUT/DEL |
PUT/DELETE 请求 | |
| WebSocket | websocket_client |
WebSocket 客户端 |
websocket_listener |
WebSocket 服务端 |
.then() 方法用于链式处理异步结果。记得在主程序最后调用 .wait() 来等待异步操作完成。
utility::string_t,支持跨平台(Windows 下为 std::wstring)