Using Cpr for making http requests - C++

I came across this module (CPR) a couple of days back, as I had to create a prototype REST client for something in C++.

CPR or C++ Requests is a simple wrapper around libcrul inspired by Python Requests.

Python requests make it very easy to make http requests. The process goes like

Some time ago I wrote a post about making an http request using libcurl in c. Although the libcurl api is stable, it gives you so many options in front of you that there is a good chance of someone making a mistake while using it. After using libcurl directly, one would really appreciate the ease of use that python requests provide. CPR provides the best from both of the worlds. As it’s description on curl.haxx.se says

C++ Requests: Curl for People, a spiritual port of Python Requests. (based on libcurl) 

So let’s get started with CPR.

You can compile and install CPR

$ git clone https://github.com/whoshuu/cpr
$ cd cpr
$ mkdir build && cd build
$ cmake ..
$ make
$ sudo make install

As mentioned in the Official Documentation the sample GET request looks something like

#include <cpr/cpr.h>
#include <iostream>

using namespace std;

int main(int argc, char** argv) {
    cpr::Response r = cpr::Get(
        cpr::Url{"https://jsonplaceholder.typicode.com/todos/1"});

    cout << r.status_code << "\n";            // 200
    cout << r.header["content-type"] << "\n"; // application/json;charset=utf-8
    cout << r.text << "\n";                   // JSON text string

    return 0;
}

To compile this code g++ command looks like

[11:39 PM][girish@battle-ship]:cpr-tutorial
$ g++ -o cpr-demo cpr_demo.cpp -I/usr/local/include -L/usr/local/lib64/ -lcpr
[11:39 PM][girish@battle-ship]:cpr-tutorial
$ ./cpr-demo 
200
application/json; charset=utf-8
{
  "userId": 1,
  "id": 1,
  "title": "delectus aut autem",
  "completed": false
}

Or You can also use Conan which is a package manager for C and C++.

The process to use Conan is quite simple. All you have to do is install Conan

$ pip install conan

Create a conanfile.txt which is similar to Pipfile in the case of python’s Pipenv.

For using CPR, the conanfile.txt looks like.

[requires]
cpr/1.5.0

[generators]
cmake

Where we are just specifying dependency and a build generator to use.

Once you have conanfile.txt in place, let’s write a CMakeLists.txt for the same code so that we can build it using cmake. Again, here is a code snippet from the documentation of CPR itself

project(myproject CXX)

add_executable(${PROJECT_NAME} cpr_demo.cpp)

include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) # Include Conan-generated file
conan_basic_setup(TARGETS) # Introduce Conan-generated targets

target_link_libraries(${PROJECT_NAME} CONAN_PKG::cpr)

at this point, we have all the code ready; now let’s build it using conan and CMake.

First we need to download and install all the dependencies for the project.

[11:41 PM][girish@battle-ship]:cpr-tutorial
$ mkdir build
[11:41 PM][girish@battle-ship]:cpr-tutorial
$ cd build
[11:41 PM][girish@battle-ship]:build
$ conan install ../ –build=missing

It will download and build all of the dependencies. It may take a lot of time if you have a lot of dependencies in the project.

[11:44 PM][girish@battle-ship]:build
$ conan install ../ --build=missing
WARN: Remotes registry file missing, creating default one in /home/girish/.conan/remotes.json
Configuration:
[settings]
arch=x86_64
arch_build=x86_64
build_type=Release
compiler=gcc
compiler.libcxx=libstdc++11
compiler.version=10
os=Linux
os_build=Linux
[options]
[build_requires]
[env]

cpr/1.5.0: Not found in local cache, looking in remotes...
cpr/1.5.0: Trying with 'conan-center'...
Downloading conanmanifest.txt completed [0.93k]                                          
Downloading conanfile.py completed [2.77k]                                               
Downloading conan_export.tgz completed [0.32k]                                           
Decompressing conan_export.tgz completed [0.00k]
.
.
.
.
. 

After all the dependencies are downloaded and built, you can run cmake and get the build files ready.

[11:51 PM][girish@battle-ship]:build
$ cmake ..
-- The CXX compiler identification is GNU 10.2.1
-- Check for working CXX compiler: /usr/lib64/ccache/c++
-- Check for working CXX compiler: /usr/lib64/ccache/c++ - works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Conan: Adjusting output directories
-- Conan: Using cmake targets configuration
.
.
.
.

We have the build files ready now, let’s build the executable and run it.

[11:51 PM][girish@battle-ship]:build
$ make
Scanning dependencies of target cpr-demo
[ 50%] Building CXX object CMakeFiles/cpr_demo.o
[100%] Linking CXX executable cpr-demo
[100%] Built target cpr-demo
[11:51 PM][girish@battle-ship]:build
$ ./cpr-demo 
200
application/json; charset=utf-8
{
  "userId": 1,
  "id": 1,
  "title": "delectus aut autem",
  "completed": false
}

This was the first time I used CPR and conan. I’ll be trying conan and writing more about it in next few weeks.