Skip to content

Commit e1c601b

Browse files
authored
C++: Hello API & OpenAPI with Swagger (#28)
* C++ web app * WIP: Get APIs working * Add commented code to adjust swagger/openapi doc URLs * Remove files that are no longer needed * Add a POST: /ping route, and fix GET: /hello * / redirects to /swagger/ui Until oatpp/oatpp-swagger#99 is addressed * Tag "Hello API" endpoints with "exp" * Update Readme
1 parent ad05c24 commit e1c601b

19 files changed

+500
-72
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ Service | Port
2121

2222
| | C++ | C# | Go | Python | Rust |
2323
|-----------------------|-----|----|----|--------|------|
24-
| Hello API | |||||
25-
| Open API & Swagger UI | |||||
24+
| Hello API | |||||
25+
| Open API & Swagger UI | |||||
2626
| Dev container ||||||
27-
| Dependency management | |||||
27+
| Dependency management | |||||
2828
| Configuration ||||||
2929
| Structured logging ||||||
3030
| Docker container ||||||

cpp/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
11
bin/
2+
3+
build/
4+
vcpkg_installed/

cpp/.vscode/c_cpp_properties.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
"compilerPath": "/usr/bin/g++-14",
1010
"cStandard": "c17",
1111
"cppStandard": "c++23",
12-
"intelliSenseMode": "gcc-x64"
12+
"intelliSenseMode": "gcc-x64",
13+
"configurationProvider": "ms-vscode.cmake-tools"
1314
}
1415
],
1516
"version": 4

cpp/.vscode/launch.json

Lines changed: 0 additions & 34 deletions
This file was deleted.

cpp/.vscode/tasks.json

Lines changed: 0 additions & 28 deletions
This file was deleted.

cpp/CMakeLists.txt

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
cmake_minimum_required(VERSION 3.30)
2+
project(lpg VERSION 0.1.0 LANGUAGES CXX)
3+
set(CMAKE_CXX_STANDARD 23)
4+
5+
6+
add_library(lpg-lib
7+
8+
src/dto/MessageDto.hpp
9+
src/dto/StatusDto.hpp
10+
11+
src/controller/StaticController.hpp
12+
src/controller/HelloApiController.hpp
13+
14+
src/AppComponent.hpp
15+
src/SwaggerComponent.hpp
16+
src/ErrorHandler.cpp
17+
src/ErrorHandler.hpp
18+
)
19+
20+
21+
find_package(oatpp 1.3.0 REQUIRED)
22+
find_package(oatpp-swagger 1.3.0 REQUIRED)
23+
24+
target_link_libraries(lpg-lib
25+
PUBLIC oatpp::oatpp
26+
PUBLIC oatpp::oatpp-swagger
27+
)
28+
29+
add_definitions(
30+
## define path to swagger-ui static resources folder
31+
-DOATPP_SWAGGER_RES_PATH="${oatpp-swagger_INCLUDE_DIRS}/../bin/oatpp-swagger/res"
32+
)
33+
34+
if(CMAKE_SYSTEM_NAME MATCHES Linux)
35+
find_package(Threads REQUIRED)
36+
target_link_libraries(lpg-lib INTERFACE Threads::Threads ${CMAKE_DL_LIBS})
37+
endif()
38+
39+
40+
# Add executable
41+
add_executable(lpg
42+
src/App.cpp
43+
)
44+
45+
target_link_libraries(lpg
46+
lpg-lib
47+
)

cpp/CMakePresets.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"version": 8,
3+
"configurePresets": [
4+
{
5+
"name": "main",
6+
"displayName": "GCC 14.2.0 x86_64-linux-gnu",
7+
"description": "Using compilers: C = /usr/bin/gcc, CXX = /usr/bin/g++",
8+
"binaryDir": "${sourceDir}/out/build/${presetName}",
9+
"cacheVariables": {
10+
"CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}",
11+
"CMAKE_C_COMPILER": "/usr/bin/gcc",
12+
"CMAKE_CXX_COMPILER": "/usr/bin/g++-14",
13+
"CMAKE_BUILD_TYPE": "Debug",
14+
"CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake",
15+
"VCPKG_TARGET_TRIPLET": "x64-linux"
16+
}
17+
}
18+
]
19+
}

cpp/app.cpp

Lines changed: 0 additions & 6 deletions
This file was deleted.

