forked from loafle/openapi-generator-original
[C++][Pistache] Generate API generalization interface (#15279)
* [C++][Pistache] Refactor setupSupportingFiles Supporting files are set up in the CppPistacheServerCodegen() constructor as well as in processOpts(). Refactor the code and extract a method setupSupportingFiles(). * [C++][Pistache] Refactor: Simplify isQueryParam condition Both branches of the if/else do the same steps. Refactor this out and invert logic. * [C++][Pistache] Refactor: Add injectImplInFilename Both branches of the if/else if do the similar steps and are dependent on the suffix. Make this obvious by introducing a new method injectImplInFilename(String result, String suffix). * [C++][Pistache] Refactor: injectImplInFilename: remove index search We do not need the separatorChar index to inject the "Impl" string. Simply truncate the whole string. Also rename the parameter from 'result' to' filename'. * CppPistacheServer: Refactor postProcessOperationsWithModels Pull out the post-processing for a single operation, and also pull out post-processing for parameters. Introduce boolean expressions for supported parsing per parameter, and consumption of JSON. Reorder code to make locality more explicit i.e. how consumeJSON and isParsingSupported is generated and used. * CppPistacheServer: Refactor to use functional matching Functional matching like anyMatch() directly state what boolean value is searched. However, the Predicates deserve to heave names themselves. * CppPistacheServer: Add base class for Api Looking at the generated main-api-server.cpp code it gets obvious that the API classes are self similar with a similar interface. Only the construction and teh initialization is called in the main() function. Leverage this fact to create a generalization ApiBase. Introduce ApiBase as a pure virtual base class to the concrete API classes and declare init() as virtual. Pull the route member into the base class. With this change we could have a container hold all the ApiImpl objects later and call init() on all of them using a for_each loop. * CppPistacheServer: Use ApiBase for ApiImpl storage Refactor the main-api-server template to use a vector for ApiImpl storage instead of separate objects. This leverages the previously added ApiBase generalization. We push all concrete ApiImpl objects into a vector and call init() on each of them. * [C++][Pistache]: Update generated sample Due to teh addition of ApiBase class update the generated sample. * [C++][Pistache] Add comment for postProcessSingleParam * [C++][Pistache] Rename and comment implFilenameFromApiFilename While writing the comment, I realized that the method name could be more precise. Thus rename injectImplInFilename to implFilenameFromApiFilename and add comment.
This commit is contained in:
+87
-69
@@ -34,6 +34,7 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import static org.openapitools.codegen.utils.StringUtils.underscore;
|
||||
|
||||
@@ -113,11 +114,7 @@ public class CppPistacheServerCodegen extends AbstractCppCodegen {
|
||||
VARIABLE_NAME_FIRST_CHARACTER_UPPERCASE_DESC,
|
||||
Boolean.toString(this.variableNameFirstCharacterUppercase));
|
||||
|
||||
supportingFiles.add(new SupportingFile("helpers-header.mustache", "model", modelNamePrefix + "Helpers.h"));
|
||||
supportingFiles.add(new SupportingFile("helpers-source.mustache", "model", modelNamePrefix + "Helpers.cpp"));
|
||||
supportingFiles.add(new SupportingFile("main-api-server.mustache", "", modelNamePrefix + "main-api-server.cpp"));
|
||||
supportingFiles.add(new SupportingFile("cmake.mustache", "", "CMakeLists.txt"));
|
||||
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
|
||||
setupSupportingFiles();
|
||||
|
||||
languageSpecificPrimitives = new HashSet<>(
|
||||
Arrays.asList("int", "char", "bool", "long", "float", "double", "int32_t", "int64_t"));
|
||||
@@ -149,6 +146,16 @@ public class CppPistacheServerCodegen extends AbstractCppCodegen {
|
||||
importMapping.put("nlohmann::json", "#include <nlohmann/json.hpp>");
|
||||
}
|
||||
|
||||
private void setupSupportingFiles() {
|
||||
supportingFiles.clear();
|
||||
supportingFiles.add(new SupportingFile("api-base-header.mustache", "api", "ApiBase.h"));
|
||||
supportingFiles.add(new SupportingFile("helpers-header.mustache", "model", modelNamePrefix + "Helpers.h"));
|
||||
supportingFiles.add(new SupportingFile("helpers-source.mustache", "model", modelNamePrefix + "Helpers.cpp"));
|
||||
supportingFiles.add(new SupportingFile("main-api-server.mustache", "", modelNamePrefix + "main-api-server.cpp"));
|
||||
supportingFiles.add(new SupportingFile("cmake.mustache", "", "CMakeLists.txt"));
|
||||
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processOpts() {
|
||||
super.processOpts();
|
||||
@@ -157,12 +164,7 @@ public class CppPistacheServerCodegen extends AbstractCppCodegen {
|
||||
}
|
||||
if (additionalProperties.containsKey("modelNamePrefix")) {
|
||||
additionalProperties().put("prefix", modelNamePrefix);
|
||||
supportingFiles.clear();
|
||||
supportingFiles.add(new SupportingFile("helpers-header.mustache", "model", modelNamePrefix + "Helpers.h"));
|
||||
supportingFiles.add(new SupportingFile("helpers-source.mustache", "model", modelNamePrefix + "Helpers.cpp"));
|
||||
supportingFiles.add(new SupportingFile("main-api-server.mustache", "", modelNamePrefix + "main-api-server.cpp"));
|
||||
supportingFiles.add(new SupportingFile("cmake.mustache", "", "CMakeLists.txt"));
|
||||
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
|
||||
setupSupportingFiles();
|
||||
}
|
||||
if (additionalProperties.containsKey(RESERVED_WORD_PREFIX_OPTION)) {
|
||||
reservedWordPrefix = (String) additionalProperties.get(RESERVED_WORD_PREFIX_OPTION);
|
||||
@@ -267,63 +269,69 @@ public class CppPistacheServerCodegen extends AbstractCppCodegen {
|
||||
operations.put("classnameSnakeLowerCase", underscore(classname).toLowerCase(Locale.ROOT));
|
||||
List<CodegenOperation> operationList = operations.getOperation();
|
||||
for (CodegenOperation op : operationList) {
|
||||
boolean consumeJson = false;
|
||||
boolean isParsingSupported = true;
|
||||
if (op.bodyParam != null) {
|
||||
if (op.bodyParam.vendorExtensions == null) {
|
||||
op.bodyParam.vendorExtensions = new HashMap<>();
|
||||
}
|
||||
|
||||
boolean isStringOrDate = op.bodyParam.isString || op.bodyParam.isDate;
|
||||
op.bodyParam.vendorExtensions.put("x-codegen-pistache-is-string-or-date", isStringOrDate);
|
||||
}
|
||||
if (op.consumes != null) {
|
||||
for (Map<String, String> consume : op.consumes) {
|
||||
if (consume.get("mediaType") != null && consume.get("mediaType").equals("application/json")) {
|
||||
consumeJson = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
op.httpMethod = op.httpMethod.substring(0, 1).toUpperCase(Locale.ROOT) + op.httpMethod.substring(1).toLowerCase(Locale.ROOT);
|
||||
|
||||
for (CodegenParameter param : op.allParams) {
|
||||
if (param.isFormParam) isParsingSupported = false;
|
||||
if (param.isFile) isParsingSupported = false;
|
||||
if (param.isCookieParam) isParsingSupported = false;
|
||||
|
||||
//TODO: This changes the info about the real type but it is needed to parse the header params
|
||||
if (param.isHeaderParam) {
|
||||
param.dataType = "std::optional<Pistache::Http::Header::Raw>";
|
||||
param.baseType = "std::optional<Pistache::Http::Header::Raw>";
|
||||
} else if (param.isQueryParam) {
|
||||
if (param.isPrimitiveType) {
|
||||
param.dataType = "std::optional<" + param.dataType + ">";
|
||||
} else {
|
||||
param.dataType = "std::optional<" + param.dataType + ">";
|
||||
param.baseType = "std::optional<" + param.baseType + ">";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (op.vendorExtensions == null) {
|
||||
op.vendorExtensions = new HashMap<>();
|
||||
}
|
||||
op.vendorExtensions.put("x-codegen-pistache-consumes-json", consumeJson);
|
||||
op.vendorExtensions.put("x-codegen-pistache-is-parsing-supported", isParsingSupported);
|
||||
|
||||
// Check if any one of the operations needs a model, then at API file level, at least one model has to be included.
|
||||
for (String hdr : op.imports) {
|
||||
if (importMapping.containsKey(hdr)) {
|
||||
continue;
|
||||
}
|
||||
operations.put("hasModelImport", true);
|
||||
}
|
||||
postProcessSingleOperation(operations, op);
|
||||
}
|
||||
|
||||
return objs;
|
||||
}
|
||||
|
||||
private void postProcessSingleOperation(OperationMap operations, CodegenOperation op) {
|
||||
if (op.vendorExtensions == null) {
|
||||
op.vendorExtensions = new HashMap<>();
|
||||
}
|
||||
|
||||
if (op.bodyParam != null) {
|
||||
if (op.bodyParam.vendorExtensions == null) {
|
||||
op.bodyParam.vendorExtensions = new HashMap<>();
|
||||
}
|
||||
|
||||
boolean isStringOrDate = op.bodyParam.isString || op.bodyParam.isDate;
|
||||
op.bodyParam.vendorExtensions.put("x-codegen-pistache-is-string-or-date", isStringOrDate);
|
||||
}
|
||||
|
||||
boolean consumeJson = false;
|
||||
if (op.consumes != null) {
|
||||
Predicate<Map<String,String>> isMediaTypeJson = consume -> (consume.get("mediaType") != null && consume.get("mediaType").equals("application/json"));
|
||||
consumeJson = op.consumes.stream().anyMatch(isMediaTypeJson);
|
||||
}
|
||||
op.vendorExtensions.put("x-codegen-pistache-consumes-json", consumeJson);
|
||||
|
||||
op.httpMethod = op.httpMethod.substring(0, 1).toUpperCase(Locale.ROOT) + op.httpMethod.substring(1).toLowerCase(Locale.ROOT);
|
||||
|
||||
boolean isParsingSupported = true;
|
||||
for (CodegenParameter param : op.allParams) {
|
||||
boolean paramSupportsParsing = (!param.isFormParam && !param.isFile && !param.isCookieParam);
|
||||
isParsingSupported = isParsingSupported && paramSupportsParsing;
|
||||
|
||||
postProcessSingleParam(param);
|
||||
}
|
||||
op.vendorExtensions.put("x-codegen-pistache-is-parsing-supported", isParsingSupported);
|
||||
|
||||
// Check if any one of the operations needs a model, then at API file level, at least one model has to be included.
|
||||
Predicate<String> importNotInImportMapping = hdr -> !importMapping.containsKey(hdr);
|
||||
if (op.imports.stream().anyMatch(importNotInImportMapping)) {
|
||||
operations.put("hasModelImport", true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* postProcessSingleParam - Modifies a single parameter, adjusting generated
|
||||
* data types for Header and Query parameters.
|
||||
* @param param CodegenParameter to be modified.
|
||||
*/
|
||||
private static void postProcessSingleParam(CodegenParameter param) {
|
||||
//TODO: This changes the info about the real type but it is needed to parse the header params
|
||||
if (param.isHeaderParam) {
|
||||
param.dataType = "std::optional<Pistache::Http::Header::Raw>";
|
||||
param.baseType = "std::optional<Pistache::Http::Header::Raw>";
|
||||
} else if (param.isQueryParam) {
|
||||
param.dataType = "std::optional<" + param.dataType + ">";
|
||||
if (!param.isPrimitiveType) {
|
||||
param.baseType = "std::optional<" + param.baseType + ">";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toModelFilename(String name) {
|
||||
return toModelName(name);
|
||||
@@ -334,17 +342,27 @@ public class CppPistacheServerCodegen extends AbstractCppCodegen {
|
||||
String result = super.apiFilename(templateName, tag);
|
||||
|
||||
if (templateName.endsWith("impl-header.mustache")) {
|
||||
int ix = result.lastIndexOf(File.separatorChar);
|
||||
result = result.substring(0, ix) + result.substring(ix, result.length() - 2) + "Impl.h";
|
||||
result = result.replace(apiFileFolder(), implFileFolder());
|
||||
result = implFilenameFromApiFilename(result, ".h");
|
||||
} else if (templateName.endsWith("impl-source.mustache")) {
|
||||
int ix = result.lastIndexOf(File.separatorChar);
|
||||
result = result.substring(0, ix) + result.substring(ix, result.length() - 4) + "Impl.cpp";
|
||||
result = result.replace(apiFileFolder(), implFileFolder());
|
||||
result = implFilenameFromApiFilename(result, ".cpp");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* implFilenameFromApiFilename - Inserts the string "Impl" in front of the
|
||||
* suffix and replace "api" with "impl" directory prefix.
|
||||
*
|
||||
* @param filename Filename of the api-file to be modified
|
||||
* @param suffix Suffix of the file (usually ".cpp" or ".h")
|
||||
* @return a filename string of impl file.
|
||||
*/
|
||||
private String implFilenameFromApiFilename(String filename, String suffix) {
|
||||
String result = filename.substring(0, filename.length() - suffix.length()) + "Impl" + suffix;
|
||||
result = result.replace(apiFileFolder(), implFileFolder());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toApiFilename(String name) {
|
||||
return toApiName(name);
|
||||
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
{{>licenseInfo}}
|
||||
/*
|
||||
* ApiBase.h
|
||||
*
|
||||
* Generalization of the Api classes
|
||||
*/
|
||||
|
||||
#ifndef ApiBase_H_
|
||||
#define ApiBase_H_
|
||||
|
||||
#include <pistache/router.h>
|
||||
#include <memory>
|
||||
|
||||
namespace {{apiNamespace}}
|
||||
{
|
||||
|
||||
class ApiBase {
|
||||
public:
|
||||
explicit ApiBase(const std::shared_ptr<Pistache::Rest::Router>& rtr) : router(rtr) {};
|
||||
virtual ~ApiBase() = default;
|
||||
virtual void init() = 0;
|
||||
|
||||
protected:
|
||||
const std::shared_ptr<Pistache::Rest::Router> router;
|
||||
};
|
||||
|
||||
} // namespace {{apiNamespace}}
|
||||
|
||||
#endif /* ApiBase_H_ */
|
||||
+3
-3
@@ -9,6 +9,8 @@
|
||||
#define {{classname}}_H_
|
||||
|
||||
{{{defaultInclude}}}
|
||||
#include "ApiBase.h"
|
||||
|
||||
#include <pistache/http.h>
|
||||
#include <pistache/router.h>
|
||||
#include <pistache/http_headers.h>
|
||||
@@ -22,7 +24,7 @@
|
||||
namespace {{apiNamespace}}
|
||||
{
|
||||
|
||||
class {{declspec}} {{classname}} {
|
||||
class {{declspec}} {{classname}} : public ApiBase {
|
||||
public:
|
||||
explicit {{classname}}(const std::shared_ptr<Pistache::Rest::Router>& rtr);
|
||||
virtual ~{{classname}}() = default;
|
||||
@@ -38,8 +40,6 @@ private:
|
||||
{{/operation}}
|
||||
void {{classnameSnakeLowerCase}}_default_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
|
||||
|
||||
const std::shared_ptr<Pistache::Rest::Router> router;
|
||||
|
||||
/// <summary>
|
||||
/// Helper function to handle unexpected Exceptions during Parameter parsing and validation.
|
||||
/// May be overridden to return custom error formats. This is called inside a catch block.
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ using namespace {{modelNamespace}};{{/hasModelImport}}
|
||||
const std::string {{classname}}::base = "{{basePathWithoutHost}}";
|
||||
|
||||
{{classname}}::{{classname}}(const std::shared_ptr<Pistache::Rest::Router>& rtr)
|
||||
: router(rtr)
|
||||
: ApiBase(rtr)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
+8
-3
@@ -9,6 +9,8 @@
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "ApiBase.h"
|
||||
{{#apiInfo}}{{#apis}}{{#operations}}
|
||||
#include "{{classname}}Impl.h"{{/operations}}{{/apis}}{{/apiInfo}}
|
||||
|
||||
@@ -66,13 +68,16 @@ int main() {
|
||||
opts.maxResponseSize(PISTACHE_SERVER_MAX_RESPONSE_SIZE);
|
||||
httpEndpoint->init(opts);
|
||||
|
||||
auto apiImpls = std::vector<std::shared_ptr<ApiBase>>();
|
||||
{{#apiInfo}}{{#apis}}{{#operations}}
|
||||
{{classname}}Impl {{classname}}server(router);
|
||||
{{classname}}server.init();{{/operations}}{{/apis}}{{/apiInfo}}
|
||||
apiImpls.push_back(std::make_shared<{{classname}}Impl>(router));{{/operations}}{{/apis}}{{/apiInfo}}
|
||||
|
||||
for (auto api : apiImpls) {
|
||||
api->init();
|
||||
}
|
||||
|
||||
httpEndpoint->setHandler(router->handler());
|
||||
httpEndpoint->serve();
|
||||
|
||||
httpEndpoint->shutdown();
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
CMakeLists.txt
|
||||
README.md
|
||||
api/ApiBase.h
|
||||
api/PetApi.cpp
|
||||
api/PetApi.h
|
||||
api/StoreApi.cpp
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* OpenAPI Petstore
|
||||
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0
|
||||
*
|
||||
*
|
||||
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||
* https://openapi-generator.tech
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
/*
|
||||
* ApiBase.h
|
||||
*
|
||||
* Generalization of the Api classes
|
||||
*/
|
||||
|
||||
#ifndef ApiBase_H_
|
||||
#define ApiBase_H_
|
||||
|
||||
#include <pistache/router.h>
|
||||
#include <memory>
|
||||
|
||||
namespace org::openapitools::server::api
|
||||
{
|
||||
|
||||
class ApiBase {
|
||||
public:
|
||||
explicit ApiBase(const std::shared_ptr<Pistache::Rest::Router>& rtr) : router(rtr) {};
|
||||
virtual ~ApiBase() = default;
|
||||
virtual void init() = 0;
|
||||
|
||||
protected:
|
||||
const std::shared_ptr<Pistache::Rest::Router> router;
|
||||
};
|
||||
|
||||
} // namespace org::openapitools::server::api
|
||||
|
||||
#endif /* ApiBase_H_ */
|
||||
@@ -22,7 +22,7 @@ using namespace org::openapitools::server::model;
|
||||
const std::string PetApi::base = "/v2";
|
||||
|
||||
PetApi::PetApi(const std::shared_ptr<Pistache::Rest::Router>& rtr)
|
||||
: router(rtr)
|
||||
: ApiBase(rtr)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
#define PetApi_H_
|
||||
|
||||
|
||||
#include "ApiBase.h"
|
||||
|
||||
#include <pistache/http.h>
|
||||
#include <pistache/router.h>
|
||||
#include <pistache/http_headers.h>
|
||||
@@ -33,7 +35,7 @@
|
||||
namespace org::openapitools::server::api
|
||||
{
|
||||
|
||||
class PetApi {
|
||||
class PetApi : public ApiBase {
|
||||
public:
|
||||
explicit PetApi(const std::shared_ptr<Pistache::Rest::Router>& rtr);
|
||||
virtual ~PetApi() = default;
|
||||
@@ -54,8 +56,6 @@ private:
|
||||
void upload_file_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
|
||||
void pet_api_default_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
|
||||
|
||||
const std::shared_ptr<Pistache::Rest::Router> router;
|
||||
|
||||
/// <summary>
|
||||
/// Helper function to handle unexpected Exceptions during Parameter parsing and validation.
|
||||
/// May be overridden to return custom error formats. This is called inside a catch block.
|
||||
|
||||
@@ -22,7 +22,7 @@ using namespace org::openapitools::server::model;
|
||||
const std::string StoreApi::base = "/v2";
|
||||
|
||||
StoreApi::StoreApi(const std::shared_ptr<Pistache::Rest::Router>& rtr)
|
||||
: router(rtr)
|
||||
: ApiBase(rtr)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
#define StoreApi_H_
|
||||
|
||||
|
||||
#include "ApiBase.h"
|
||||
|
||||
#include <pistache/http.h>
|
||||
#include <pistache/router.h>
|
||||
#include <pistache/http_headers.h>
|
||||
@@ -33,7 +35,7 @@
|
||||
namespace org::openapitools::server::api
|
||||
{
|
||||
|
||||
class StoreApi {
|
||||
class StoreApi : public ApiBase {
|
||||
public:
|
||||
explicit StoreApi(const std::shared_ptr<Pistache::Rest::Router>& rtr);
|
||||
virtual ~StoreApi() = default;
|
||||
@@ -50,8 +52,6 @@ private:
|
||||
void place_order_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
|
||||
void store_api_default_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
|
||||
|
||||
const std::shared_ptr<Pistache::Rest::Router> router;
|
||||
|
||||
/// <summary>
|
||||
/// Helper function to handle unexpected Exceptions during Parameter parsing and validation.
|
||||
/// May be overridden to return custom error formats. This is called inside a catch block.
|
||||
|
||||
@@ -22,7 +22,7 @@ using namespace org::openapitools::server::model;
|
||||
const std::string UserApi::base = "/v2";
|
||||
|
||||
UserApi::UserApi(const std::shared_ptr<Pistache::Rest::Router>& rtr)
|
||||
: router(rtr)
|
||||
: ApiBase(rtr)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
#define UserApi_H_
|
||||
|
||||
|
||||
#include "ApiBase.h"
|
||||
|
||||
#include <pistache/http.h>
|
||||
#include <pistache/router.h>
|
||||
#include <pistache/http_headers.h>
|
||||
@@ -33,7 +35,7 @@
|
||||
namespace org::openapitools::server::api
|
||||
{
|
||||
|
||||
class UserApi {
|
||||
class UserApi : public ApiBase {
|
||||
public:
|
||||
explicit UserApi(const std::shared_ptr<Pistache::Rest::Router>& rtr);
|
||||
virtual ~UserApi() = default;
|
||||
@@ -54,8 +56,6 @@ private:
|
||||
void update_user_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
|
||||
void user_api_default_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
|
||||
|
||||
const std::shared_ptr<Pistache::Rest::Router> router;
|
||||
|
||||
/// <summary>
|
||||
/// Helper function to handle unexpected Exceptions during Parameter parsing and validation.
|
||||
/// May be overridden to return custom error formats. This is called inside a catch block.
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "ApiBase.h"
|
||||
|
||||
#include "PetApiImpl.h"
|
||||
#include "StoreApiImpl.h"
|
||||
#include "UserApiImpl.h"
|
||||
@@ -78,17 +80,18 @@ int main() {
|
||||
opts.maxResponseSize(PISTACHE_SERVER_MAX_RESPONSE_SIZE);
|
||||
httpEndpoint->init(opts);
|
||||
|
||||
auto apiImpls = std::vector<std::shared_ptr<ApiBase>>();
|
||||
|
||||
PetApiImpl PetApiserver(router);
|
||||
PetApiserver.init();
|
||||
StoreApiImpl StoreApiserver(router);
|
||||
StoreApiserver.init();
|
||||
UserApiImpl UserApiserver(router);
|
||||
UserApiserver.init();
|
||||
apiImpls.push_back(std::make_shared<PetApiImpl>(router));
|
||||
apiImpls.push_back(std::make_shared<StoreApiImpl>(router));
|
||||
apiImpls.push_back(std::make_shared<UserApiImpl>(router));
|
||||
|
||||
for (auto api : apiImpls) {
|
||||
api->init();
|
||||
}
|
||||
|
||||
httpEndpoint->setHandler(router->handler());
|
||||
httpEndpoint->serve();
|
||||
|
||||
httpEndpoint->shutdown();
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user