mirror of
https://github.com/oatpp/oatpp-swagger.git
synced 2024-11-21 03:12:00 +08:00
Configure controller paths dynamically - improves (#58)
This commit is contained in:
parent
a4e0e32398
commit
2bd4ab11ab
@ -98,13 +98,6 @@ message("\n#####################################################################
|
||||
###################################################################################################
|
||||
## define targets
|
||||
|
||||
set(SWAGGER_ROOT_PATH "/swagger" CACHE STRING "Default root path to the Swagger")
|
||||
set(SWAGGER_UI_PATH "/ui" CACHE STRING "Default path suffix to the Swagger UI")
|
||||
add_compile_definitions(
|
||||
SWAGGER_ROOT_PATH="${SWAGGER_ROOT_PATH}"
|
||||
SWAGGER_UI_PATH="${SWAGGER_UI_PATH}"
|
||||
)
|
||||
|
||||
include(cmake/module-utils.cmake)
|
||||
|
||||
include(cmake/msvc-runtime.cmake)
|
||||
|
27
README.md
27
README.md
@ -113,14 +113,6 @@ endif()
|
||||
include_directories(${oatpp_INCLUDE_DIRS})
|
||||
include_directories(${oatpp-swagger_INCLUDE_DIRS})
|
||||
|
||||
set(SWAGGER_ROOT_PATH "/swagger" CACHE STRING "Default root path to the Swagger")
|
||||
set(SWAGGER_UI_PATH "/ui" CACHE STRING "Default path suffix to the Swagger UI")
|
||||
|
||||
add_compile_definitions(
|
||||
SWAGGER_ROOT_PATH="${SWAGGER_ROOT_PATH}"
|
||||
SWAGGER_UI_PATH="${SWAGGER_UI_PATH}"
|
||||
)
|
||||
|
||||
add_definitions(
|
||||
-DOATPP_SWAGGER_RES_PATH="${OATPP_BASE_DIR}/bin/oatpp-swagger/res"
|
||||
)
|
||||
@ -132,4 +124,23 @@ target_link_libraries (project PUBLIC
|
||||
)
|
||||
```
|
||||
|
||||
### Customise Swagger UI Paths
|
||||
|
||||
To customise swagger UI endpoints paths add the following component:
|
||||
|
||||
```c++
|
||||
/**
|
||||
* Swagger Controller Paths
|
||||
*/
|
||||
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::swagger::ControllerPaths>, controllerPaths)([] {
|
||||
auto paths = std::make_shared<oatpp::swagger::ControllerPaths>();
|
||||
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;
|
||||
}());
|
||||
```
|
||||
|
||||
**NOTE:** `paths->ui` and `paths->uiResources` MUST have the same base path - as shown above.
|
||||
|
||||
**Done!**
|
||||
|
@ -39,7 +39,7 @@
|
||||
window.onload = function() {
|
||||
// Begin Swagger UI call region
|
||||
const ui = SwaggerUIBundle({
|
||||
url: "/api-docs/oas-3.0.0.json",
|
||||
url: "/%%API.JSON%%",
|
||||
dom_id: '#swagger-ui',
|
||||
deepLinking: true,
|
||||
presets: [
|
||||
|
@ -2,6 +2,7 @@
|
||||
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
|
||||
@ -9,8 +10,7 @@ add_library(${OATPP_THIS_MODULE_NAME}
|
||||
oatpp-swagger/Resources.hpp
|
||||
oatpp-swagger/Types.cpp
|
||||
oatpp-swagger/Types.hpp
|
||||
oatpp-swagger/oas3/Model.hpp
|
||||
)
|
||||
oatpp-swagger/oas3/Model.hpp)
|
||||
|
||||
set_target_properties(${OATPP_THIS_MODULE_NAME} PROPERTIES
|
||||
CXX_STANDARD 11
|
||||
|
@ -25,9 +25,11 @@
|
||||
#ifndef oatpp_swagger_AsyncController_hpp
|
||||
#define oatpp_swagger_AsyncController_hpp
|
||||
|
||||
#include "oatpp-swagger/ControllerPaths.hpp"
|
||||
#include "oatpp-swagger/Resources.hpp"
|
||||
#include "oatpp-swagger/Generator.hpp"
|
||||
|
||||
#include "oatpp/web/protocol/http/outgoing/StreamingBody.hpp"
|
||||
#include "oatpp/web/server/api/ApiController.hpp"
|
||||
|
||||
#include "oatpp/parser/json/mapping/ObjectMapper.hpp"
|
||||
@ -51,16 +53,20 @@ namespace oatpp { namespace swagger {
|
||||
class AsyncController : public oatpp::web::server::api::ApiController {
|
||||
public:
|
||||
typedef AsyncController __ControllerType;
|
||||
public:
|
||||
private:
|
||||
oatpp::Object<oas3::Document> m_document;
|
||||
std::shared_ptr<oatpp::swagger::Resources> m_resources;
|
||||
private:
|
||||
ControllerPaths m_paths;
|
||||
public:
|
||||
AsyncController(const std::shared_ptr<ObjectMapper>& objectMapper,
|
||||
const oatpp::Object<oas3::Document>& document,
|
||||
const std::shared_ptr<oatpp::swagger::Resources>& resources)
|
||||
const std::shared_ptr<oatpp::swagger::Resources>& resources,
|
||||
const ControllerPaths& paths)
|
||||
: oatpp::web::server::api::ApiController(objectMapper)
|
||||
, m_document(document)
|
||||
, m_resources(resources)
|
||||
, m_paths(paths)
|
||||
{}
|
||||
public:
|
||||
|
||||
@ -92,13 +98,21 @@ public:
|
||||
|
||||
Generator generator(generatorConfig);
|
||||
auto document = generator.generateDocument(documentInfo, endpointsList);
|
||||
|
||||
ControllerPaths paths;
|
||||
try {
|
||||
auto ps = OATPP_GET_COMPONENT(std::shared_ptr<ControllerPaths>);
|
||||
if(ps) paths = *ps;
|
||||
} catch (std::runtime_error&) {
|
||||
// DO nothing.
|
||||
}
|
||||
|
||||
return std::make_shared<AsyncController>(objectMapper, document, resources);
|
||||
return std::make_shared<AsyncController>(objectMapper, document, resources, paths);
|
||||
}
|
||||
|
||||
#include OATPP_CODEGEN_BEGIN(ApiController)
|
||||
|
||||
ENDPOINT_ASYNC("GET", "/api-docs/oas-3.0.0.json", Api) {
|
||||
ENDPOINT_ASYNC("GET", m_paths.apiJson, Api) {
|
||||
|
||||
ENDPOINT_ASYNC_INIT(Api)
|
||||
|
||||
@ -108,23 +122,40 @@ public:
|
||||
|
||||
};
|
||||
|
||||
ENDPOINT_ASYNC("GET", SWAGGER_ROOT_PATH SWAGGER_UI_PATH, GetUIRoot) {
|
||||
ENDPOINT_ASYNC("GET", m_paths.ui, GetUIRoot) {
|
||||
|
||||
ENDPOINT_ASYNC_INIT(GetUIRoot)
|
||||
|
||||
Action act() override {
|
||||
return _return(controller->createResponse(Status::CODE_200, controller->m_resources->getResource("index.html")));
|
||||
std::string ui;
|
||||
if(controller->m_resources->isStreaming()) {
|
||||
v_char8 buffer[1024];
|
||||
auto fileStream = controller->m_resources->getResourceStream("index.html");
|
||||
oatpp::data::stream::BufferOutputStream s(1024);
|
||||
oatpp::data::stream::transfer(fileStream, &s, 0, buffer, 1024);
|
||||
ui = s.toString();
|
||||
} else {
|
||||
ui = * controller->m_resources->getResource("index.html"); // * - copy of the index.html
|
||||
}
|
||||
ui.replace(ui.find("%%API.JSON%%"), 12, controller->m_paths.apiJson);
|
||||
return _return(controller->createResponse(Status::CODE_200, ui));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
ENDPOINT_ASYNC("GET", SWAGGER_ROOT_PATH "/{filename}", GetUIResource) {
|
||||
ENDPOINT_ASYNC("GET", m_paths.uiResources, GetUIResource) {
|
||||
|
||||
ENDPOINT_ASYNC_INIT(GetUIResource)
|
||||
|
||||
Action act() override {
|
||||
auto filename = request->getPathVariable("filename");
|
||||
OATPP_ASSERT_HTTP(filename, Status::CODE_400, "filename should not be null")
|
||||
if(controller->m_resources->isStreaming()) {
|
||||
auto body = std::make_shared<oatpp::web::protocol::http::outgoing::StreamingBody>(
|
||||
controller->m_resources->getResourceStream(filename->c_str())
|
||||
);
|
||||
return _return(OutgoingResponse::createShared(Status::CODE_200, body));
|
||||
}
|
||||
return _return(controller->createResponse(Status::CODE_200, controller->m_resources->getResource(filename->c_str())));
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
#ifndef oatpp_swagger_Controller_hpp
|
||||
#define oatpp_swagger_Controller_hpp
|
||||
|
||||
#include "oatpp-swagger/ControllerPaths.hpp"
|
||||
#include "oatpp-swagger/Resources.hpp"
|
||||
#include "oatpp-swagger/Generator.hpp"
|
||||
|
||||
@ -53,13 +54,17 @@ class Controller : public oatpp::web::server::api::ApiController {
|
||||
private:
|
||||
oatpp::Object<oas3::Document> m_document;
|
||||
std::shared_ptr<oatpp::swagger::Resources> m_resources;
|
||||
private:
|
||||
ControllerPaths m_paths;
|
||||
public:
|
||||
Controller(const std::shared_ptr<ObjectMapper>& objectMapper,
|
||||
const oatpp::Object<oas3::Document>& document,
|
||||
const std::shared_ptr<oatpp::swagger::Resources>& resources)
|
||||
const std::shared_ptr<oatpp::swagger::Resources>& resources,
|
||||
const ControllerPaths& paths)
|
||||
: oatpp::web::server::api::ApiController(objectMapper)
|
||||
, m_document(document)
|
||||
, m_resources(resources)
|
||||
, m_paths(paths)
|
||||
{}
|
||||
public:
|
||||
|
||||
@ -85,33 +90,46 @@ public:
|
||||
std::shared_ptr<Generator::Config> generatorConfig;
|
||||
try {
|
||||
generatorConfig = OATPP_GET_COMPONENT(std::shared_ptr<Generator::Config>);
|
||||
} catch (std::runtime_error e) {
|
||||
} catch (std::runtime_error&) {
|
||||
generatorConfig = std::make_shared<Generator::Config>();
|
||||
}
|
||||
|
||||
Generator generator(generatorConfig);
|
||||
auto document = generator.generateDocument(documentInfo, endpointsList);
|
||||
|
||||
return std::make_shared<Controller>(objectMapper, document, resources);
|
||||
|
||||
ControllerPaths paths;
|
||||
try {
|
||||
auto ps = OATPP_GET_COMPONENT(std::shared_ptr<ControllerPaths>);
|
||||
if(ps) paths = *ps;
|
||||
} catch (std::runtime_error&) {
|
||||
// DO nothing.
|
||||
}
|
||||
|
||||
return std::make_shared<Controller>(objectMapper, document, resources, paths);
|
||||
}
|
||||
|
||||
#include OATPP_CODEGEN_BEGIN(ApiController)
|
||||
|
||||
ENDPOINT("GET", "/api-docs/oas-3.0.0.json", api) {
|
||||
ENDPOINT("GET", m_paths.apiJson, api) {
|
||||
return createDtoResponse(Status::CODE_200, m_document);
|
||||
}
|
||||
|
||||
ENDPOINT("GET", SWAGGER_ROOT_PATH SWAGGER_UI_PATH, getUIRoot) {
|
||||
ENDPOINT("GET", m_paths.ui, getUIRoot) {
|
||||
std::string ui;
|
||||
if(m_resources->isStreaming()) {
|
||||
auto body = std::make_shared<oatpp::web::protocol::http::outgoing::StreamingBody>(
|
||||
m_resources->getResourceStream("index.html")
|
||||
);
|
||||
return OutgoingResponse::createShared(Status::CODE_200, body);
|
||||
v_char8 buffer[1024];
|
||||
auto fileStream = m_resources->getResourceStream("index.html");
|
||||
oatpp::data::stream::BufferOutputStream s(1024);
|
||||
oatpp::data::stream::transfer(fileStream, &s, 0, buffer, 1024);
|
||||
ui = s.toString();
|
||||
} else {
|
||||
ui = *m_resources->getResource("index.html"); // * - copy of the index.html
|
||||
}
|
||||
return createResponse(Status::CODE_200, m_resources->getResource("index.html"));
|
||||
ui.replace(ui.find("%%API.JSON%%"), 12, m_paths.apiJson);
|
||||
return createResponse(Status::CODE_200, ui);
|
||||
}
|
||||
|
||||
ENDPOINT("GET", SWAGGER_ROOT_PATH "/{filename}", getUIResource, PATH(String, filename)) {
|
||||
ENDPOINT("GET", m_paths.uiResources, getUIResource, PATH(String, filename)) {
|
||||
if(m_resources->isStreaming()) {
|
||||
auto body = std::make_shared<oatpp::web::protocol::http::outgoing::StreamingBody>(
|
||||
m_resources->getResourceStream(filename->c_str())
|
||||
|
56
src/oatpp-swagger/ControllerPaths.hpp
Normal file
56
src/oatpp-swagger/ControllerPaths.hpp
Normal file
@ -0,0 +1,56 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* Project _____ __ ____ _ _
|
||||
* ( _ ) /__\ (_ _)_| |_ _| |_
|
||||
* )(_)( /(__)\ )( (_ _)(_ _)
|
||||
* (_____)(__)(__)(__) |_| |_|
|
||||
*
|
||||
*
|
||||
* Copyright 2018-present, Leonid Stryzhevskyi, <lganzzzo@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef oatpp_swagger_ControllerPaths_hpp
|
||||
#define oatpp_swagger_ControllerPaths_hpp
|
||||
|
||||
#include "oatpp/core/Types.hpp"
|
||||
|
||||
namespace oatpp { namespace swagger {
|
||||
|
||||
/**
|
||||
* Swagger Controller endpoints paths.
|
||||
*/
|
||||
struct ControllerPaths {
|
||||
|
||||
/**
|
||||
* Path to generated API JSON.
|
||||
*/
|
||||
oatpp::String apiJson = "api-docs/oas-3.0.0.json";
|
||||
|
||||
/**
|
||||
* Path to swagger UI (index.html).
|
||||
*/
|
||||
oatpp::String ui = "swagger/ui";
|
||||
|
||||
/**
|
||||
* Path to other ui resources. MUST contain `/{filename}` at the end.
|
||||
*/
|
||||
oatpp::String uiResources = "swagger/{filename}";
|
||||
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif //oatpp_swagger_ControllerPaths_hpp
|
Loading…
Reference in New Issue
Block a user