Swagger/OpenAPI Generation for C++: Overview of Tools and Libraries
Modern server-side development in C++ rarely goes without a REST API. The OpenAPI specification (formerly known as Swagger) has become the industry standard for describing interfaces between a client and a server. However, manually writing code for request handling, data validation, and response generation is a labor-intensive and error-prone process. Fortunately, the C++ ecosystem offers several mature solutions for automatic code generation from an OpenAPI specification. In this article, we will review the main tools, their strengths, and provide practical examples.
1. OpenAPI Generator (openapi-generator.tech)
The most popular universal code generator for dozens of languages, including C++. Supports OpenAPI 3.0 and 3.1. Allows generating both server code (C++ REST SDK / cpprestsdk, Pistache, Restbed) and client code.
Installation
npm install @openapitools/openapi-generator-cli -g# or via Docker:docker run --rm -v ${PWD}:/local openapitools/openapi-generator-cli generate \ -i /local/petstore.yaml \ -g cpp-restsdk \ -o /local/out/cpp-clientExample of generating a client with cpprestsdk
Suppose you have a file petstore.yaml describing an API for a pet store. After generation, you will get ready-made classes:
#include "ApiClient.h"#include "PetApi.h"
int main() { auto client = std::make_shared<ApiClient>(); PetApi api(client);
api.getPetById(1).then([](std::shared_ptr<Pet> pet) { std::cout << "Pet name: " << pet->getName() << std::endl; }).wait(); return 0;}Pros: huge community, support for many frameworks, active development.
Cons: generated code can be verbose, requires manual tuning for a specific framework.
2. oat++ (oatpp.io)
A modern C++ framework with its own support for OpenAPI 3.0. Unlike OpenAPI Generator, oat++ does not generate code from a specification but allows you to annotate already written endpoints and automatically export an OpenAPI specification.
Example of endpoint annotation
ENDPOINT("GET", "/pets/{petId}", getPetById) { auto dto = PetDto::createShared(); dto->id = request->getPathVariable("petId"); dto->name = "Rex"; dto->status = "available"; return createDtoResponse(Status::CODE_200, dto);}
// DTO descriptionDTO(PetDto, FIELD(Int32, id, "id"), FIELD(String, name, "name"), FIELD(String, status, "status"));After this, oat++ will automatically generate openapi.json at runtime. For static generation, the oatpp-swagger utility is used.
Pros: native approach, single framework, excellent documentation, built-in Swagger UI support.
Cons: requires using oat++ entirely, not suitable for existing projects on other frameworks.
3. Drogon (drogon.org)
A high-performance asynchronous web framework for C++17/20. Includes the drogon_ctl module for generating a project skeleton and the drogon::OpenApiPlugin plugin for automatic generation of OpenAPI 3.0 documentation.
Example of using OpenApiPlugin
#include <drogon/drogon.h>using namespace drogon;
int main() { app().registerController(std::make_shared<PetController>()); app().addPlugin("drogon::OpenApiPlugin", { {"title", "Pet Store API"}, {"version", "1.0.0"} }); app().run();}Controller with auto-documentation:
class PetController : public HttpController<PetController> {public: MET Also in library
Event Bus and Observer Pattern in C++: Implementation in Modern C++
Candle Rust Guide: Complete Tutorial with Examples
Compose Multiplatform for Kotlin: Complete Guide with Examples
WebSocket library in C++: complete guide to selection and usage
Database Migrations in C++: Overview of Tools and Libraries