{"id":19142663,"url":"https://github.com/jgaa/restc-cpp","last_synced_at":"2025-05-15T08:00:23.588Z","repository":{"id":37821584,"uuid":"54464427","full_name":"jgaa/restc-cpp","owner":"jgaa","description":"Modern C++ REST Client library","archived":false,"fork":false,"pushed_at":"2025-02-02T13:52:02.000Z","size":1177,"stargazers_count":632,"open_issues_count":54,"forks_count":96,"subscribers_count":46,"default_branch":"master","last_synced_at":"2025-04-14T13:04:54.598Z","etag":null,"topics":["asio","c-plus-plus","coroutines","http-client","json","json-serialization","rest","rest-client"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jgaa.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-03-22T09:56:49.000Z","updated_at":"2025-04-07T11:01:32.000Z","dependencies_parsed_at":"2024-11-09T07:30:48.463Z","dependency_job_id":"56c90681-d7a0-4d44-9684-dc705ac6dbd5","html_url":"https://github.com/jgaa/restc-cpp","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jgaa%2Frestc-cpp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jgaa%2Frestc-cpp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jgaa%2Frestc-cpp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jgaa%2Frestc-cpp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jgaa","download_url":"https://codeload.github.com/jgaa/restc-cpp/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254301420,"owners_count":22047901,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asio","c-plus-plus","coroutines","http-client","json","json-serialization","rest","rest-client"],"created_at":"2024-11-09T07:28:01.092Z","updated_at":"2025-05-15T08:00:23.480Z","avatar_url":"https://github.com/jgaa.png","language":"C++","funding_links":[],"categories":["C++"],"sub_categories":[],"readme":"[![CI](https://github.com/jgaa/restc-cpp/actions/workflows/ci.yaml/badge.svg)](https://github.com/jgaa/restc-cpp/actions/workflows/ci.yaml)\n\n# Introduction to the restc-cpp C++ library\n\u003ci\u003eThe magic that takes the pain out of accessing JSON API's from C++ \u003c/i\u003e\n\n\u003cb\u003eWhat it does:\u003c/b\u003e\n- It formulates a HTTP request to a REST API server. Then, it transforms\n  the JSON formatted payload in the reply into a native C++ object (GET).\n- It Serialize a native C++ object or a container of C++ objects into a JSON payload\n  and send it to the REST API server (POST, PUT).\n- It formulates a HTTP request to the REST API without serializing any data in either\n  direction (typically DELETE).\n- It uploads a stream of data, like a file, to a HTTP server.\n- It downloads a stream of data, like a file or an array of JSON objects, from a HTTP server.\n\nThat's basically it. It does not solve world hunger.\nIt make no attempts to be a C++ framework.\n\nYou can use it's single components, like the powerful C++ HTTP Client to\nsend and receive non-JSON data as a native C++ replacement for libcurl.\nYou can use the template code that transforms data between C++ and JSON\nfor other purposes (for example in a REST API SERVER) - but the library\nis designed and implemented for the single purpose of using C++ to\ninteract efficiently and effortless with external REST API servers.\n\nThe library is written by Jarle (jgaa) Aase, a senior freelance C++ developer\nwith roughly 30 years of experience in software development.\n\n# Design Goals\nThe design goal of this project is to make external REST API's\nsimple and safe to use in C++ projects, but still fast and memory efficient.\n\nAnother goal was to use coroutines for the application logic that sends data to or\npulls data from the REST API servers. This makes the code easy to write\nand understand, and also simplifies debugging and investigation of core dumps.\nIn short; the code executes asynchronously, but there are no visible callbacks\nor completion functions. It looks like crystal clear,\nold fashion, single threaded sequential code (using modern C++ language).\nYou don't sacrifice code clearness to achieve massive parallelism and\nhigh performance. Coroutines was a strong motivation to write a new\nC++ HTTP Client from scratch. To see how this actually works, please see the\n [modern async cpp example](https://github.com/jgaa/modern_async_cpp_example)).\n\n\nFinally, in a world where the Internet is getting increasingly\n[dangerous](http://www.dailydot.com/layer8/bruce-schneier-internet-of-things/),\nand all kind of malicious parties, from your own government to the international Mafia\n(with Putin in Moscow and other autocrats in parliaments and as head of state all over the world - \nincluding USA, EU and Norway -, the differences is\nblurring out), search for vulnerabilities in your software stack to snoop, ddos,\nintercept and blackmail you and your customers/users - I have a strong emphasis\non security in all software projects I'm involved in. I have limited the\ndependencies on third party libraries as much as I could (I still use OpenSSL\nwhich is a snakes nest of of yet undisclosed vulnerabilities - but as of now\nthere are no alternatives that works out of the box with boost::asio).\nI have also tried to imagine any possible way a malicious API server\ncould try to attack you (by exploiting or exceeding local resources - like sending\na malicious compressed package that expands to a petabyte of zeros) and designed\nto detect any potential problems and break out of it by throwing an exception as\nsoon as possible.\n\n# Why?\nIn the spring of 2016 I was asked to implement a SDK for a REST API in\nseveral languages. For Python, Java and Ruby it was trivial to make a simple\nobject oriented implementation. When I started planning the C++ implementation of the\nSDK, I found no suitable, free libraries. I could not even find a proper HTTP Client\nimplementation(!). I could have solved the problem using QT - but i found it\noverkill to use a huge GUI framework for C++ code that are most likely to run\nin high performance servers - and that may end up in projects using some other\nC++ framework that can't coexist with QT.\n\nMany years ago I designed and implemented a C++ REST Client for an early\nversion of Amazon AWS using libcurl - and - well, I had no strong urge to repeat\nthat experience. So I spent a few weeks creating my own HTTP Client library\nusing boost::asio with JSON serialization/deserialization.\n\n# Dependencies\nRestc-cpp depends on C++14 (or newer) with its standard libraries and:\n  - boost\n  - rapidjson (CMake will download and install rapidjson for the project)\n  - gtest (CMake will download and install gtest for the project if it is not installed)\n  - openssl or libressl (If compiled with TLS support)\n  - zlib (If compiled with compression support)\n\n# License\nMIT license. It is Free. Free as in speech. Free as in Free Air.\n\n# Examples\n\n## Fetch raw data\nThe following code demonstrates how to run a simple HTTP request asynchronously,\nusing the co-routine support in boost::asio behind the scenes.\n\n\n```C++\n#include \u003ciostream\u003e\n#include \"restc-cpp/restc-cpp.h\"\n\nusing namespace std;\nusing namespace restc_cpp;\n\nvoid DoSomethingInteresting(Context\u0026 ctx) {\n    // Here we are in a co-routine, running in a worker-thread.\n\n    // Asynchronously connect to a server and fetch some data.\n    auto reply = ctx.Get(\"http://jsonplaceholder.typicode.com/posts/1\");\n\n    // Asynchronously fetch the entire data-set and return it as a string.\n    auto json = reply-\u003eGetBodyAsString();\n\n    // Just dump the data.\n    cout \u003c\u003c \"Received data: \" \u003c\u003c json \u003c\u003c endl;\n}\n\nint main() {\n    auto rest_client = RestClient::Create();\n\n    // Call DoSomethingInteresting as a co-routine in a worker-thread.\n    rest_client-\u003eProcess(DoSomethingInteresting);\n\n    // Wait for the coroutine to finish, then close the client.\n    rest_client-\u003eCloseWhenReady(true);\n}\n```\n\nAnd here is the output you could expect\n```text\nReceived data: {\n  \"userId\": 1,\n  \"id\": 1,\n  \"title\": \"sunt aut facere repellat provident occaecati excepturi optio reprehenderit\",\n  \"body\": \"quia et suscipit\\nsuscipit recusandae consequuntur expedita et cum\\nreprehenderit molestiae ut ut quas totam\\nnostrum rerum est autem sunt rem eveniet architecto\"\n}\n```\n\n\n## Fetch a C++ object from a server that serialize to JSON\n\nHere is a sightly more interesting example, using JSON\nserialization, and some modern C++ features.\n\n```C++\n#include \u003ciostream\u003e\n\n#include \u003cboost/lexical_cast.hpp\u003e\n#include \u003cboost/fusion/adapted.hpp\u003e\n\n#include \"restc-cpp/restc-cpp.h\"\n#include \"restc-cpp/RequestBuilder.h\"\n\nusing namespace std;\nusing namespace restc_cpp;\n\n// C++ structure that match the JSON entries received\n// from http://jsonplaceholder.typicode.com/posts/{id}\nstruct Post {\n    int userId = 0;\n    int id = 0;\n    string title;\n    string body;\n};\n\n// Since C++ does not (yet) offer reflection, we need to tell the library how\n// to map json members to a type. We are doing this by declaring the\n// structs/classes with BOOST_FUSION_ADAPT_STRUCT from the boost libraries.\n// This allows us to convert the C++ classes to and from JSON.\n\nBOOST_FUSION_ADAPT_STRUCT(\n    Post,\n    (int, userId)\n    (int, id)\n    (string, title)\n    (string, body)\n)\n\n// The C++ main function - the place where any adventure starts\nint main() {\n    // Create an instance of the rest client\n    auto rest_client = RestClient::Create();\n\n    // Create and instantiate a Post from data received from the server.\n    Post my_post = rest_client-\u003eProcessWithPromiseT\u003cPost\u003e([\u0026](Context\u0026 ctx) {\n        // This is a co-routine, running in a worker-thread\n\n        // Instantiate a Post structure.\n        Post post;\n\n        // Serialize it asynchronously. The asynchronously part does not really matter\n        // here, but it may if you receive huge data structures.\n        SerializeFromJson(post,\n\n            // Construct a request to the server\n            RequestBuilder(ctx)\n                .Get(\"http://jsonplaceholder.typicode.com/posts/1\")\n\n                // Add some headers for good taste\n                .Header(\"X-Client\", \"RESTC_CPP\")\n                .Header(\"X-Client-Purpose\", \"Testing\")\n\n                // Send the request\n                .Execute());\n\n        // Return the post instance trough a C++ future\u003c\u003e\n        return post;\n    })\n\n    // Get the Post instance from the future\u003c\u003e, or any C++ exception thrown\n    // within the lambda.\n    .get();\n\n    // Print the result for everyone to see.\n    cout \u003c\u003c \"Received post# \" \u003c\u003c my_post.id \u003c\u003c \", title: \" \u003c\u003c my_post.title;\n}\n```\n\nThe code above should return something like:\n```text\nReceived post# 1, title: sunt aut facere repellat provident occaecati excepturi optio reprehenderit\n```\n\nPlease refer to the [tutorial](doc/Tutorial.md) for more examples.\n\n# Features\n- High level Request Builder interface (similar to Java HTTP Clients) for convenience.\n- Low level interface to create requests.\n- All network IO operations are asynchronous trough boost::asio.\n  - Use your own asio io-services\n  - Let the library create and deal with the asio io-services\n  - Use your own worker threads\n  - Let the library create and deal with worker-threads\n- Uses C++ / boost coroutines for application logic.\n- HTTP Redirects.\n- HTTP Basic Authentication.\n- [Logging](doc/Logging.md) trough logfault, boost::log, std::clog or trough your own log macros or via a callback to whatever log framework you use.\n- Log-level for the library can be set at compile time (none, error, warn, info, debug, trace)\n- Connection Pool for fast re-use of existing server connections.\n- Compression (gzip, deflate).\n- JSON serialization to and from native C++ objects.\n  - Optional Mapping between C++ property names and JSON 'on the wire' names.\n  - Option to tag property names as read-only to filter them out when the C++ object is serialized for transfer to the server.\n  - Filters out empty C++ properties when the C++ object is serialized for transfer to the server (can be disabled).\n  - Iterator interface to received JSON lists of objects.\n  - Memory constraint on incoming objects (to limit damages from rouge or buggy REST servers).\n  - Serialization directly from std::istream to C++ object.\n- Plain or chunked outgoing HTTP payloads.\n- Several strategies for lazy data fetching in outgoing requests.\n  - Override RequestBody to let the library pull for data when required.\n  - Write directly to the outgoing DataWriter when data is required.\n  - Just provide a C++ object and let the library serialize it directly to the wire.\n- HTTP Proxy support\n- SOCKS5 Proxy support (naive implementatin for now, no support for authentication).\n\n# Current Status\nThe project has been in public BETA since April 11th 2017.\n\n# Supported compilers\nThese are the compilers that are being tested before anything is merged to the master branch.\n\n- g++ from 8 to 14\n- clang (current)\n- msvc (current)\n- Apple clang (current)\n\n# Supported C++ standards\nThese are the C++ versions that are are being tested before anything is merged to the master branch.\n\n- C++14\n- C++17\n- C++20\n \n# Supported operating systems\nThese are the operating systems where my Continues Integration (Jenkins) servers currently compiles the project and run all the tests:\n\n - Debian Testing\n - Debian Bookworm\n - Debian Bullseye\n - Debian Buster\n - Windows 10 / Microsoft Visual Studio 2022, Community version using vcpkg for dependencies\n - Ubuntu Noble (LTS)\n - Ubuntu Jammy (LTS)\n - Ubuntu Bionic (LTS)\n - Fedora (latest)\n - MacOS (latest)\n\nThe Jenkins setup is [here](ci/jenkins).\n\nI currently use my own CI infrastructure running on my own hardware. I use Jenkins on a VM with Debian Bookworm, and three slaves for Docker on Linux VM's, one slave running on a VM with Microsoft Windows 10 Pro. Using Docker to build with different Linux distributions gives me flexibility. It also immediately catches mistakes that break the build or test(s) on a specific Linux distribution or platform. Using my own infrastructure improves the security, as I don't share any credentials with 3rd party services or allow external access into my LAN. \n\nGithub Actions can not compile for various Linux variants (at least not on the free plan for Open Source projects), \nand it can not run multiple docker-containers (or even *any* containers for Windows or MacOS builds) to allow integration testing.\nI have configured it for this repository anyway, because it's automation setup is different than the Jenkins setup,\nwhich have helped identifying some issues with the projects cmake files.\n\n# Blog-posts about the project:\n  - [About version 0.90](https://lastviking.eu/restc_cpp_90.html)\n  - [restc-cpp tags on The Last Viking's Nest](https://lastviking.eu/_tags/restc-cpp.html)\n\n# Similar projects\n  - [RESTinCurl](https://github.com/jgaa/RESTinCurl) by me. Aimed at mobile applications, IoT and projects that already link with libcurl.\n  - [Boost.Beast](https://github.com/boostorg/beast) by Vinnie Falco. When you like to write many lines of code...\n\n  **Json serialization only**\n  - [Boost.Json](https://www.boost.org/doc/libs/1_83_0/libs/json/doc/html/index.html)\n  - [JSON for Modern C++](https://nlohmann.github.io/json/) by Niels Lohmann. My favorite json library, when I need to more than just static serialization.\n  - [json11 - tiny JSON library for C++11, providing JSON parsing and serialization](https://github.com/dropbox/json11)\n\n# More information\n- [Getting started](doc/GettingStarted.md)\n- [Tutorial](doc/Tutorial.md)\n- [Build for Linux](https://github.com/jgaa/restc-cpp/wiki/Building-under-Linux)\n- [Build for macOS](https://github.com/jgaa/restc-cpp/wiki/Building-under-macOS)\n- [Build for Windows](https://github.com/jgaa/restc-cpp/wiki/Building-under-Windows)\n- [Running the tests](doc/RunningTheTests.md)\n- [Planned work](https://github.com/jgaa/restc-cpp/wiki)\n- [How to link your program with restc-cpp from the command-line](https://github.com/jgaa/restc-cpp/tree/master/examples/cmdline)\n- [How to use cmake to find and link with restc-cpp from your project](https://github.com/jgaa/restc-cpp/tree/master/examples/cmake_normal)\n- [How to use restc-cpp as an external cmake module from your project](https://github.com/jgaa/restc-cpp/tree/master/examples/cmake_external_project)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjgaa%2Frestc-cpp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjgaa%2Frestc-cpp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjgaa%2Frestc-cpp/lists"}