### Swagger UI Component Setup Source: https://github.com/oatpp/oatpp-swagger/blob/master/README.md Details the necessary components to add to your AppComponents for Swagger UI integration. This includes DocumentInfo for API metadata and Resources for loading Swagger UI assets. ```c++ /** * General API docs info */ OATPP_CREATE_COMPONENT(std::shared_ptr, swaggerDocumentInfo)([] { oatpp::swagger::DocumentInfo::Builder builder; builder .setTitle("User entity service") .setDescription("CRUD API Example project with swagger docs") .setVersion("1.0") .setContactName("Ivan Ovsyanochka") .setContactUrl("https://oatpp.io/") .setLicenseName("Apache License, Version 2.0") .setLicenseUrl("http://www.apache.org/licenses/LICENSE-2.0") .addServer("http://localhost:8000", "server on localhost"); // When you are using the AUTHENTICATION() Endpoint-Macro you must add an SecurityScheme object (https://swagger.io/specification/#securitySchemeObject) // For basic-authentication you can use the default Basic-Authorization-Security-Scheme like this // For more complex authentication schemes you can use the oatpp::swagger::DocumentInfo::SecuritySchemeBuilder builder // Don't forget to add info->addSecurityRequirement("basic_auth") to your ENDPOINT_INFO() Macro! .addSecurityScheme("basic_auth", oatpp::swagger::DocumentInfo::SecuritySchemeBuilder::DefaultBasicAuthorizationSecurityScheme()); return builder.build(); }()); /** * Swagger-Ui Resources (/lib/oatpp-swagger/res) */ OATPP_CREATE_COMPONENT(std::shared_ptr, swaggerResources)([] { // Make sure to specify correct full path to oatpp-swagger/res folder !!! return oatpp::swagger::Resources::loadResources("/lib/oatpp-swagger/res"); }()); ``` -------------------------------- ### oatpp-swagger CMake Configuration Source: https://github.com/oatpp/oatpp-swagger/blob/master/src/CMakeLists.txt Defines the oatpp-swagger library, sets C++ standard to 17, manages dependencies, and configures installation of swagger-ui resources. It links against the oatpp library and sets include directories. ```cmake add_library(${OATPP_THIS_MODULE_NAME} oatpp-swagger/AsyncController.hpp oatpp-swagger/Controller.hpp oatpp-swagger/ControllerPaths.hpp oatpp-swagger/Generator.cpp oatpp-swagger/Generator.hpp oatpp-swagger/Model.hpp oatpp-swagger/Resources.cpp oatpp-swagger/Resources.hpp oatpp-swagger/Types.cpp oatpp-swagger/Types.hpp oatpp-swagger/oas3/Model.hpp) set_target_properties(${OATPP_THIS_MODULE_NAME} PROPERTIES CXX_STANDARD 17 CXX_EXTENSIONS OFF CXX_STANDARD_REQUIRED ON ) if(OATPP_MODULES_LOCATION STREQUAL OATPP_MODULES_LOCATION_EXTERNAL) add_dependencies(${OATPP_THIS_MODULE_NAME} ${LIB_OATPP_EXTERNAL}) endif() target_link_oatpp(${OATPP_THIS_MODULE_NAME}) target_include_directories(${OATPP_THIS_MODULE_NAME} PUBLIC $ ) ## TODO link dependencies here (if some) ####################################################################################################### ## install targets if(OATPP_INSTALL) include("../cmake/module-install.cmake") ## install swagger-ui files install(DIRECTORY ../res DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/oatpp-${OATPP_MODULE_VERSION}/bin/${OATPP_MODULE_NAME}" FILES_MATCHING PATTERN "*.*" ) ## set environment variable to point to swagger-ui res files set(ENV{OATPP_SWAGGER_RES_PATH} "${CMAKE_INSTALL_INCLUDEDIR}/oatpp-${OATPP_MODULE_VERSION}/bin/${OATPP_MODULE_NAME}/res") endif() ``` -------------------------------- ### CMake Configuration for oatpp-swagger Source: https://github.com/oatpp/oatpp-swagger/blob/master/README.md Provides the necessary CMake directives to find and link the oatpp and oatpp-swagger libraries, and to define the path to Swagger UI resources. ```c++ find_package(oatpp 1.3.0 REQUIRED) if(oatpp_FOUND) message(STATUS "Found oatpp version: ${oatpp_VERSION_STRING}") else() message(FATAL_ERROR "Could not find oatpp") endif() find_package(oatpp-swagger 1.3.0 REQUIRED) if(oatpp-swagger_FOUND) message(STATUS "Found oatpp-swagger version: ${oatpp-swagger_VERSION_STRING}") else() message(FATAL_ERROR "Could not find oatpp-swagger") endif() include_directories(${oatpp_INCLUDE_DIRS}) include_directories(${oatpp-swagger_INCLUDE_DIRS}) add_definitions( -DOATPP_SWAGGER_RES_PATH="${OATPP_BASE_DIR}/bin/oatpp-swagger/res" ) target_link_libraries (project PUBLIC // add_your libraries here PUBLIC oatpp::oatpp PUBLIC oatpp::oatpp-swagger ) ``` -------------------------------- ### oatpp-swagger API Documentation Overview Source: https://github.com/oatpp/oatpp-swagger/blob/master/README.md This section outlines the core concepts for integrating Swagger UI with oatpp services. It covers the locations for Swagger UI and OpenAPI specifications, and the automatic documentation capabilities of oatpp's API controllers. ```APIDOC Swagger UI Integration for oatpp Services: Purpose: Integrate Swagger UI to visualize and interact with RESTful APIs built with oatpp. Key Components: - oatpp::swagger::Controller: Handles serving Swagger UI assets and OpenAPI specifications. - oatpp::swagger::AsyncController: An asynchronous version for async handlers. - oatpp::swagger::DocumentInfo: Component to define API metadata (title, version, contact, license, servers, security schemes). - oatpp::swagger::Resources: Component to load Swagger UI static assets. Access Points: - Swagger UI: Accessible at `http://localhost:/swagger/ui`. - OpenAPI 3.0.0 Specification: Accessible at `http://localhost:/api-docs/oas-3.0.0.json`. Automatic Documentation: When using `oatpp::web::server::api::ApiController`: - Endpoint names are documented automatically. - Request parameters (path, query, header) are documented. - Request bodies are documented, including their DTO types and content types (e.g., `application/json`). - Response codes and their associated DTO types/content types can be documented. Manual Endpoint Annotation: Use the `ENDPOINT_INFO` macro to add detailed documentation to specific endpoints: - `info->summary`: A brief description of the endpoint's purpose. - `info->addConsumes(contentType)`: Specifies the expected request body type and content type. - `info->addResponse(statusCode, contentType)`: Specifies successful response types and content types. - `info->addResponse(statusCode)`: Specifies error response codes without a specific body type. - `info->addSecurityRequirement(schemeName)`: Links the endpoint to a defined security scheme. Example Endpoint Annotation: ```c++ ENDPOINT_INFO(createUser) { info->summary = "Create new User"; info->addConsumes("application/json"); info->addResponse(Status::CODE_200, "application/json"); info->addResponse(Status::CODE_500); } ENDPOINT("POST", "demo/api/users", createUser, BODY_DTO(UserDto, userDto)) { // ... implementation ... } ``` Component Configuration: Define `swaggerDocumentInfo` and `swaggerResources` as components in your application's AppComponents. - `swaggerDocumentInfo`: Configures API metadata using `oatpp::swagger::DocumentInfo::Builder`. - `setTitle`, `setDescription`, `setVersion`, `setContactName`, `setContactUrl`, `setLicenseName`, `setLicenseUrl`. - `addServer`: Defines API server URLs. - `addSecurityScheme`: Defines authentication mechanisms (e.g., Basic Auth). - `swaggerResources`: Loads static assets from the oatpp-swagger resource directory. - `oatpp::swagger::Resources::loadResources("/lib/oatpp-swagger/res")` Router Integration: Create an instance of `oatpp::swagger::Controller` and add its endpoints to your web router. - `auto swaggerController = oatpp::swagger::Controller::createShared();` - `swaggerController->addEndpointsToRouter(router);` CMake Integration: Ensure `oatpp` and `oatpp-swagger` are found and linked in your `CMakeLists.txt`. - `find_package(oatpp ...)` - `find_package(oatpp-swagger ...)` - `include_directories(...)` - `add_definitions(-DOATPP_SWAGGER_RES_PATH="...")` - `target_link_libraries(... oatpp::oatpp oatpp::oatpp-swagger)` ``` -------------------------------- ### Configure Module Tests Executable Source: https://github.com/oatpp/oatpp-swagger/blob/master/test/CMakeLists.txt Defines the main executable for running module tests. It lists all necessary source files, including test controllers and implementation files for both synchronous and asynchronous operations. ```CMake add_executable(module-tests oatpp-swagger/tests.cpp oatpp-swagger/test-controllers/TestController.hpp oatpp-swagger/test-controllers/TestAsyncController.hpp oatpp-swagger/ControllerTest.cpp oatpp-swagger/ControllerTest.hpp oatpp-swagger/AsyncControllerTest.cpp oatpp-swagger/AsyncControllerTest.hpp ) ``` -------------------------------- ### Define Swagger UI Resource Path Source: https://github.com/oatpp/oatpp-swagger/blob/master/test/CMakeLists.txt Sets a preprocessor definition for the path to the swagger-ui resource folder, typically used to locate static assets for the UI. ```CMake add_definitions(-DOATPP_SWAGGER_RES_PATH="${CMAKE_CURRENT_LIST_DIR}/../res") ``` -------------------------------- ### Automatic Endpoint Documentation Source: https://github.com/oatpp/oatpp-swagger/blob/master/README.md Demonstrates how oatpp::web::server::api::ApiController automatically documents endpoints. It shows how to add metadata like summary, request body types, and response types using ENDPOINT_INFO. ```c++ ENDPOINT_INFO(createUser) { info->summary = "Create new User"; info->addConsumes("application/json"); info->addResponse(Status::CODE_200, "application/json"); info->addResponse(Status::CODE_500); } ENDPOINT("POST", "demo/api/users", createUser, BODY_DTO(UserDto, userDto)) { return createDtoResponse(Status::CODE_200, m_database->createUser(userDto)); } ``` -------------------------------- ### Configure oatpp-swagger Module with CMake Source: https://github.com/oatpp/oatpp-swagger/blob/master/CMakeLists.txt This CMakeLists.txt file configures the oatpp-swagger module. It sets module metadata, defines build options like shared libraries and tests, and handles finding the core oatpp dependency, supporting different locations for the oatpp library. ```cmake cmake_minimum_required(VERSION 3.20 FATAL_ERROR) ################################################################################################### ## These variables are passed to oatpp-module-install.cmake script ## use these variables to configure module installation set(OATPP_THIS_MODULE_NAME oatpp-swagger) ## name of the module (also name of folders in installation dirs) set(OATPP_THIS_MODULE_VERSION "1.4.0") ## version of the module (also sufix of folders in installation dirs) set(OATPP_THIS_MODULE_LIBRARIES oatpp-swagger) ## list of libraries to find when find_package is called set(OATPP_THIS_MODULE_TARGETS oatpp-swagger) ## list of targets to install set(OATPP_THIS_MODULE_DIRECTORIES oatpp-swagger) ## list of directories to install ################################################################################################### project(${OATPP_THIS_MODULE_NAME} VERSION ${OATPP_THIS_MODULE_VERSION} LANGUAGES CXX ) option(BUILD_SHARED_LIBS "Build shared libraries" OFF) option(OATPP_DIR_SRC "Path to oatpp module directory (sources)") option(OATPP_DIR_LIB "Path to directory with liboatpp (directory containing ex: liboatpp.so or liboatpp.dynlib)") option(OATPP_BUILD_TESTS "Build tests for this module" ON) option(OATPP_INSTALL "Install module binaries" ON) option(OATPP_MSVC_LINK_STATIC_RUNTIME "MSVC: Link with static runtime (/MT and /MTd)." OFF) set(OATPP_MODULES_LOCATION "INSTALLED" CACHE STRING "Location where to find oatpp modules. can be [INSTALLED|EXTERNAL|CUSTOM]") ################################################################################################### ## get oatpp main module in specified location set(OATPP_MODULES_LOCATION_INSTALLED INSTALLED) set(OATPP_MODULES_LOCATION_EXTERNAL EXTERNAL) set(OATPP_MODULES_LOCATION_CUSTOM CUSTOM) if(OATPP_MODULES_LOCATION STREQUAL OATPP_MODULES_LOCATION_INSTALLED) message("Finding oatpp in location=INSTALLED") find_package(oatpp ${OATPP_THIS_MODULE_VERSION} REQUIRED) get_target_property(OATPP_INCLUDE oatpp::oatpp INTERFACE_INCLUDE_DIRECTORIES) message("OATPP_INCLUDE=${OATPP_INCLUDE}") get_target_property(OATPP_TEST_INCLUDE oatpp::oatpp-test INTERFACE_INCLUDE_DIRECTORIES) message("OATPP_TEST_INCLUDE=${OATPP_TEST_INCLUDE}") elseif(OATPP_MODULES_LOCATION STREQUAL OATPP_MODULES_LOCATION_EXTERNAL) message("Finding oatpp in location=EXTERNAL") include(ExternalProject) set(MODULE_WAIT_DEPS ON) set(LIB_OATPP_EXTERNAL "lib_oatpp_external") ExternalProject_Add(${LIB_OATPP_EXTERNAL} GIT_REPOSITORY "https://github.com/oatpp/oatpp.git" GIT_TAG origin/master CMAKE_ARGS -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DOATPP_INSTALL=OFF -DOATPP_BUILD_TESTS=OFF INSTALL_COMMAND cmake -E echo "SKIP INSTALL '${LIB_OATPP_EXTERNAL}'" ) ExternalProject_Get_Property(${LIB_OATPP_EXTERNAL} BINARY_DIR) set(OATPP_DIR_LIB ${BINARY_DIR}/src) ExternalProject_Get_Property(${LIB_OATPP_EXTERNAL} SOURCE_DIR) set(OATPP_DIR_SRC ${SOURCE_DIR}/src) message("OATPP_DIR_SRC --> '${OATPP_DIR_SRC}'") message("OATPP_DIR_LIB --> '${OATPP_DIR_LIB}'") elseif(OATPP_MODULES_LOCATION STREQUAL OATPP_MODULES_LOCATION_CUSTOM) message("Finding oatpp in location=CUSTOM") message("OATPP_DIR_SRC --> '${OATPP_DIR_SRC}'") message("OATPP_DIR_LIB --> '${OATPP_DIR_LIB}'") else() message(FATAL_ERROR "Unknown location to find oatpp '${OATPP_MODULES_LOCATION}'") endif() if(OATPP_DIR_LIB) link_directories(${OATPP_DIR_LIB}) endif() ################################################################################################### ## get dependencies message("\n############################################################################") message("## ${OATPP_THIS_MODULE_NAME} module. Resolving dependencies...\n") ## TODO find dependecies here (if some) message("\n############################################################################\n") ################################################################################################### ## define targets include(cmake/module-utils.cmake) include(cmake/msvc-runtime.cmake) configure_msvc_runtime() add_subdirectory(src) if(OATPP_BUILD_TESTS) enable_testing() add_subdirectory(test) endif() ``` -------------------------------- ### Add Test Source: https://github.com/oatpp/oatpp-swagger/blob/master/test/CMakeLists.txt Registers the 'module-tests' executable as a test to be run by the testing framework. ```CMake add_test(module-tests module-tests) ``` -------------------------------- ### Swagger UI Controller Registration Source: https://github.com/oatpp/oatpp-swagger/blob/master/README.md Explains how to create and register the Swagger UI controller with your application's router to make the Swagger UI and OpenAPI specification accessible. ```c++ auto swaggerController = oatpp::swagger::Controller::createShared(); swaggerController->addEndpointsToRouter(router); ``` -------------------------------- ### Add Include Directories Source: https://github.com/oatpp/oatpp-swagger/blob/master/test/CMakeLists.txt Specifies the include directories for the 'module-tests' target, making project headers accessible during compilation. It includes the current source directory. ```CMake target_include_directories(module-tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ) ``` -------------------------------- ### Manage Module Dependencies Source: https://github.com/oatpp/oatpp-swagger/blob/master/test/CMakeLists.txt Handles dependencies for the 'module-tests' target. It conditionally adds dependencies based on the OATPP_MODULES_LOCATION setting and links the current oatpp module. ```CMake if(OATPP_MODULES_LOCATION STREQUAL OATPP_MODULES_LOCATION_EXTERNAL) add_dependencies(module-tests ${LIB_OATPP_EXTERNAL}) endif() add_dependencies(module-tests ${OATPP_THIS_MODULE_NAME}) target_link_oatpp(module-tests) target_link_libraries(module-tests PRIVATE ${OATPP_THIS_MODULE_NAME} ) ``` -------------------------------- ### Customise Swagger UI Paths in C++ Source: https://github.com/oatpp/oatpp-swagger/blob/master/README.md This C++ code snippet demonstrates how to customize the endpoint paths for the Swagger UI. It involves creating a `oatpp::swagger::ControllerPaths` component and setting custom values for `apiJson`, `ui`, and `uiResources` paths. Ensure `paths->ui` and `paths->uiResources` share the same base path for correct functionality. ```c++ /** * Swagger Controller Paths */ OATPP_CREATE_COMPONENT(std::shared_ptr, controllerPaths)([] { auto paths = std::make_shared(); paths->apiJson = "custom/path/for/api.json"; // default is "api-docs/oas-3.0.0.json" paths->ui = "my/custom/path/swagger-ui"; // default is "swagger/ui" paths->uiResources = "my/custom/path/{filename}"; // default is "swagger/{filename}" return paths; }()); ``` -------------------------------- ### Set C++ Standard Properties Source: https://github.com/oatpp/oatpp-swagger/blob/master/test/CMakeLists.txt Configures the C++ standard for the 'module-tests' target to C++17, disabling C++ extensions and enforcing standard compliance for better portability and code quality. ```CMake set_target_properties(module-tests PROPERTIES CXX_STANDARD 17 CXX_EXTENSIONS OFF CXX_STANDARD_REQUIRED ON ) ``` -------------------------------- ### Swagger UI OAuth2 Redirect Handler Source: https://github.com/oatpp/oatpp-swagger/blob/master/res/oauth2-redirect.html This JavaScript code processes the OAuth2 redirect from an authorization server for Swagger UI. It extracts query parameters or URL fragments, validates the state, and sends the authorization code or token back to the opener window via a callback function. It handles different OAuth2 flows and potential errors. ```javascript 'use strict'; function run () { var oauth2 = window.opener.swaggerUIRedirectOauth2; var sentState = oauth2.state; var redirectUrl = oauth2.redirectUrl; var isValid, qp, arr; if (/code|token|error/.test(window.location.hash)) { qp = window.location.hash.substring(1).replace('?', '&'); } else { qp = location.search.substring(1); } arr = qp.split("&"); arr.forEach(function (v,i,_arr) { _arr[i] = '"' + v.replace('=', '":"') + '"'; }); qp = qp ? JSON.parse('{' + arr.join() + '}', function (key, value) { return key === "" ? value : decodeURIComponent(value); } ) : {}; isValid = qp.state === sentState; if (( oauth2.auth.schema.get("flow") === "accessCode" || oauth2.auth.schema.get("flow") === "authorizationCode" || oauth2.auth.schema.get("flow") === "authorization_code" ) && !oauth2.auth.code) { if (!isValid) { oauth2.errCb({ authId: oauth2.auth.name, source: "auth", level: "warning", message: "Authorization may be unsafe, passed state was changed in server. The passed state wasn't returned from auth server." }); } if (qp.code) { delete oauth2.state; oauth2.auth.code = qp.code; oauth2.callback({auth: oauth2.auth, redirectUrl: redirectUrl}); } else { let oauthErrorMsg; if (qp.error) { oauthErrorMsg = "["+qp.error+"]: " + (qp.error_description ? qp.error_description+ ". " : "no accessCode received from the server. ") + (qp.error_uri ? "More info: "+qp.error_uri : ""); } oauth2.errCb({ authId: oauth2.auth.name, source: "auth", level: "error", message: oauthErrorMsg || "[Authorization failed]: no accessCode received from the server." }); } } else { oauth2.callback({auth: oauth2.auth, token: qp, isValid: isValid, redirectUrl: redirectUrl}); } window.close(); } if (document.readyState !== 'loading') { run(); } else { document.addEventListener('DOMContentLoaded', function () { run(); }); } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.