SiddiqSoft.restcl 2.1.0

dotnet add package SiddiqSoft.restcl --version 2.1.0
                    
NuGet\Install-Package SiddiqSoft.restcl -Version 2.1.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="SiddiqSoft.restcl" Version="2.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="SiddiqSoft.restcl" Version="2.1.0" />
                    
Directory.Packages.props
<PackageReference Include="SiddiqSoft.restcl" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add SiddiqSoft.restcl --version 2.1.0
                    
#r "nuget: SiddiqSoft.restcl, 2.1.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package SiddiqSoft.restcl@2.1.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=SiddiqSoft.restcl&version=2.1.0
                    
Install as a Cake Addin
#tool nuget:?package=SiddiqSoft.restcl&version=2.1.0
                    
Install as a Cake Tool

restcl: A Focused REST Client for Modern C++

Build Status alternate text is missing from this package README image alternate text is missing from this package README image alternate text is missing from this package README image

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

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

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

  1. Clone the repository
  2. Copy the include/siddiqsoft directory to your project
  3. Ensure your compiler supports C++23
  4. 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 libcurl
  • WinHttpRESTClient: 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-library flag for std::stop_token and std::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-devel or libcurl4-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_argument for 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_ptr for 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, @throw tags
  • 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

  1. 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.

  2. Modern C++: C++23 is required, enabling:

    • Visual Studio 2022 on Windows
    • WinHTTP library with HTTP/2 support
    • Modern language features and idioms
  3. Header-Only: Easy integration with no compilation overhead for the library itself.

  4. Native Implementations: Use platform-specific libraries for actual IO:

    • Windows: WinHTTP library
    • Unix/Linux/macOS: libcurl
  5. User-Defined Literals: Support for convenient syntax like _GET, _DELETE, etc. via the siddiqsoft::restcl_literals namespace.

  6. Instructional: Use as little code as necessary and be clear about intent.

  7. Interface-Focused: The focus is on the interface to the end user, not internal complexity.

  8. 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:

  1. Code follows the style guidelines in best_practices.md
  2. All tests pass: ctest --preset default
  3. New features include appropriate tests
  4. Documentation is updated accordingly
  5. 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:

  1. Check the best_practices.md for comprehensive guidance
  2. Review existing GitHub Issues
  3. Create a new issue with detailed information
  4. 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 Compatible and additional computed target framework versions.
native native is compatible. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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
Loading failed