restc-cpp: a REST client for C++ that reads like sequential code
Modern C++ REST Client library
At a glance
- What is it?
- restc-cpp is a MIT licensed C++ library that wraps boost::asio in coroutines, so HTTP calls to JSON APIs look like ordinary sequential code while running asynchronously. It suits server and tool authors who want typed JSON handling without adopting a framework or linking libcurl, and it comes with a strong defensive posture against hostile servers.
- Who is it for?
- Adopt restc-cpp when your C++ service or tool needs typed JSON requests with an asynchronous implementation that still reads as straight line code, and when you would rather depend on boost::asio than on libcurl. Do not choose it if your project is stuck on a C++11 toolchain, since it requires C++14 or newer, or if you need a mature, frequently released HTTP client, because the newest published version is 1.0.0 from 2025-02-02 even though the last push was on 2026-06-07.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 138 days ago.
- What is it written in?
- Mainly C++, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem that started the library: no free C++ HTTP client
restc-cpp began as a gap noticed in the spring of 2016, when the author was asked to implement an SDK for a REST API in several languages. For Python, Java and Ruby the object oriented implementation was trivial. For C++ there was no suitable free library, and the search did not even turn up a proper HTTP client implementation.
The alternatives were rejected on their own terms. Using QT was considered overkill for code likely to run in high performance servers, and a GUI framework conflicts with projects built on a different C++ framework. An earlier C++ REST client built on libcurl for Amazon AWS had left an unfavourable impression.
So the author wrote an HTTP client on top of boost::asio, with JSON serialization and deserialization on top of that. The library is written by Jarle Aase, a senior freelance C++ developer with roughly 30 years of experience.
The scope is deliberately narrow. The documentation says it does not solve world hunger and makes no attempts to be a C++ framework. It is designed for the single purpose of using C++ to interact with external REST API servers efficiently, although you can reuse its individual components, including the HTTP client, as a native C++ replacement for libcurl when you want non-JSON data.
Five operations, from typed objects to streamed files
The feature list is short enough to hold in your head, which is a good sign for a library that claims not to be a framework.
First, it formulates an HTTP request to a REST API server and transforms the JSON formatted payload in the reply into a native C++ object, which is the GET case. Second, it serializes a native C++ object or a container of C++ objects into a JSON payload and sends it, covering POST and PUT. Third, it formulates a request with no data serialized in either direction, which is typically a DELETE.
Fourth, it uploads a stream of data, such as a file, to an HTTP server. Fifth, it downloads a stream of data, such as a file or an array of JSON objects, from a server.
The streaming cases are the reason this is more than a JSON wrapper. A REST client that can only handle a whole document in memory is awkward for large downloads, and the library treats streams as a first class case.
The dependency list is short as well: C++14 or newer with its standard library, boost, rapidjson, gtest, and optionally OpenSSL or libressl for TLS and zlib for compression support. CMake downloads rapidjson and gtest for the project if they are not already installed, so a first build needs a network connection unless you provide them yourself.
The first request: a coroutine that looks synchronous
The headline design goal is that coroutines carry the application logic that sends data to or pulls data from REST API servers, which makes the code easy to write and understand and simplifies debugging and core dump investigation. In short, the code executes asynchronously but there are no visible callbacks or completion functions. It reads like single threaded sequential code.
Here is the raw data example, trimmed to its essential lines:
#include <iostream>
#include "restc-cpp/restc-cpp.h"
using namespace std;
using namespace restc_cpp;
void DoSomethingInteresting(Context& ctx) {
auto reply = ctx.Get("http://jsonplaceholder.typicode.com/posts/1");
auto json = reply->GetBodyAsString();
cout << "Received data: " << json << endl;
}The interesting part is what is missing. There is no callback, no future, no continuation. The Get call suspends the coroutine and resumes it when the reply arrives.
The entry point creates the client, hands the coroutine to a worker thread, and closes the client when the work is done:
int main() {
auto rest_client = RestClient::Create();
rest_client->Process(DoSomethingInteresting);
rest_client->CloseWhenReady(true);
}Process starts DoSomethingInteresting as a coroutine in a worker thread, and CloseWhenReady waits for the coroutine to finish before closing the client. If you want to see a fuller version, the documentation points at a separate modern async C++ example project.
JSON to struct mapping without reflection
C++ has no reflection, so a library that maps JSON onto your own types has to be told the mapping. The documentation is explicit about this and shows a plain struct that mirrors the JSON entries received from the sample endpoint, with int userId, int id, string title and string body members.
The example then uses boost::fusion adaptation and boost::lexical_cast to declare how the JSON members correspond to the struct fields. That is the mechanism: boost::fusion carries the member list so the library can iterate over the struct fields at runtime, and lexical_cast handles the string conversions where a value needs to change type on the way in.
The cost is a dependency on boost::fusion in your own translation units, which is a design decision worth understanding rather than accepting silently. The library aims to make external REST APIs simple and safe to use in C++ projects while still being fast and memory efficient, and this is the price of that convenience.
One caveat on reading the documentation: the repository README is truncated partway through the mapping example, so the exact declaration syntax is not fully visible there. The full reference lives in the doc/ directory and in the generated API documentation, and that is where you should read before copying the pattern.
Defending against a server that attacks you
Security is not an afterthought in this library, and the reasoning in the introduction is worth taking seriously even if you skip the rhetorical flourishes.
The author limits third party dependencies as much as possible, with OpenSSL named as the remaining exception, described as a nest of yet undisclosed vulnerabilities but currently without an alternative that works out of the box with boost::asio. That is a candid constraint rather than a claim of safety.
More concretely, the library is designed around the idea of a malicious API server attacking the client, for example by exceeding local resources such as sending a malicious compressed package that expands to a petabyte of zeros. The design detects such problems and breaks out of them by throwing an exception as soon as possible.
That is a meaningful difference in posture. Most HTTP clients assume the server is cooperating. This one treats decompression limits, resource exhaustion and hostile payloads as expected inputs, and the failure mode is an exception rather than a hung process or a filled disk.
The documented dependencies support the same posture: zlib is optional and tied to compression support, and TLS is a build-time choice, so a deployment that does not need them does not carry them.
How this compares with libcurl and with a REST framework
Two comparisons matter here, and they are different.
Against libcurl, the difference is where the abstraction sits. libcurl is a transport library: it moves bytes, and every JSON, retry, serialisation and error policy decision is yours to write. restc-cpp moves that boundary up one level, giving you typed objects, coroutine flow control and JSON handling as part of the request. The author also uses restc-cpp's HTTP client on its own as a native C++ replacement for libcurl, which is a decent sign that the transport layer stands on its own.
Against a REST framework, the difference is scope. The documentation says explicitly that it makes no attempts to be a C++ framework, and the design goal is a focused library rather than an application architecture. That cuts both ways: there is no dependency injection container, no configuration layer and no plugin system to learn, and equally none of that machinery in your binary.
The realistic alternative for many teams is a small hand-rolled wrapper over libcurl or over an existing boost::asio client. That approach wins when the API surface is one or two endpoints, and loses when you need typed objects, streams and consistent error handling across a large client.
MIT licence and a release history that has slowed down
The licence is MIT, described in the documentation as free as in speech and free as in Free Air. There is no copyleft obligation, no attribution clause beyond keeping the licence text, and no separate commercial condition, so restc-cpp can be linked into a commercial product without a fee to negotiate.
The repository is not archived and the last push was on 2026-06-07. The published releases tell a different story about rhythm: v1.0.0 on 2025-02-02, an RC 1 on 2022-08-07 and a maintenance release v0.10.0 on 2020-10-31. So the project reached 1.0 in early 2025 and has had commits since, but the gap between the 1.0 tag and the current work is where any API changes would live, and the README does not describe the state of master relative to the 1.0.0 tag.
For an evaluator that matters. A 1.0.0 tag gives you a defined baseline to vendor and a licence that will not surprise legal, but it also means the API is not moving as quickly as the commit history suggests. Pin to the tag if you need a stable dependency, and read the release notes rather than assuming master is the supported version.
The repository itself supports several build paths, with CMakeLists.txt at the root, a conan/ directory, example projects for cmake_normal, cmake_external_project, cmdline and logip, Visual Studio batch scripts for several compiler versions and vcpkg, and container scripts for running builds in Docker. That range of entry points is itself a signal about who the library is for: people integrating it into an existing build system, not people starting from an empty directory.
Editorial conclusion
Adopt restc-cpp when your C++ service or tool needs typed JSON requests with an asynchronous implementation that still reads as straight line code, and when you would rather depend on boost::asio than on libcurl. Do not choose it if your project is stuck on a C++11 toolchain, since it requires C++14 or newer, or if you need a mature, frequently released HTTP client, because the newest published version is 1.0.0 from 2025-02-02 even though the last push was on 2026-06-07. Before you commit, verify that your platform's boost and OpenSSL versions are supported, read the JSON to struct mapping section in full, since the repository README truncates it, and confirm that the exception handling on connection failure matches how your application reports errors.
Frequently asked questions
What is restc-cpp and what does it depend on?
It is a MIT licensed C++ REST client library built on boost::asio with JSON serialization and deserialization through rapidjson. It requires C++14 or newer and optionally uses OpenSSL or libressl for TLS and zlib for compression.
How do I make an asynchronous HTTP request with restc-cpp?
Write your logic as a coroutine taking a Context reference, call ctx.Get or the equivalent inside it, and pass the function to rest_client->Process so it runs in a worker thread. The code executes asynchronously without callbacks, and CloseWhenReady closes the client once the coroutine finishes.
How does restc-cpp convert JSON into my C++ struct?
Since C++ has no reflection, you declare the mapping yourself, using boost::fusion adaptation of your struct together with boost::lexical_cast for value conversion. The repository README shows the start of that example with a Post struct matching the sample JSON endpoint.
How does restc-cpp handle a malicious or misbehaving server?
The library is designed to detect cases where a server tries to exhaust local resources, for example by sending a compressed package that expands enormously, and to break out by throwing an exception as soon as possible. It also limits third party dependencies, with OpenSSL named as the remaining exception.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/jgaa-restc-cpp)Was this useful?