cpp/src/App.cpp

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
2+
#include "AppComponent.hpp"
3+
4+
#include "controller/StaticController.hpp"
5+
#include "controller/HelloApiController.hpp"
6+
7+
#include "oatpp-swagger/Controller.hpp"
8+
9+
#include "oatpp/network/Server.hpp"
10+
11+
#include <iostream>
12+
13+
void run() {
14+
15+
AppComponent components; // Create scope Environment components
16+
17+
/* Get router component */
18+
OATPP_COMPONENT(std::shared_ptr<oatpp::web::server::HttpRouter>, router);
19+
20+
oatpp::web::server::api::Endpoints docEndpoints;
21+
22+
// docEndpoints.append(router->addController(UserController::createShared())->getEndpoints());
23+
24+
docEndpoints.append(router ->addController(HelloApiController::createShared())->getEndpoints());
25+
router->addController(oatpp::swagger::Controller::createShared(docEndpoints));
26+
router->addController(StaticController::createShared());
27+
28+
/* Get connection handler component */
29+
OATPP_COMPONENT(std::shared_ptr<oatpp::network::ConnectionHandler>, connectionHandler);
30+
31+
/* Get connection provider component */
32+
OATPP_COMPONENT(std::shared_ptr<oatpp::network::ServerConnectionProvider>, connectionProvider);
33+
34+
/* create server */
35+
oatpp::network::Server server(connectionProvider,
36+
connectionHandler);
37+
38+
OATPP_LOGD("Server", "Running on port %s...", connectionProvider->getProperty("port").toString()->c_str());
39+
40+
server.run();
41+
42+
}
43+
44+
/**
45+
* main
46+
*/
47+
int main(int argc, const char * argv[]) {
48+
49+
oatpp::base::Environment::init();
50+
51+
run();
52+
53+
/* Print how many objects were created during app running, and what have left-probably leaked */
54+
/* Disable object counting for release builds using '-D OATPP_DISABLE_ENV_OBJECT_COUNTERS' flag for better performance */
55+
std::cout << "\nEnvironment:\n";
56+
std::cout << "objectsCount = " << oatpp::base::Environment::getObjectsCount() << "\n";
57+
std::cout << "objectsCreated = " << oatpp::base::Environment::getObjectsCreated() << "\n\n";
58+
59+
oatpp::base::Environment::destroy();
60+
61+
return 0;
62+
}

cpp/src/AppComponent.hpp

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
2+
#ifndef AppComponent_hpp
3+
#define AppComponent_hpp
4+
5+
#include "SwaggerComponent.hpp"
6+
7+
#include "ErrorHandler.hpp"
8+
9+
#include "oatpp/web/server/HttpConnectionHandler.hpp"
10+
#include "oatpp/web/server/HttpRouter.hpp"
11+
#include "oatpp/network/tcp/server/ConnectionProvider.hpp"
12+
13+
#include "oatpp/parser/json/mapping/ObjectMapper.hpp"
14+
15+
#include "oatpp/core/macro/component.hpp"
16+
17+
/**
18+
* Class which creates and holds Application components and registers components in oatpp::base::Environment
19+
* Order of components initialization is from top to bottom
20+
*/
21+
class AppComponent {
22+
public:
23+
24+
/**
25+
* Swagger component
26+
*/
27+
SwaggerComponent swaggerComponent;
28+
29+
/**
30+
* Create ObjectMapper component to serialize/deserialize DTOs in Controller's API
31+
*/
32+
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::data::mapping::ObjectMapper>, apiObjectMapper)([] {
33+
auto objectMapper = oatpp::parser::json::mapping::ObjectMapper::createShared();
34+
objectMapper->getDeserializer()->getConfig()->allowUnknownFields = false;
35+
return objectMapper;
36+
}());
37+
38+
/**
39+
* Create ConnectionProvider component which listens on the port
40+
*/
41+
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::network::ServerConnectionProvider>, serverConnectionProvider)([] {
42+
return oatpp::network::tcp::server::ConnectionProvider::createShared({"0.0.0.0", 8000, oatpp::network::Address::IP_4});
43+
}());
44+
45+
/**
46+
* Create Router component
47+
*/
48+
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::web::server::HttpRouter>, httpRouter)([] {
49+
return oatpp::web::server::HttpRouter::createShared();
50+
}());
51+
52+
/**
53+
* Create ConnectionHandler component which uses Router component to route requests
54+
*/
55+
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::network::ConnectionHandler>, serverConnectionHandler)([] {
56+
57+
OATPP_COMPONENT(std::shared_ptr<oatpp::web::server::HttpRouter>, router); // get Router component
58+
OATPP_COMPONENT(std::shared_ptr<oatpp::data::mapping::ObjectMapper>, objectMapper); // get ObjectMapper component
59+
60+
auto connectionHandler = oatpp::web::server::HttpConnectionHandler::createShared(router);
61+
connectionHandler->setErrorHandler(std::make_shared<ErrorHandler>(objectMapper));
62+
return connectionHandler;
63+
64+
}());
65+
66+
};
67+
68+
#endif /* AppComponent_hpp */

0 commit comments

Comments
 (0)