There are many C++ RESTful frameworks available. This document aims to provide a multidimensional comparison of the most popular ones. The chosen frameworks are:
Each framework has been used to create a basic REST services. All services are equivalent and contain 3 endpoints:
/test
- handles POST message (JSON) and sends it back with additional text and status code 200./test/status
- handles GET message and prints "OK"./test/labels/<string>
- handles GET message with parameter. The /test
endpoint was used for testing performance. There were 5 testing parameters used to test various aspects:
hardware_concurrency()
on the machine used to run tests.A testcase is any combination of above parameters. There could be in total 16 testcases, but testcases for N=200 and t=0ms. were intentionally excluded as not providing any new information.
Services were deployed on the following system:
All services logged the reception of message and response with millisecond precision. The tables contain time (min:sec.ms) from the reception of the first request to the last reply. The best times are marked in green, the worst in red. Let's number the tests:
Red x
means that the service run into deadlock and test could not be finished.
Below table summarizes other features of analyses frameworks that can be interesting for a professional development.
Only Restbed's AGPL license may be problematic for some companies, which would like to use this framework for its products and tools.
"Ease of including" is a subjective measure describing how easy for me was to get the framework, build it, manage its dependecies and integrate it with existing package management systems, that companies may use. The highest scores got Crow and Httplib for header only libraries ensuring the easiest integration. Restinio got the lowest score, since I was not able to overcome a problem with its dependencies using just apt tool on Ubuntu Xenial (https://github.com/Stiffstream/restinio/issues/86).
"Ease of using" is another subjective measure describing how easy for me was to build the basic service. Again Crow and Httplib got highest scores, together with Pistache. These libraries provide us with many useful primitives to build a service, helpful examples and the amount of boilerplate code is reduced to minimum. The lowest score goes to Cpp-REST-SDK, which seems to be overcomplicated and the simplest tasks require diving deep into the documentation and writing lots of own code. Restinio was in the middle. It may be a little overcomplicated too, but provides many useful examples and after a while you can get the idea.
This repository contains 6 basic services used for this test. Anyone is enouraged to use them for verification of above results or running own tests. Each service is a Cmake project, which can be built separately.
Before building the benchmark projects, its dependencies need to be installed. You may install them in the system or locally - in that case use -DCMAKE_PREFIX_PATH=<>
can be used to indicate the location of libraries in the next step. All projects use https://github.com/log4cplus/log4cplus to provide consistent logging with millisecond precision. Also:
crow_all.h
header file.cd basic-xxx
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
make
After building, place the logger-config.ini
in the folder containing the binaries.
To run a service use:
$ ./basic-xxx [t (ms.)] [C]
t is the simulated time of handling a request, C is the number of threads in the threadpool. Parameters are positional and optional. Default value for C is hardware_concurrency()
and for t is 0. basic-httplib accepts only single parameter t, as the number of threads is chosen at compilation time (see basic-httplib/main.cpp
).
To simulate clients, a python script postInLoop.py
was used. Run:
$ python3 postInLoop.py -h
for usage.