SiddiqSoft.restcl
2.1.0
dotnet add package SiddiqSoft.restcl --version 2.1.0
NuGet\Install-Package SiddiqSoft.restcl -Version 2.1.0
<PackageReference Include="SiddiqSoft.restcl" Version="2.1.0" />
<PackageVersion Include="SiddiqSoft.restcl" Version="2.1.0" />
<PackageReference Include="SiddiqSoft.restcl" />
paket add SiddiqSoft.restcl --version 2.1.0
#r "nuget: SiddiqSoft.restcl, 2.1.0"
#:package SiddiqSoft.restcl@2.1.0
#addin nuget:?package=SiddiqSoft.restcl&version=2.1.0
#tool nuget:?package=SiddiqSoft.restcl&version=2.1.0
restcl: A Focused REST Client for Modern C++
Overview
restcl is a header-only REST client library for modern C++23 that provides a clean, JSON-first API for interacting with RESTful servers. It abstracts platform-specific HTTP implementations (WinHTTP on Windows, libcurl on Unix/Linux/macOS) behind a unified, modern C++ interface. The library prioritizes simplicity and instructional clarity over performance, making it ideal for applications that need straightforward REST communication without the complexity of lower-level HTTP libraries.
Key Features
- JSON-First API: JSON is a first-class citizen in the API design
- Modern C++23: Leverages C++23 features including
std::expected,std::format, and user-defined literals - Header-Only: Easy integration with no compilation overhead
- Cross-Platform: Native implementations for Windows (WinHTTP) and Unix/Linux/macOS (libcurl)
- User-Defined Literals: Convenient syntax like
"https://api.example.com"_GET - Async Support: Non-blocking async operations with callback-based responses
- Error Handling: Uses
std::expected<T, E>for robust error handling without exceptions for IO operations - Comprehensive Testing: Extensive test suite with unit, integration, and stress tests
- Type-Safe: Template-based design with support for custom character types
Table of Contents
- Quick Start
- Installation
- Usage Examples
- Architecture
- Dependencies
- Building
- Testing
- Best Practices
- Contributing
- License
Quick Start
Basic GET Request
#include <siddiqsoft/restcl.hpp>
using namespace siddiqsoft::restcl_literals;
int main() {
auto client = siddiqsoft::GetRESTClient();
auto request = "https://api.example.com/users"_GET;
auto response = client->send(request);
if (response) {
std::cout << "Status: " << response->statusCode() << "\n";
std::cout << "Body: " << response->body() << "\n";
} else {
std::cerr << "Error: " << response.error() << "\n";
}
return 0;
}
POST Request with JSON
#include <siddiqsoft/restcl.hpp>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using namespace siddiqsoft::restcl_literals;
int main() {
auto client = siddiqsoft::GetRESTClient();
auto request = "https://api.example.com/users"_POST;
json payload = {
{"name", "John Doe"},
{"email", "john@example.com"}
};
request.setBody(payload.dump());
request.setHeader("Content-Type", "application/json");
auto response = client->send(request);
if (response) {
auto result = json::parse(response->body());
std::cout << "Created user: " << result["id"] << "\n";
}
return 0;
}
Async Request with Callback
#include <siddiqsoft/restcl.hpp>
#include <atomic>
using namespace siddiqsoft::restcl_literals;
int main() {
auto client = siddiqsoft::GetRESTClient();
std::atomic<bool> done{false};
auto request = "https://api.example.com/data"_GET;
client->sendAsync(request, [&done](const auto& req, auto response) {
if (response) {
std::cout << "Async response: " << response->statusCode() << "\n";
} else {
std::cerr << "Async error: " << response.error() << "\n";
}
done = true;
});
// Wait for async operation to complete
while (!done) {
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
return 0;
}
Installation
Via NuGet (Windows)
nuget install SiddiqSoft.restcl
Via CMake (Recommended)
Add to your CMakeLists.txt:
include(FetchContent)
FetchContent_Declare(restcl
GIT_REPOSITORY https://github.com/SiddiqSoft/restcl.git
GIT_TAG main
)
FetchContent_MakeAvailable(restcl)
target_link_libraries(your_target PRIVATE restcl::restcl)
Manual Integration
- Clone the repository
- Copy the
include/siddiqsoftdirectory to your project - Ensure your compiler supports C++23
- Link against platform-specific libraries:
- Windows: WinHTTP (included in Windows SDK)
- Unix/Linux/macOS: libcurl
Usage Examples
Supported HTTP Methods
The library provides user-defined literals for all standard HTTP methods:
using namespace siddiqsoft::restcl_literals;
auto get_req = "https://api.example.com/resource"_GET;
auto post_req = "https://api.example.com/resource"_POST;
auto put_req = "https://api.example.com/resource/123"_PUT;
auto delete_req = "https://api.example.com/resource/123"_DELETE;
auto patch_req = "https://api.example.com/resource/123"_PATCH;
auto head_req = "https://api.example.com/resource"_HEAD;
auto options_req = "https://api.example.com/resource"_OPTIONS;
Working with Headers
auto request = "https://api.example.com/data"_GET;
request.setHeader("Authorization", "Bearer token123");
request.setHeader("Accept", "application/json");
request.setHeader("User-Agent", "MyApp/1.0");
// Access headers
auto auth = request.getHeader("Authorization");
Request Configuration
auto client = siddiqsoft::GetRESTClient({
{"connectTimeout", 3000}, // Connection timeout in ms
{"timeout", 5000}, // Overall timeout in ms
{"userAgent", "MyApp/1.0"}, // Custom user agent
{"trace", false} // Enable/disable tracing
});
Error Handling
The library uses std::expected<T, E> for error handling:
auto response = client->send(request);
if (response) {
// Success path
std::cout << "Status: " << response->statusCode() << "\n";
} else {
// Error path
int error_code = response.error();
std::cerr << "Request failed with error: " << error_code << "\n";
}
JSON Integration
#include <nlohmann/json.hpp>
using json = nlohmann::json;
// Parse response as JSON
auto response = client->send(request);
if (response && response->statusCode() == 200) {
auto data = json::parse(response->body());
// Access JSON data
std::string name = data["name"];
int age = data["age"];
}
API Reference
For comprehensive API documentation, see API.md.
Architecture
Project Structure
restcl/
├── include/siddiqsoft/
│ ├── restcl.hpp # Main public header (platform dispatcher)
│ └── private/
│ ├── basic_restclient.hpp # Abstract base class for REST clients
│ ├── http_frame.hpp # Base class for HTTP requests/responses
│ ├── rest_request.hpp # REST request model with literals support
│ ├── rest_response.hpp # REST response model with parsing
│ ├── restcl_unix.hpp # libcurl-based implementation
│ └── restcl_win.hpp # WinHTTP-based implementation
├── tests/ # Comprehensive test suite
│ ├── test_validation.cpp # Validation and error handling tests
│ ├── test_restcl.cpp # Core functionality tests
│ ├── test_serializers.cpp # JSON serialization tests
│ ├── test_postbin.cpp # Integration tests with external services
│ ├── test_libcurl_helpers.cpp # Unix/Linux-specific tests
│ └── test_mock_and_coverage.cpp # Mock and coverage tests
├── docs/ # Doxygen documentation
├── pack/ # NuGet packaging and build helpers
├── CMakeLists.txt # Main CMake configuration
├── CMakePresets.json # CMake presets for builds
├── .clang-format # Code formatting rules
├── .clang-tidy # Static analysis configuration
├── best_practices.md # Comprehensive development guidelines
└── azure-pipelines.yml # CI/CD pipeline
Core Components
basic_restclient<CharT>
Abstract interface defining the REST client contract with send() and sendAsync() methods.
http_frame<CharT>
Base class providing common HTTP functionality including headers, content, and protocol version management.
rest_request<CharT>
Extends http_frame with request-specific encoding and HTTP method support.
rest_response<CharT>
Extends http_frame with response parsing, status codes, and reason phrases.
Platform-Specific Implementations
HttpRESTClient: Unix/Linux/macOS implementation using libcurlWinHttpRESTClient: Windows implementation using WinHTTP with HTTP/2 support
Dependencies
Core Dependencies
| Dependency | Version | Purpose |
|---|---|---|
| nlohmann/json | v3.12.0 | JSON parsing and serialization |
| SplitUri | v3.0.0 | URI parsing and manipulation |
| AzureCppUtils | v3.2.5 | Azure-specific utilities |
| string2map | v2.5.0 | String-to-map conversion utilities |
| RunOnEnd | v1.4.2 | RAII-based cleanup utilities |
| asynchrony | v2.1.1 | Asynchronous operation helpers |
| acw32h | v2.7.4 | Windows-specific C++ wrapper for WinHTTP (Windows only) |
| CURL | v8.7+ | libcurl for Unix/Linux/macOS |
Build Tools
| Tool | Version | Purpose |
|---|---|---|
| CMake | v3.29+ | Build system |
| Clang-Format | Latest | Code formatting |
| Clang-Tidy | Latest | Static analysis |
| Google Test | v1.17.0 | Testing framework |
| Doxygen | Latest | Documentation generation |
Compiler Requirements
- C++23 Standard: Required
- Visual Studio 2022: For Windows builds (MSVC)
- Clang 18+ or GCC 13+: For Unix/Linux builds
- Clang on macOS: With
-fexperimental-libraryflag forstd::stop_tokenandstd::jthread
Building
Prerequisites
- CMake 3.29 or later
- C++23 compatible compiler
- Platform-specific dependencies:
- Windows: Windows SDK (includes WinHTTP)
- Linux: libcurl development libraries (
libcurl-develorlibcurl4-openssl-dev) - macOS: libcurl (usually pre-installed)
Build Steps
# Clone the repository
git clone https://github.com/SiddiqSoft/restcl.git
cd restcl
# Configure with CMake
cmake --preset default -DRESTCL_BUILD_TESTS=ON
# Build the project
cmake --build --preset default
# Run tests (optional)
ctest --preset default
CMake Options
RESTCL_BUILD_TESTS: Enable/disable test suite (default: OFF)CMAKE_BUILD_TYPE: Debug or Release (default: Release)
Testing
The library includes a comprehensive test suite covering:
Test Categories
- Unit Tests (
test_validation.cpp): Request/response validation, error handling, edge cases - Core Tests (
test_restcl.cpp): Core functionality, async operations, multiple HTTP verbs, stress tests - Serialization Tests (
test_serializers.cpp): JSON serialization and deserialization - Integration Tests (
test_postbin.cpp): Real HTTP calls to external services - Platform-Specific Tests (
test_libcurl_helpers.cpp): Unix/Linux-specific libcurl tests - Mock Tests (
test_mock_and_coverage.cpp): Mock objects and code coverage validation
Running Tests
# Build with tests enabled
cmake --preset default -DRESTCL_BUILD_TESTS=ON
cmake --build --preset default
# Run all tests
ctest --preset default
# Run specific test
ctest --preset default -R test_restcl
Test Coverage
- ASAN (Address Sanitizer) and leak detection enabled for Debug builds on Linux/Clang
- Code coverage instrumentation enabled for Debug builds
- Tests pass on both Windows (MSVC) and Unix/Linux (Clang/GCC)
Best Practices
For comprehensive guidance on code style, testing strategies, common patterns, and best practices when working with or extending this library, see best_practices.md.
Key Principles
Error Handling
- Use
std::expected<T, E>for IO operations instead of exceptions - Throw
std::invalid_argumentfor validation errors - Different platforms return different error codes:
- Windows: WinHTTP error codes (12001, 12002, 12029, etc.)
- Unix/Linux: POSIX error codes (ECONNRESET, etc.)
Modern C++ Features
- Leverage C++23 features:
std::expected,std::format,std::atomic, concepts - Use move semantics extensively
- Prefer
std::shared_ptrfor shared ownership - Use
[[nodiscard]]on functions returning important values
Async Operations
- Use callbacks for async operations:
std::function<void(rest_request<>&, std::expected<rest_response<>, int>)> - Callbacks receive both request and response (or error code)
- Register global callbacks via
configure()and override per-request - Use
std::atomic<bool>with.wait()and.notify_all()for test synchronization
Code Style
- Classes: PascalCase (e.g.,
rest_request,HttpRESTClient) - Functions: camelCase (e.g.,
setMethod(),getUri()) - Constants: UPPER_SNAKE_CASE (e.g.,
HTTP_NEWLINE) - Private members: Prefix with underscore (e.g.,
_statusCode) - Namespaces: lowercase (e.g.,
siddiqsoft,restcl_literals)
Documentation
- Use Doxygen comments (
///or/**) for public APIs - Include
@brief,@param,@return,@throwtags - Comment non-obvious algorithms or platform-specific code
- Guard debug output with
#if defined(DEBUG)
Design Philosophy
Motivation
Design a library where JSON is a first-class API metaphor for interacting with RESTful servers.
Core Principles
Focused Scope: REST interactions with JSON only. This limitation allows us to simplify usage and make it feel very C++ instead of the C-like API of Win32 or LibCURL.
Modern C++: C++23 is required, enabling:
- Visual Studio 2022 on Windows
- WinHTTP library with HTTP/2 support
- Modern language features and idioms
Header-Only: Easy integration with no compilation overhead for the library itself.
Native Implementations: Use platform-specific libraries for actual IO:
- Windows: WinHTTP library
- Unix/Linux/macOS: libcurl
User-Defined Literals: Support for convenient syntax like
_GET,_DELETE, etc. via thesiddiqsoft::restcl_literalsnamespace.Instructional: Use as little code as necessary and be clear about intent.
Interface-Focused: The focus is on the interface to the end user, not internal complexity.
Simplicity Over Performance: Hide the underlying implementation and prioritize clarity.
Roadmap
- Performance optimizations
- Additional test coverage
- Extended documentation with more examples
- Support for additional content types
- Enhanced error diagnostics
Contributing
Contributions are welcome! Please ensure:
- Code follows the style guidelines in best_practices.md
- All tests pass:
ctest --preset default - New features include appropriate tests
- Documentation is updated accordingly
- Code is formatted with clang-format:
clang-format -i <file>
License
This project is licensed under the MIT License. See the LICENSE file for details.
Support
For issues, questions, or suggestions:
- Check the best_practices.md for comprehensive guidance
- Review existing GitHub Issues
- Create a new issue with detailed information
- For security concerns, please email privately
Acknowledgments
- Built with modern C++23 features
- Uses nlohmann/json for JSON handling
- Cross-platform support via WinHTTP and libcurl
- Comprehensive testing with Google Test framework
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| native | native is compatible. |
-
- nlohmann.json (>= 3.11.0)
- SiddiqSoft.acw32h (>= 2.7.0)
- SiddiqSoft.asynchrony (>= 1.8.0)
- SiddiqSoft.AzureCppUtils (>= 3.0.1)
- SiddiqSoft.SplitUri (>= 2.1.0)
- SiddiqSoft.string2map (>= 2.4.0)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on SiddiqSoft.restcl:
| Package | Downloads |
|---|---|
|
SiddiqSoft.CosmosClient
Azure Cosmos REST-API Client for Modern C++ |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2.1.0 | 37 | 5/1/2026 |
| 2.0.3 | 88 | 4/29/2026 |
| 2.0.2 | 80 | 4/28/2026 |
| 1.6.5 | 475 | 12/17/2024 |
| 1.6.4 | 421 | 12/13/2024 |
| 1.6.3 | 441 | 12/12/2024 |
| 1.6.2 | 402 | 12/7/2024 |
| 1.6.1 | 397 | 12/7/2024 |
| 1.6.0 | 382 | 12/7/2024 |
| 1.5.2.4 | 422 | 10/28/2024 |
| 1.5.2 | 413 | 10/25/2024 |
| 1.5.1 | 424 | 10/4/2024 |
| 0.10.13 | 378 | 10/2/2024 |
| 0.10.12 | 411 | 10/2/2024 |
| 0.10.11 | 404 | 10/2/2024 |
| 0.10.10 | 380 | 10/1/2024 |
| 0.10.9 | 383 | 9/28/2024 |
| 0.10.8 | 372 | 9/28/2024 |
| 0.10.7 | 737 | 12/22/2021 |
| 0.10.6 | 636 | 12/21/2021 |
Documentation at https://siddiqsoft.github.io/restcl