C++ for the Web with Drogon
Drogon is currently the fastest web server in the world. If you already know a bit of C++, it wouldn’t hurt to try it out. I personally think drogon is great, however I do find its documentation somewhat lacking which is all the more reason to contribute to them. If you find that drogon is right for you, please consider contributing to / sponsoring their project.
In this blog, we’ll see how we can set up a basic REST API using drogon and CMake.
The code snippets I’ve provided apply to macOS and Linux. However, you can still follow along if you’re on windows and have worked with CMake and VS before.
Project Setup
If you’re like me and you don’t mind using CMake with submodules, we can set up drogon like so:
Get the pre-requisite libraries installed in accordance with the official documentation. For macOS, I had to install ossp-uuid
and jsoncpp
.
Create a CMakeLists.txt in your project root.
touch CMakeLists.txt
Initialize Git in your project root.
git init
Add drogon as a submodule
git submodule add https://github.com/drogonframework/drogon.git external/drogon
Pull drogon’s submodules (trantor)
git submodule update --init --recursive
At this point you’ve got your dependencies setup. Let’s go ahead and add some code for our basic REST API.
Create a new directory for our source files
mkdir src
And add our entrypoint
touch src/main.cpp
Here’s a basic CMakeLists.txt
file that will build our project
cmake_minimum_required(VERSION 3.25.2)
project(
drogontutorial
VERSION 0.1
DESCRIPTION "Drogon CMake Tutorial"
LANGUAGES CXX
)
# compiler flags
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")
add_executable(${PROJECT_NAME} src/main.cpp)
add_subdirectory(external/drogon)
target_link_libraries(${PROJECT_NAME} PRIVATE drogon)
And this will be our src/main.cpp
#include <drogon/drogon.h>
int main()
{
using namespace drogon;
app().setLogPath("./")
.setLogLevel(trantor::Logger::kWarn)
.addListener("0.0.0.0", 8080)
.setThreadNum(8)
.registerHandler("/hello?name={name}",
[](const HttpRequestPtr& req,
std::function<void(const HttpResponsePtr&)>&& callback,
const std::string& name)
{
Json::Value json;
json["result"] = "ok";
json["message"] = std::string("hello,") + name;
auto resp = HttpResponse::newHttpJsonResponse(json);
callback(resp);
},
{ Get,"LoginFilter" })
.run();
}
Building and Running the App
So far your directory structure should look something like this:
.
├── CMakeLists.txt
├── external
│ └── drogon
└── src
└── main.cpp
4 directories, 2 files
Go ahead and create a directory to house our build files
mkdir build && cd build
Now lets generate the Makefile using
cmake ..
and now to compile our application,
make -j$(nproc)
Hopefully after all this, you should find an executable called drogontutorial
in the build directory.
let’s run this file to start our server.
./drogontutorial
Now, your server should be listening on port 8080. Test it out by sending your name to /hello
curl http://localhost:8080/hello?name=yourname
And just like that you’ve got a starter project to write your own REST APIs in C++.
If you find this nice, do check out their examples on github.
Until next time!