curlpp
libcurlのC++ラッパーライブラリ。C++標準ライブラリ構造を活用し、例外安全性と型安全性を提供。RAII原則に基づく設計でメモリ管理を自動化。libcurlの全機能にアクセス可能でありながら、よりC++らしいインターフェースを実現。
GitHub概要
jpbarrette/curlpp
C++ wrapper around libcURL
スター1,767
ウォッチ62
フォーク372
作成日:2015年2月26日
言語:C++
ライセンス:-
トピックス
c-plus-pluscurlpplibcurltransfer
スター履歴
データ取得日時: 2025/10/22 09:55
ライブラリ
curlpp
概要
curlppは「C++用のlibcurlラッパーライブラリ」として開発された、オブジェクト指向HTTPクライアントライブラリです。「C++らしい方法でHTTP通信を行う」をコンセプトに、libcurlの強力な機能をC++の設計パターンで提供。RAII(Resource Acquisition Is Initialization)対応、型安全性、例外安全性、C++標準ライブラリとの統合など、C++開発者にとって自然で安全なHTTP通信環境を実現しています。
詳細
curlpp 2025年版は、libcurlの実績と信頼性をC++の現代的な設計パターンで活用できる成熟したラッパーライブラリです。15年以上の開発実績により、C++プロジェクトでのHTTP/HTTPS通信において高い安定性と保守性を提供。オブジェクト指向設計によりリソース管理を自動化し、型安全なAPIで実行時エラーを大幅に削減。例外ベースのエラーハンドリングとRAII対応により、メモリリークやリソースリークを防止し、企業レベルのC++アプリケーション開発に最適化されています。
主な特徴
- RAII対応: 自動的なリソース管理とクリーンアップ機能
- 型安全性: コンパイル時の型チェックによるエラー防止
- 例外安全性: C++らしい例外ベースのエラーハンドリング
- オブジェクト指向: libcurlの機能をC++クラスで抽象化
- STL統合: std::stringやstd::listとのシームレスな統合
- オプション取得: 設定済みオプション値の取得機能
メリット・デメリット
メリット
- C++の設計パターンに準拠した自然で保守性の高いコード記述
- RAII対応による自動的なリソース管理とメモリ安全性の向上
- 型安全なAPIによる実行時エラーの大幅削減
- 例外ベースのエラーハンドリングによる堅牢なエラー処理
- libcurlの全機能を活用しつつC++らしい記述が可能
- CMakeサポートとvcpkg対応による簡単なビルド環境構築
デメリット
- libcurlへの依存によるバイナリサイズの増加
- C++特有の学習コストと複雑な設定が必要な場合がある
- 小規模プロジェクトには過剰な機能性とオーバーヘッド
- デバッグ時にラッパー層が障壁となる可能性
- 最新のHTTP/3やQUICサポートがlibcurlの対応状況に依存
- Windowsでのビルド設定が他プラットフォームより複雑
参考ページ
書き方の例
インストールとビルド設定
# vcpkgを使用したインストール
vcpkg install curlpp
# GitHubからソースコード取得
git clone https://github.com/jpbarrette/curlpp.git
cd curlpp
# CMakeを使用したビルド
mkdir build && cd build
cmake ..
make
# pkg-configでコンパイラフラグ取得
pkg-config --cflags --libs curlpp
# または curlpp-config使用
curlpp-config --cflags --libs
基本的な初期化とクリーンアップ(RAII)
#include <curlpp/cURLpp.hpp>
#include <curlpp/Easy.hpp>
#include <curlpp/Options.hpp>
#include <iostream>
#include <sstream>
// RAII対応の基本パターン
int main() {
try {
// RAII: 自動的に初期化・クリーンアップ
curlpp::Cleanup cleanup;
// この範囲でcurlppを安全に使用可能
std::cout << "curlpp初期化完了" << std::endl;
} catch(const curlpp::RuntimeError& e) {
std::cerr << "実行時エラー: " << e.what() << std::endl;
return 1;
} catch(const curlpp::LogicError& e) {
std::cerr << "論理エラー: " << e.what() << std::endl;
return 1;
}
std::cout << "curlpp自動クリーンアップ完了" << std::endl;
return 0;
}
// 手動初期化・クリーンアップパターン(非推奨)
void manual_cleanup_example() {
try {
// 手動初期化(アプリケーション全体で1回のみ)
curlpp::initialize();
// HTTP通信処理
// ...
// 手動クリーンアップ(アプリケーション終了時)
curlpp::terminate();
} catch(const std::exception& e) {
std::cerr << "エラー: " << e.what() << std::endl;
curlpp::terminate(); // エラー時も必ずクリーンアップ
}
}
基本的なHTTPリクエスト(GET/POST)
#include <curlpp/cURLpp.hpp>
#include <curlpp/Easy.hpp>
#include <curlpp/Options.hpp>
#include <curlpp/Exception.hpp>
#include <iostream>
#include <sstream>
#include <string>
// 基本的なGETリクエスト
void simple_get_request() {
try {
curlpp::Cleanup cleanup;
curlpp::Easy request;
// URLの設定
request.setOpt(new curlpp::Options::Url("https://api.example.com/users"));
// ヘッダーの設定
std::list<std::string> headers;
headers.push_back("Accept: application/json");
headers.push_back("User-Agent: curlpp/1.0");
request.setOpt(new curlpp::Options::HttpHeader(headers));
// レスポンスをstd::stringstreamに書き込み
std::ostringstream response_stream;
request.setOpt(new curlpp::Options::WriteStream(&response_stream));
// リクエスト実行
request.perform();
// レスポンス取得
std::string response = response_stream.str();
std::cout << "レスポンス: " << response << std::endl;
// HTTPステータスコード取得
long response_code = curlpp::Infos::ResponseCode::get(request);
std::cout << "ステータスコード: " << response_code << std::endl;
} catch(const curlpp::RuntimeError& e) {
std::cerr << "実行時エラー: " << e.what() << std::endl;
} catch(const curlpp::LogicError& e) {
std::cerr << "論理エラー: " << e.what() << std::endl;
}
}
// POSTリクエスト(JSON送信)
void post_json_request() {
try {
curlpp::Cleanup cleanup;
curlpp::Easy request;
// URL設定
request.setOpt(new curlpp::Options::Url("https://api.example.com/users"));
// POSTデータ(JSON)
std::string json_data = R"({
"name": "田中太郎",
"email": "[email protected]",
"age": 30
})";
// POSTオプション設定
request.setOpt(new curlpp::Options::Post(true));
request.setOpt(new curlpp::Options::PostFields(json_data));
request.setOpt(new curlpp::Options::PostFieldSize(json_data.length()));
// ヘッダー設定
std::list<std::string> headers;
headers.push_back("Content-Type: application/json");
headers.push_back("Accept: application/json");
headers.push_back("Authorization: Bearer your-token");
request.setOpt(new curlpp::Options::HttpHeader(headers));
// レスポンス取得用ストリーム
std::ostringstream response_stream;
request.setOpt(new curlpp::Options::WriteStream(&response_stream));
// リクエスト実行
request.perform();
// 結果確認
long response_code = curlpp::Infos::ResponseCode::get(request);
std::string response = response_stream.str();
if (response_code == 201) {
std::cout << "ユーザー作成成功: " << response << std::endl;
} else {
std::cerr << "エラー " << response_code << ": " << response << std::endl;
}
} catch(const curlpp::RuntimeError& e) {
std::cerr << "実行時エラー: " << e.what() << std::endl;
}
}
// フォームデータPOST
void post_form_data() {
try {
curlpp::Cleanup cleanup;
curlpp::Easy request;
request.setOpt(new curlpp::Options::Url("https://api.example.com/login"));
// フォームデータ設定
std::string form_data = "username=testuser&password=secret123";
request.setOpt(new curlpp::Options::Post(true));
request.setOpt(new curlpp::Options::PostFields(form_data));
// Content-Typeヘッダー
std::list<std::string> headers;
headers.push_back("Content-Type: application/x-www-form-urlencoded");
request.setOpt(new curlpp::Options::HttpHeader(headers));
// レスポンス取得
std::ostringstream response_stream;
request.setOpt(new curlpp::Options::WriteStream(&response_stream));
request.perform();
std::cout << "ログイン結果: " << response_stream.str() << std::endl;
} catch(const curlpp::RuntimeError& e) {
std::cerr << "ログインエラー: " << e.what() << std::endl;
}
}
高度な設定(認証、SSL、プロキシ等)
#include <curlpp/cURLpp.hpp>
#include <curlpp/Easy.hpp>
#include <curlpp/Options.hpp>
#include <curlpp/Infos.hpp>
// Basic認証とSSL設定
void advanced_authentication() {
try {
curlpp::Cleanup cleanup;
curlpp::Easy request;
// URL設定
request.setOpt(new curlpp::Options::Url("https://secure-api.example.com/data"));
// Basic認証
request.setOpt(new curlpp::Options::HttpAuth(CURLAUTH_BASIC));
request.setOpt(new curlpp::Options::UserPwd("username:password"));
// SSL/TLS設定
request.setOpt(new curlpp::Options::SslVerifyPeer(true));
request.setOpt(new curlpp::Options::SslVerifyHost(2));
request.setOpt(new curlpp::Options::CaInfo("/etc/ssl/certs/ca-certificates.crt"));
// クライアント証明書
request.setOpt(new curlpp::Options::SslCert("/path/to/client.crt"));
request.setOpt(new curlpp::Options::SslKey("/path/to/client.key"));
request.setOpt(new curlpp::Options::SslKeyPasswd("cert-password"));
// タイムアウト設定
request.setOpt(new curlpp::Options::Timeout(30)); // 30秒
request.setOpt(new curlpp::Options::ConnectTimeout(10)); // 接続10秒
// User-Agentとカスタムヘッダー
request.setOpt(new curlpp::Options::UserAgent("MyApp/1.0 (curlpp)"));
std::list<std::string> headers;
headers.push_back("Accept: application/json");
headers.push_back("X-API-Version: v2");
headers.push_back("X-Request-ID: req-12345");
request.setOpt(new curlpp::Options::HttpHeader(headers));
// レスポンス取得
std::ostringstream response_stream;
request.setOpt(new curlpp::Options::WriteStream(&response_stream));
request.perform();
// 接続情報取得
std::string effective_url = curlpp::Infos::EffectiveUrl::get(request);
long response_code = curlpp::Infos::ResponseCode::get(request);
double total_time = curlpp::Infos::TotalTime::get(request);
std::cout << "有効URL: " << effective_url << std::endl;
std::cout << "ステータス: " << response_code << std::endl;
std::cout << "総時間: " << total_time << "秒" << std::endl;
std::cout << "レスポンス: " << response_stream.str() << std::endl;
} catch(const curlpp::RuntimeError& e) {
std::cerr << "実行時エラー: " << e.what() << std::endl;
}
}
// プロキシ設定とCookie管理
void proxy_and_cookies() {
try {
curlpp::Cleanup cleanup;
curlpp::Easy request;
request.setOpt(new curlpp::Options::Url("https://api.example.com/user-data"));
// プロキシ設定
request.setOpt(new curlpp::Options::Proxy("http://proxy.example.com:8080"));
request.setOpt(new curlpp::Options::ProxyUserPwd("proxy_user:proxy_pass"));
request.setOpt(new curlpp::Options::ProxyType(CURLPROXY_HTTP));
// Cookie設定
request.setOpt(new curlpp::Options::Cookie("session_id=abc123; user_pref=dark_mode"));
request.setOpt(new curlpp::Options::CookieJar("/tmp/cookies.txt")); // Cookie保存
request.setOpt(new curlpp::Options::CookieFile("/tmp/cookies.txt")); // Cookie読み込み
// リダイレクト設定
request.setOpt(new curlpp::Options::FollowLocation(true));
request.setOpt(new curlpp::Options::MaxRedirs(5));
// デバッグ情報有効化
request.setOpt(new curlpp::Options::Verbose(true));
// レスポンス取得
std::ostringstream response_stream;
request.setOpt(new curlpp::Options::WriteStream(&response_stream));
request.perform();
std::cout << "プロキシ経由でデータ取得完了" << std::endl;
std::cout << response_stream.str() << std::endl;
} catch(const curlpp::RuntimeError& e) {
std::cerr << "プロキシエラー: " << e.what() << std::endl;
}
}
// ファイルアップロード
void file_upload() {
try {
curlpp::Cleanup cleanup;
curlpp::Easy request;
request.setOpt(new curlpp::Options::Url("https://api.example.com/upload"));
// アップロードファイル設定
std::ifstream file("/path/to/upload/file.txt", std::ios::binary);
if (!file.is_open()) {
throw std::runtime_error("ファイルが開けません");
}
// ファイルサイズ取得
file.seekg(0, std::ios::end);
long file_size = file.tellg();
file.seekg(0, std::ios::beg);
// PUTリクエスト設定
request.setOpt(new curlpp::Options::Upload(true));
request.setOpt(new curlpp::Options::ReadStream(&file));
request.setOpt(new curlpp::Options::InFileSize(file_size));
// ヘッダー設定
std::list<std::string> headers;
headers.push_back("Content-Type: application/octet-stream");
headers.push_back("Authorization: Bearer your-token");
request.setOpt(new curlpp::Options::HttpHeader(headers));
// プログレス表示設定
request.setOpt(new curlpp::Options::NoProgress(false));
request.perform();
long response_code = curlpp::Infos::ResponseCode::get(request);
std::cout << "アップロード完了: " << response_code << std::endl;
} catch(const curlpp::RuntimeError& e) {
std::cerr << "アップロードエラー: " << e.what() << std::endl;
} catch(const std::exception& e) {
std::cerr << "ファイルエラー: " << e.what() << std::endl;
}
}
エラーハンドリングとデバッグ
#include <curlpp/cURLpp.hpp>
#include <curlpp/Easy.hpp>
#include <curlpp/Options.hpp>
#include <curlpp/Exception.hpp>
// 包括的なエラーハンドリング
class HttpClient {
private:
curlpp::Cleanup cleanup_;
public:
struct Response {
long status_code;
std::string body;
std::string error_message;
bool success;
double total_time;
};
Response safe_request(const std::string& url,
const std::string& method = "GET",
const std::string& data = "",
const std::list<std::string>& headers = {}) {
Response result;
result.success = false;
try {
curlpp::Easy request;
// 基本設定
request.setOpt(new curlpp::Options::Url(url));
request.setOpt(new curlpp::Options::Timeout(30));
request.setOpt(new curlpp::Options::ConnectTimeout(10));
request.setOpt(new curlpp::Options::FollowLocation(true));
request.setOpt(new curlpp::Options::MaxRedirs(3));
// SSL設定
request.setOpt(new curlpp::Options::SslVerifyPeer(true));
request.setOpt(new curlpp::Options::SslVerifyHost(2));
// メソッド設定
if (method == "POST") {
request.setOpt(new curlpp::Options::Post(true));
if (!data.empty()) {
request.setOpt(new curlpp::Options::PostFields(data));
}
} else if (method == "PUT") {
request.setOpt(new curlpp::Options::CustomRequest("PUT"));
if (!data.empty()) {
request.setOpt(new curlpp::Options::PostFields(data));
}
} else if (method == "DELETE") {
request.setOpt(new curlpp::Options::CustomRequest("DELETE"));
}
// ヘッダー設定
if (!headers.empty()) {
request.setOpt(new curlpp::Options::HttpHeader(headers));
}
// レスポンス取得設定
std::ostringstream response_stream;
request.setOpt(new curlpp::Options::WriteStream(&response_stream));
// リクエスト実行
request.perform();
// 結果取得
result.status_code = curlpp::Infos::ResponseCode::get(request);
result.body = response_stream.str();
result.total_time = curlpp::Infos::TotalTime::get(request);
result.success = (result.status_code >= 200 && result.status_code < 300);
if (!result.success) {
result.error_message = "HTTP error: " + std::to_string(result.status_code);
}
} catch(const curlpp::LibcurlRuntimeError& e) {
result.error_message = "libcurl実行時エラー: " + std::string(e.what());
std::cerr << "libcurlエラーコード: " << e.whatCode() << std::endl;
} catch(const curlpp::RuntimeError& e) {
result.error_message = "curlpp実行時エラー: " + std::string(e.what());
} catch(const curlpp::LogicError& e) {
result.error_message = "curlpp論理エラー: " + std::string(e.what());
} catch(const std::exception& e) {
result.error_message = "予期しないエラー: " + std::string(e.what());
}
return result;
}
// リトライ機能付きリクエスト
Response request_with_retry(const std::string& url,
int max_retries = 3,
int backoff_ms = 1000) {
Response result;
for (int attempt = 0; attempt <= max_retries; ++attempt) {
result = safe_request(url);
if (result.success) {
if (attempt > 0) {
std::cout << "試行 " << (attempt + 1) << " で成功" << std::endl;
}
break;
}
if (attempt < max_retries) {
std::cerr << "試行 " << (attempt + 1) << " 失敗: "
<< result.error_message << std::endl;
std::cerr << backoff_ms * (attempt + 1) << "ms後に再試行..." << std::endl;
std::this_thread::sleep_for(
std::chrono::milliseconds(backoff_ms * (attempt + 1))
);
}
}
return result;
}
};
// 使用例
void error_handling_example() {
HttpClient client;
// 基本リクエスト
auto response = client.safe_request("https://api.example.com/users");
if (response.success) {
std::cout << "成功 (" << response.status_code << "): "
<< response.body << std::endl;
std::cout << "実行時間: " << response.total_time << "秒" << std::endl;
} else {
std::cerr << "失敗: " << response.error_message << std::endl;
}
// リトライ付きリクエスト
auto retry_response = client.request_with_retry(
"https://unstable-api.example.com/data",
3, // 最大3回試行
500 // 500ms間隔
);
if (retry_response.success) {
std::cout << "リトライで成功" << std::endl;
} else {
std::cerr << "最終的に失敗: " << retry_response.error_message << std::endl;
}
}
// デバッグ用詳細ログ
void debug_request() {
try {
curlpp::Cleanup cleanup;
curlpp::Easy request;
request.setOpt(new curlpp::Options::Url("https://httpbin.org/json"));
// 詳細ログ有効化
request.setOpt(new curlpp::Options::Verbose(true));
// ヘッダー情報も取得
std::ostringstream header_stream;
request.setOpt(new curlpp::Options::HeaderFunction(
curlpp::Types::WriteFunctionFunctor(&header_stream)
));
std::ostringstream response_stream;
request.setOpt(new curlpp::Options::WriteStream(&response_stream));
request.perform();
// 詳細情報表示
std::cout << "=== ヘッダー情報 ===" << std::endl;
std::cout << header_stream.str() << std::endl;
std::cout << "=== レスポンス ===" << std::endl;
std::cout << response_stream.str() << std::endl;
// パフォーマンス情報
double name_lookup = curlpp::Infos::NameLookupTime::get(request);
double connect_time = curlpp::Infos::ConnectTime::get(request);
double total_time = curlpp::Infos::TotalTime::get(request);
std::cout << "=== パフォーマンス ===" << std::endl;
std::cout << "DNS解決時間: " << name_lookup << "秒" << std::endl;
std::cout << "接続時間: " << connect_time << "秒" << std::endl;
std::cout << "総時間: " << total_time << "秒" << std::endl;
} catch(const curlpp::RuntimeError& e) {
std::cerr << "デバッグ実行エラー: " << e.what() << std::endl;
}
}
実用的なクラス設計とマルチスレッド対応
#include <curlpp/cURLpp.hpp>
#include <curlpp/Easy.hpp>
#include <curlpp/Options.hpp>
#include <thread>
#include <future>
#include <vector>
#include <mutex>
// スレッドセーフなHTTPクライアント
class ThreadSafeHttpClient {
private:
static std::once_flag init_flag_;
static bool initialized_;
// グローバル初期化(1回のみ)
static void initialize_once() {
std::call_once(init_flag_, []() {
curlpp::initialize();
initialized_ = true;
std::atexit(cleanup_global);
});
}
static void cleanup_global() {
if (initialized_) {
curlpp::terminate();
initialized_ = false;
}
}
public:
struct RequestConfig {
std::string url;
std::string method = "GET";
std::string body;
std::list<std::string> headers;
int timeout = 30;
bool follow_redirects = true;
};
struct Response {
long status_code = 0;
std::string body;
std::map<std::string, std::string> headers;
double total_time = 0.0;
bool success = false;
std::string error;
};
ThreadSafeHttpClient() {
initialize_once();
}
// 同期リクエスト
Response execute(const RequestConfig& config) {
Response response;
try {
curlpp::Easy request;
// 基本設定
request.setOpt(new curlpp::Options::Url(config.url));
request.setOpt(new curlpp::Options::Timeout(config.timeout));
request.setOpt(new curlpp::Options::FollowLocation(config.follow_redirects));
// メソッド設定
if (config.method == "POST") {
request.setOpt(new curlpp::Options::Post(true));
if (!config.body.empty()) {
request.setOpt(new curlpp::Options::PostFields(config.body));
}
} else if (config.method == "PUT") {
request.setOpt(new curlpp::Options::CustomRequest("PUT"));
if (!config.body.empty()) {
request.setOpt(new curlpp::Options::PostFields(config.body));
}
} else if (config.method == "DELETE") {
request.setOpt(new curlpp::Options::CustomRequest("DELETE"));
}
// ヘッダー設定
if (!config.headers.empty()) {
request.setOpt(new curlpp::Options::HttpHeader(config.headers));
}
// レスポンス取得
std::ostringstream body_stream;
request.setOpt(new curlpp::Options::WriteStream(&body_stream));
std::ostringstream header_stream;
request.setOpt(new curlpp::Options::HeaderFunction(
curlpp::Types::WriteFunctionFunctor(&header_stream)
));
// リクエスト実行
request.perform();
// 結果設定
response.status_code = curlpp::Infos::ResponseCode::get(request);
response.body = body_stream.str();
response.total_time = curlpp::Infos::TotalTime::get(request);
response.success = (response.status_code >= 200 && response.status_code < 300);
// ヘッダーパース(簡易版)
std::string header_text = header_stream.str();
std::istringstream header_lines(header_text);
std::string line;
while (std::getline(header_lines, line)) {
auto colon_pos = line.find(':');
if (colon_pos != std::string::npos) {
std::string key = line.substr(0, colon_pos);
std::string value = line.substr(colon_pos + 1);
// 空白除去
value.erase(0, value.find_first_not_of(" \t"));
value.erase(value.find_last_not_of(" \t\r\n") + 1);
response.headers[key] = value;
}
}
} catch(const curlpp::RuntimeError& e) {
response.error = "curlpp runtime error: " + std::string(e.what());
} catch(const std::exception& e) {
response.error = "error: " + std::string(e.what());
}
return response;
}
// 非同期リクエスト
std::future<Response> execute_async(const RequestConfig& config) {
return std::async(std::launch::async, [this, config]() {
return this->execute(config);
});
}
// 並列リクエスト
std::vector<Response> execute_parallel(const std::vector<RequestConfig>& configs) {
std::vector<std::future<Response>> futures;
// 全リクエストを非同期で開始
for (const auto& config : configs) {
futures.push_back(execute_async(config));
}
// 結果を収集
std::vector<Response> responses;
for (auto& future : futures) {
responses.push_back(future.get());
}
return responses;
}
};
// 静的メンバー初期化
std::once_flag ThreadSafeHttpClient::init_flag_;
bool ThreadSafeHttpClient::initialized_ = false;
// RESTfulAPIクライアント
class RestApiClient {
private:
ThreadSafeHttpClient http_client_;
std::string base_url_;
std::list<std::string> default_headers_;
public:
RestApiClient(const std::string& base_url, const std::string& auth_token = "")
: base_url_(base_url) {
// デフォルトヘッダー設定
default_headers_.push_back("Content-Type: application/json");
default_headers_.push_back("Accept: application/json");
if (!auth_token.empty()) {
default_headers_.push_back("Authorization: Bearer " + auth_token);
}
}
ThreadSafeHttpClient::Response get(const std::string& endpoint) {
ThreadSafeHttpClient::RequestConfig config;
config.url = base_url_ + endpoint;
config.method = "GET";
config.headers = default_headers_;
return http_client_.execute(config);
}
ThreadSafeHttpClient::Response post(const std::string& endpoint, const std::string& json_data) {
ThreadSafeHttpClient::RequestConfig config;
config.url = base_url_ + endpoint;
config.method = "POST";
config.body = json_data;
config.headers = default_headers_;
return http_client_.execute(config);
}
ThreadSafeHttpClient::Response put(const std::string& endpoint, const std::string& json_data) {
ThreadSafeHttpClient::RequestConfig config;
config.url = base_url_ + endpoint;
config.method = "PUT";
config.body = json_data;
config.headers = default_headers_;
return http_client_.execute(config);
}
ThreadSafeHttpClient::Response del(const std::string& endpoint) {
ThreadSafeHttpClient::RequestConfig config;
config.url = base_url_ + endpoint;
config.method = "DELETE";
config.headers = default_headers_;
return http_client_.execute(config);
}
};
// 使用例
void practical_usage_example() {
try {
// APIクライアント作成
RestApiClient api("https://api.example.com/v1", "your-jwt-token");
// ユーザー一覧取得
auto users_response = api.get("/users");
if (users_response.success) {
std::cout << "ユーザー一覧: " << users_response.body << std::endl;
}
// 新規ユーザー作成
std::string user_json = R"({
"name": "田中太郎",
"email": "[email protected]",
"department": "engineering"
})";
auto create_response = api.post("/users", user_json);
if (create_response.success) {
std::cout << "ユーザー作成成功: " << create_response.body << std::endl;
} else {
std::cerr << "作成失敗: " << create_response.error << std::endl;
}
// 並列リクエスト例
ThreadSafeHttpClient client;
std::vector<ThreadSafeHttpClient::RequestConfig> configs = {
{"https://api.example.com/users", "GET"},
{"https://api.example.com/posts", "GET"},
{"https://api.example.com/comments", "GET"}
};
auto responses = client.execute_parallel(configs);
for (size_t i = 0; i < responses.size(); ++i) {
std::cout << "リクエスト " << (i+1) << ": ";
if (responses[i].success) {
std::cout << "成功 (" << responses[i].status_code << ")" << std::endl;
} else {
std::cout << "失敗 - " << responses[i].error << std::endl;
}
}
} catch(const std::exception& e) {
std::cerr << "予期しないエラー: " << e.what() << std::endl;
}
}
int main() {
practical_usage_example();
return 0;
}