forked from lthn/blockchain
Add initial Oatpp-based API server implementation
Introduces a new API module using Oatpp and Oatpp-Swagger, including controllers, DTOs, and server setup. Updates build scripts and dependencies to support the new API layer for Lethean, providing endpoints and Swagger documentation.
This commit is contained in:
parent
4a5c5ae742
commit
d78c6cecd8
8 changed files with 256 additions and 1 deletions
|
|
@ -26,7 +26,9 @@ class BlockchainConan(ConanFile):
|
|||
"boost/1.85.0",
|
||||
"openssl/3.2.0",
|
||||
"miniupnpc/2.2.5",
|
||||
"jwt-cpp/0.7.1"
|
||||
"jwt-cpp/0.7.1",
|
||||
"oatpp/1.3.0.latest",
|
||||
"oatpp-swagger/1.3.0.latest"
|
||||
]
|
||||
|
||||
def generate(self):
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ INIT_SHARED_PCH()
|
|||
|
||||
add_subdirectory(config)
|
||||
add_subdirectory(genesis)
|
||||
add_subdirectory(api)
|
||||
|
||||
add_library(common ${COMMON})
|
||||
add_dependencies(common version config ${PCH_LIB_NAME})
|
||||
|
|
|
|||
38
src/api/ApiServer.hpp
Normal file
38
src/api/ApiServer.hpp
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
#ifndef ApiServer_hpp
|
||||
#define ApiServer_hpp
|
||||
|
||||
#include "oatpp/web/server/HttpConnectionHandler.hpp"
|
||||
#include "oatpp/network/tcp/server/ConnectionProvider.hpp"
|
||||
#include "oatpp/core/macro/component.hpp"
|
||||
#include "oatpp-swagger/Resources.hpp"
|
||||
|
||||
#include "oatpp/parser/json/mapping/ObjectMapper.hpp"
|
||||
#include "oatpp-swagger/Resources.hpp"
|
||||
#include "oatpp-swagger/Model.hpp"
|
||||
class ApiServer {
|
||||
public:
|
||||
|
||||
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::network::ServerConnectionProvider>, serverConnectionProvider)([] {
|
||||
return oatpp::network::tcp::server::ConnectionProvider::createShared({"0.0.0.0", 8000, oatpp::network::Address::IP_4});
|
||||
}());
|
||||
|
||||
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::web::server::HttpRouter>, httpRouter)([] {
|
||||
return oatpp::web::server::HttpRouter::createShared();
|
||||
}());
|
||||
|
||||
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::network::ConnectionHandler>, serverConnectionHandler)([] {
|
||||
OATPP_COMPONENT(std::shared_ptr<oatpp::web::server::HttpRouter>, router);
|
||||
return oatpp::web::server::HttpConnectionHandler::createShared(router);
|
||||
}());
|
||||
|
||||
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::data::mapping::ObjectMapper>, apiObjectMapper)([] {
|
||||
return oatpp::parser::json::mapping::ObjectMapper::createShared();
|
||||
}());
|
||||
|
||||
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::swagger::Resources>, swaggerResources)([] {
|
||||
return oatpp::swagger::Resources::loadResources(OATPP_SWAGGER_RES_PATH);
|
||||
}());
|
||||
|
||||
};
|
||||
|
||||
#endif /* ApiServer_hpp */
|
||||
30
src/api/CMakeLists.txt
Normal file
30
src/api/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
if(NOT PROJECT_NAME)
|
||||
project(lethean-api)
|
||||
endif()
|
||||
|
||||
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()
|
||||
|
||||
add_library(lthn_api INTERFACE)
|
||||
add_library(lthn::api ALIAS lthn_api)
|
||||
|
||||
target_include_directories(lthn_api INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
include_directories(${oatpp_INCLUDE_DIRS})
|
||||
include_directories(${oatpp-swagger_INCLUDE_DIRS})
|
||||
add_executable(lethean-api main.cpp)
|
||||
|
||||
target_link_libraries(lethean-api PRIVATE lthn::api PUBLIC oatpp::oatpp oatpp::oatpp-swagger)
|
||||
|
||||
add_definitions(-DOATPP_SWAGGER_RES_PATH="${oatpp-swagger_INCLUDE_DIRS}/../bin/oatpp-swagger/res")
|
||||
#add_subdirectory(tests)
|
||||
35
src/api/controller/RootController.hpp
Normal file
35
src/api/controller/RootController.hpp
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
#ifndef RootController_hpp
|
||||
#define RootController_hpp
|
||||
|
||||
#include "./info/InfoController.hpp"
|
||||
#include "../dto/DTOs.hpp"
|
||||
|
||||
#include "oatpp/web/server/api/ApiController.hpp"
|
||||
#include "oatpp/core/macro/codegen.hpp"
|
||||
#include "oatpp/core/macro/component.hpp"
|
||||
|
||||
#include OATPP_CODEGEN_BEGIN(ApiController)
|
||||
|
||||
class RootController : public oatpp::web::server::api::ApiController {
|
||||
private:
|
||||
std::shared_ptr<InfoController> m_infoController;
|
||||
public:
|
||||
RootController(OATPP_COMPONENT(std::shared_ptr<ObjectMapper>, objectMapper))
|
||||
: oatpp::web::server::api::ApiController(objectMapper),
|
||||
m_infoController(std::make_shared<InfoController>(objectMapper))
|
||||
{}
|
||||
public:
|
||||
|
||||
// oatpp::web::server::api::Endpoints(m_infoController, "/info");
|
||||
|
||||
ENDPOINT("GET", "/hello", root) {
|
||||
auto dto = MyDto::createShared();
|
||||
dto->message = "Hello World!";
|
||||
return createDtoResponse(Status::CODE_200, dto);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#include OATPP_CODEGEN_END(ApiController)
|
||||
|
||||
#endif /* RootController_hpp */
|
||||
37
src/api/controller/info/InfoController.hpp
Normal file
37
src/api/controller/info/InfoController.hpp
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
#ifndef InfoController_hpp
|
||||
#define InfoController_hpp
|
||||
|
||||
#include "oatpp/web/server/api/ApiController.hpp"
|
||||
#include "oatpp/core/macro/codegen.hpp"
|
||||
#include "oatpp/core/macro/component.hpp"
|
||||
|
||||
#include OATPP_CODEGEN_BEGIN(ApiController)
|
||||
|
||||
class InfoController : public oatpp::web::server::api::ApiController {
|
||||
public:
|
||||
InfoController(OATPP_COMPONENT(std::shared_ptr<ObjectMapper>, objectMapper))
|
||||
: oatpp::web::server::api::ApiController(objectMapper)
|
||||
{}
|
||||
public:
|
||||
|
||||
ENDPOINT_INFO(version) {
|
||||
info->summary = "Get API version";
|
||||
info->description = "Returns the current version of the API.";
|
||||
}
|
||||
ENDPOINT("GET", "/version", version) {
|
||||
return createResponse(Status::CODE_200, "v0.0.1");
|
||||
}
|
||||
|
||||
ENDPOINT_INFO(root) {
|
||||
info->summary = "Get info root";
|
||||
info->description = "Returns a placeholder for the info root.";
|
||||
}
|
||||
ENDPOINT("GET", "/", root) {
|
||||
return createResponse(Status::CODE_200, "Info root");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#include OATPP_CODEGEN_END(ApiController)
|
||||
|
||||
#endif /* InfoController_hpp */
|
||||
36
src/api/dto/DTOs.hpp
Normal file
36
src/api/dto/DTOs.hpp
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright (c) 2014-2018 Zano Project
|
||||
// Copyright (c) 2014-2018 The Louisdor Project
|
||||
// Copyright (c) 2012-2013 The Boolberry developers
|
||||
// Copyright (c) 2017-2025 Lethean (https://lt.hn)
|
||||
//
|
||||
// Licensed under the European Union Public Licence (EUPL) version 1.2.
|
||||
// You may obtain a copy of the licence at:
|
||||
//
|
||||
// https://joinup.ec.europa.eu/software/page/eupl/licence-eupl
|
||||
//
|
||||
// The EUPL is a copyleft licence that is compatible with the MIT/X11
|
||||
// licence used by the original projects; the MIT terms are therefore
|
||||
// considered “grandfathered” under the EUPL for this code.
|
||||
//
|
||||
// SPDX‑License‑Identifier: EUPL-1.2
|
||||
//
|
||||
|
||||
#ifndef DTOs_hpp
|
||||
#define DTOs_hpp
|
||||
|
||||
#include "oatpp/core/macro/codegen.hpp"
|
||||
#include "oatpp/core/Types.hpp"
|
||||
|
||||
#include OATPP_CODEGEN_BEGIN(DTO)
|
||||
|
||||
class MyDto : public oatpp::DTO {
|
||||
|
||||
DTO_INIT(MyDto, DTO);
|
||||
|
||||
DTO_FIELD(String, message);
|
||||
|
||||
};
|
||||
|
||||
#include OATPP_CODEGEN_END(DTO)
|
||||
|
||||
#endif /* DTOs_hpp */
|
||||
76
src/api/main.cpp
Normal file
76
src/api/main.cpp
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
#include "controller/RootController.hpp"
|
||||
#include "ApiServer.hpp"
|
||||
|
||||
#include "oatpp/network/Server.hpp"
|
||||
#include "oatpp-swagger/Controller.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
void run() {
|
||||
/* Register Components in scope of run() method */
|
||||
ApiServer components;
|
||||
|
||||
/* Get router component */
|
||||
OATPP_COMPONENT(std::shared_ptr<oatpp::web::server::HttpRouter>, router);
|
||||
|
||||
/* Create RootController and add all of its endpoints to router */
|
||||
auto rootController = std::make_shared<RootController>();
|
||||
router->addController(rootController);
|
||||
|
||||
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::swagger::DocumentInfo>, swaggerDocumentInfo)([] {
|
||||
|
||||
oatpp::swagger::DocumentInfo::Builder builder;
|
||||
|
||||
builder
|
||||
.setTitle("Lethean Blockchain API")
|
||||
.setDescription("New API layer for Lethean")
|
||||
.setVersion("1.0")
|
||||
.setContactName("Lethean")
|
||||
.setContactUrl("https://lt.hn/")
|
||||
|
||||
.setLicenseName("EUPL-1.2")
|
||||
.setLicenseUrl("https://joinup.ec.europa.eu/software/page/eupl/licence-eupl")
|
||||
|
||||
.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();
|
||||
|
||||
}());
|
||||
|
||||
/* Create Swagger-UI controller and add its endpoints to router */
|
||||
auto swaggerController = oatpp::swagger::Controller::createShared(rootController->getEndpoints());
|
||||
router->addController(swaggerController);
|
||||
|
||||
/* Get connection handler component */
|
||||
OATPP_COMPONENT(std::shared_ptr<oatpp::network::ConnectionHandler>, connectionHandler);
|
||||
|
||||
/* Get connection provider component */
|
||||
OATPP_COMPONENT(std::shared_ptr<oatpp::network::ServerConnectionProvider>, connectionProvider);
|
||||
|
||||
/* Create server which takes provided TCP connections and passes them to HTTP connection handler */
|
||||
oatpp::network::Server server(connectionProvider, connectionHandler);
|
||||
|
||||
/* Print server port */
|
||||
OATPP_LOGI("lethean-api", "Server running on port %s", connectionProvider->getProperty("port").getData());
|
||||
|
||||
/* Run server */
|
||||
server.run();
|
||||
}
|
||||
|
||||
int main(int argc, const char * argv[]) {
|
||||
|
||||
oatpp::base::Environment::init();
|
||||
|
||||
run();
|
||||
|
||||
/* Destroy oatpp Environment */
|
||||
oatpp::base::Environment::destroy();
|
||||
|
||||
return 0;
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue