Generación de Swagger/OpenAPI para C++: revisión de herramientas y bibliotecas
El desarrollo moderno de aplicaciones de servidor en C++ rara vez prescinde de una API REST. La especificación OpenAPI (anteriormente conocida como Swagger) se ha convertido en el estándar industrial para describir las interfaces de interacción entre el cliente y el servidor. Sin embargo, escribir código manualmente para procesar solicitudes, validar datos y generar respuestas es un proceso laborioso y propenso a errores. Afortunadamente, el ecosistema de C++ ofrece varias soluciones maduras para la generación automática de código a partir de una especificación OpenAPI. En este artículo, analizaremos las principales herramientas, sus puntos fuertes y proporcionaremos ejemplos prácticos.
1. OpenAPI Generator (openapi-generator.tech)
El generador de código universal más popular para docenas de lenguajes, incluido C++. Es compatible con OpenAPI 3.0 y 3.1. Permite generar tanto código de servidor (C++ REST SDK / cpprestsdk, Pistache, Restbed) como código de cliente.
Instalación
npm install @openapitools/openapi-generator-cli -g# o mediante Docker:docker run --rm -v ${PWD}:/local openapitools/openapi-generator-cli generate \ -i /local/petstore.yaml \ -g cpp-restsdk \ -o /local/out/cpp-clientEjemplo de generación de un cliente con cpprestsdk
Supongamos que tiene un archivo petstore.yaml con la descripción de una API para una tienda de mascotas. Después de la generación, obtendrá clases listas para usar:
#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 << "Nombre de la mascota: " << pet->getName() << std::endl; }).wait(); return 0;}Ventajas: comunidad enorme, soporte para múltiples frameworks, desarrollo activo.
Desventajas: el código generado puede ser redundante y requiere ajustes manuales para el framework específico.
2. oat++ (oatpp.io)
Un framework moderno para C++ con soporte nativo para OpenAPI 3.0. A diferencia de OpenAPI Generator, oat++ no genera código a partir de una especificación, sino que permite anotar los endpoints ya escritos y exportar automáticamente la especificación OpenAPI.
Ejemplo de anotación de un endpoint
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);}
// Descripción del DTODTO(PetDto, FIELD(Int32, id, "id"), FIELD(String, name, "name"), FIELD(String, status, "status"));Después de esto, oat++ generará automáticamente openapi.json en tiempo de ejecución. Para la generación estática, se utiliza la utilidad oatpp-swagger.
Ventajas: enfoque nativo, framework unificado, excelente documentación, soporte integrado para Swagger UI.
Desventajas: requiere usar oat++ en su totalidad, no es adecuado para proyectos existentes en otros frameworks.
3. Drogon (drogon.org)
Un framework web asíncrono de alto rendimiento para C++17/20. Incluye el módulo drogon_ctl para generar el esqueleto del proyecto y el plugin drogon::OpenApiPlugin para la generación automática de documentación OpenAPI 3.0.
Ejemplo de uso de OpenApiPlugin
#include <drogon/drogon.h>using namespace drogon;
int main() { app().registerController(std::make_shared<PetController>()); app().addPlugin("drogon::OpenApiPlugin", { {"title", "API de la Tienda de Mascotas"}, {"version", "1.0.0"} }); app().run();}Controlador con autodocumentación:
class PetController : public HttpController<PetController> {public: MET