This is a C++ library originally written for accessing GitHub REST API v3. It is now organized to work with any REST API.
It supports three interchangeable HTTP backends for connecting to remote API servers: Qt 6/5, libcurl and cpp-httplib. All backends expose the same IConnection API, so applications can choose the HTTP stack that best fits their existing dependencies.
std::expected.| Backend option | Public factory header | Factory function | External dependency |
|---|---|---|---|
CppRestAPI_QtBackend=ON | <cpp_restapi/create_qt_connection.hpp> | cpp_restapi::createQtConnection() | Qt Network/Core |
CppRestAPI_CurlBackend=ON | <cpp_restapi/create_curl_connection.hpp> | cpp_restapi::createCurlConnection() | libcurl |
CppRestAPI_CppHttplibBackend=ON | <cpp_restapi/create_cpp-httplib_connection.hpp> | cpp_restapi::createCppHttplibConnection() | cpp-httplib |
Typical applications enable one backend: for example, Qt applications usually use the Qt backend, while non-Qt applications can choose libcurl or cpp-httplib. Multiple backends can be enabled in one build because each backend provides its own factory function behind the same IConnection interface. This is mainly useful for examples, tests or comparing backends rather than for normal application builds. If you do enable more than one backend, all corresponding dependencies must be available to CMake.
The Qt backend uses Qt 6 by default and falls back to Qt 5 when Qt 6 is not found. Set CppRestAPI_UseQt5 CMake variable to TRUE to force Qt 5 usage when both versions are available.
This is a CMake-based project and is primarily meant to be included as a subproject.
Simply embed cpp_restapi's sources in your project, choose the HTTP backend you want to use and include the cpp_restapi project in your CMakeLists.txt like this:
Then you can link your application against cpp_restapi:
cpp_restapi::LinkHeaderPaginationStrategy is an RFC 5988 Link-header based pagination strategy with JSON-aware merging (concatenates arrays, deep-merges objects).
This is useful for REST APIs that split large list responses into pages. For example, GitHub returns only one page of issues, releases or repositories at a time and exposes the next page through the HTTP Link header. The pagination strategy lets the library follow those links and return one merged response instead of forcing each caller to repeat the same "read header, fetch next page, merge JSON" loop.
It is built by default (controlled by the CppRestAPI_JsonPagination CMake option) because the GitHub helpers use it for paginated endpoints. It adds a dependency on the jsoncpp library. To drop the jsoncpp dependency entirely, disable both JSON pagination and GitHub helpers: -DCppRestAPI_GitHub=OFF -DCppRestAPI_JsonPagination=OFF.
cpp_restapi::GitHub::ConnectionBuilder and cpp_restapi::GitHub::Request are convenience wrappers for the GitHub REST API. They are built by default (controlled by the CppRestAPI_GitHub CMake option; enabling it automatically enables CppRestAPI_JsonPagination). Disable with -DCppRestAPI_GitHub=OFF if not needed.
This example accesses The Star Wars API using the libcurl backend.
fetch() returns std::expected<std::string, HttpError> — on success the response body is available via value(), on failure the HttpError carries the HTTP status code, response body and a human-readable message.
For accessing the GitHub API it is possible to use exactly the same approach as presented above.
However, for convenience, there are also additional helpers available:
Here the connection is built with ConnectionBuilder.
The builder sets the GitHub API URL and headers automatically. When calling build(factory, args...), any backend-specific arguments are forwarded to the factory before the URL and headers. For example, the Qt factory receives the QNetworkAccessManager first. The returned std::unique_ptr<IConnection> is then moved into GitHub::Request, which owns the connection. Refer to the documentation of ConnectionBuilder for more details.
The cpp_restapi::GitHub::Request class provides accessors for the most common GitHub API requests.
See the examples directory for complete example programs.
In addition to regular REST requests, the library supports Server-Sent Events — a standard mechanism for receiving a stream of events from a server over HTTP.
SSE support is available for all three backends via IConnection::subscribe(). The method connects to an SSE endpoint, delivers parsed events through a callback and returns an ISseConnection handle. The call is non-blocking — events are received on an internal thread (or via the Qt event loop for the Qt backend). Use close() to stop. Keep the returned ISseConnection alive for as long as you want to receive events. For the Qt backend, the Qt event loop must be running.
The SseEvent struct exposes all standard SSE fields:
| Field | Type | Description |
|---|---|---|
event | std::string | Event type (from event: field, empty if not specified) |
data | std::string | Event payload (from data: field(s), joined with \n) |
id | std::string | Last event ID (from id: field) |
retry | int | Reconnection time in ms (from retry: field, -1 if N/A) |
All three backends support non-blocking HTTP requests via a callback-based API. fetch() returns immediately and delivers the result through onSuccess / onError callbacks. It also returns a CancellationToken that can be used to suppress callbacks before they fire.
For non-Qt backends (curl, cpp-httplib) callbacks run on a background std::thread. For the Qt backend, callbacks are invoked on the Qt event-loop thread.
The CancellationToken returned by async fetch() is a std::shared_ptr<std::atomic<bool>>. Setting it to true suppresses further callbacks. It does not guarantee that an already-started network request is aborted immediately:
Paginated requests can also be performed asynchronously. The merged result is delivered through a BodyCallback once all pages have been collected:
The header-only <cpp_restapi/coroutine.hpp> provides lightweight coroutine wrappers around the callback-based async API. The project requires C++23, and the coroutine helpers also require compiler support for <coroutine>.
| Type / Function | Description |
|---|---|
Detached | Fire-and-forget wrapper — starts a coroutine that runs to completion on its own. |
coFetch(conn, request) | Returns an awaitable yielding std::expected<Response, HttpError>. |
coFetch(conn, request, strategy) | Returns an awaitable yielding std::expected<std::string, HttpError> (paginated). |
Standalone builds are mostly useful when you want to run the examples or unit tests from this repository. The main integration scenario is still to include cpp_restapi as a CMake subproject.
It is possible to build this project as any other regular CMake project by invoking:
Replace CppRestAPI_CurlBackend with another backend option if you prefer Qt or cpp-httplib. At least one backend option must be enabled, otherwise configuration fails.
This repository has an optional vcpkg submodule. It is not required when you include cpp_restapi as a subproject, but it can simplify standalone builds by providing dependencies.
Please mind that vcpkg uses telemetry.
Visit https://learn.microsoft.com/vcpkg/about/privacy for more details.
If you want to use the bundled vcpkg checkout, initialize it and configure CMake with the vcpkg toolchain file:
The repository also provides vcpkg-based CMake presets in CMakePresets.json.
Examples are located in the examples directory of the project. To build them set CppRestAPI_Examples CMake variable to ON. It can be done when invoking cmake command by providing the -DCppRestAPI_Examples=ON command-line argument (see the Basic standalone build section), or by modifying the CppRestAPI_Examples entry in the CMakeCache.txt file located in the build directory of an already configured project.
Please mind that setting CppRestAPI_Examples to ON forces all backends and optional components to be used, so all backend dependencies must be available.
Unit tests are located in the tests directory of the project. To build them set CppRestAPI_Tests CMake variable to ON.
Please mind that setting CppRestAPI_Tests to ON forces all backends and optional components to be used, so all backend dependencies must be available.
Code documentation available at https://kicer86.github.io/cpp_restapi/index.html