Files
openapi-generator/samples/server/petstore/cpp-httplib-server/feature-test/api/ParametersApi.cpp
vasireddyrajesh b96334ffad Add standalone C++ server using cpp-httplib for OpenAPI-based APIs (#21724)
Supports:
All OpenAPI 3.x data types: primitives, arrays, enums, nullable/optional fields, nested objects
All parameter types: path, query, header, cookie, and combinations
Schema composition: allOf (inheritance), oneOf (discriminated unions), anyOf (flexible unions)
Security schemes: API key and bearer token authentication
Discriminator-based polymorphic deserialization and error handling

Provides:
Error handling for invalid JSON, type mismatches, missing/unknown discriminator, and parameter validation
Build system integration (CMake) for easy compilation and linking with required dependencies
Clear build and run instructions for local development and testing
Enables comprehensive, real-world validation of generated C++ server code against OpenAPI specifications
2026-02-12 19:41:05 +08:00

775 lines
25 KiB
C++

/**
* This file is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
// System headers
#include <algorithm>
#include <cctype>
#include <locale>
// Project headers
#include "ParametersApi.h"
constexpr int HTTP_RESPONSE_CODE_TEST_ALL_PARAMETER_TYPES200_RESPONSE = 200;
constexpr int HTTP_RESPONSE_CODE_ERROR_RESPONSE = 400;
constexpr int HTTP_RESPONSE_CODE_TEST_COOKIE_PARAMETERS200_RESPONSE = 200;
constexpr int HTTP_RESPONSE_CODE_TEST_HEADER_PARAMETERS200_RESPONSE = 200;
constexpr int HTTP_RESPONSE_CODE_TEST_HEADER_PARAMETERS401_RESPONSE = 401;
constexpr int HTTP_RESPONSE_CODE_TEST_QUERY_PARAMETERS200_RESPONSE = 200;
constexpr int HTTP_RESPONSE_CODE_INTERNAL_SERVER_ERROR = 500;
namespace api {
using namespace models;
bool Parameters::parseParameterscombinedresourceIdPostParams(const httplib::Request& req, Parameters::ParameterscombinedresourceIdPostRequest& params, std::vector<std::string>& paramErrors)
{
std::vector<std::string> errors;
if (!req.body.empty())
{
try
{
nlohmann::json json = nlohmann::json::parse(req.body);
SimpleObject temp;
from_json(json, temp);
params.m_request = temp;
}
catch (const std::exception& e)
{
errors.push_back("Invalid request body: " + std::string(e.what()));
}
}
// Query Parameters - filter
if (req.has_param("filter"))
{
params.m_filter = req.get_param_value("filter");
}
// Query Parameters - limit
if (req.has_param("limit"))
{
try
{
params.m_limit = std::stoi(req.get_param_value("limit"));
}
catch (const std::exception& e)
{
errors.push_back("Invalid query parameter 'limit': " + std::string(e.what()));
}
}
else
{
// Use default value for optional parameter
params.m_limit = 10;
}
// Header Parameters - X-Correlation-Id
if (!req.get_header_value("X-Correlation-Id").empty())
{
params.m_xCorrelationId = req.get_header_value("X-Correlation-Id");
}
// Header Parameters - X-Client-Version
if (!req.get_header_value("X-Client-Version").empty())
{
params.m_xClientVersion = req.get_header_value("X-Client-Version");
}
else
{
// Use default value for optional parameter
params.m_xClientVersion = "";
}
// Path Parameters - resourceId (index: 1)
if (req.matches.size() < 1 + 1)
{
errors.push_back("Missing path parameter 'resourceId'");
}
else
{
try
{
params.m_resourceId = std::stoi(req.matches[1]);
}
catch (const std::exception& e)
{
errors.push_back("Invalid path parameter 'resourceId': " + std::string(e.what()));
}
}
// Cookie Parameters - authToken
try
{
auto cookieHeader = req.get_header_value("Cookie");
if (!cookieHeader.empty())
{
std::string cookieValue;
std::string key = "authToken=";
size_t start = cookieHeader.find(key);
if (start != std::string::npos)
{
start += key.length();
size_t end = cookieHeader.find(";", start);
if (end == std::string::npos) end = cookieHeader.length();
cookieValue = cookieHeader.substr(start, end - start);
params.m_authToken = cookieValue;
}
}
}
catch (const std::exception& e)
{
errors.push_back("Invalid cookie parameter 'authToken': " + std::string(e.what()));
}
// Cookie Parameters - userPrefs
try
{
auto cookieHeader = req.get_header_value("Cookie");
if (!cookieHeader.empty())
{
std::string cookieValue;
std::string key = "userPrefs=";
size_t start = cookieHeader.find(key);
if (start != std::string::npos)
{
start += key.length();
size_t end = cookieHeader.find(";", start);
if (end == std::string::npos) end = cookieHeader.length();
cookieValue = cookieHeader.substr(start, end - start);
params.m_userPrefs = cookieValue;
}
else
{
// Use default value for optional parameter
params.m_userPrefs = "";
}
}
else
{
// Use default value for optional parameter
params.m_userPrefs = "";
}
}
catch (const std::exception& e)
{
errors.push_back("Invalid cookie parameter 'userPrefs': " + std::string(e.what()));
}
// Return errors via out-parameter, return false if any errors
if (!errors.empty())
{
paramErrors = std::move(errors);
return false;
}
return true;
}
void Parameters::handleParameterscombinedresourceIdPostResponse(const ParameterscombinedresourceIdPostResponse& result, httplib::Response& res)
{
std::visit([&](const auto& value)
{
using T = std::decay_t<decltype(value)>;
// Success types
if constexpr (std::is_same_v<T, models::TestAllParameterTypes200Response>)
{
res.status = HTTP_RESPONSE_CODE_TEST_ALL_PARAMETER_TYPES200_RESPONSE;
nlohmann::json responseJson;
to_json(responseJson, value);
res.set_content(responseJson.dump(), "application/json");
}
// Error types
else if constexpr (std::is_same_v<T, models::ErrorResponse>)
{
res.status = HTTP_RESPONSE_CODE_ERROR_RESPONSE;
nlohmann::json errorJson = value;
res.set_content(errorJson.dump(), "application/json");
}
}, result);
}
bool Parameters::parseParameterscookiesGetParams(const httplib::Request& req, Parameters::ParameterscookiesGetRequest& params, std::vector<std::string>& paramErrors)
{
std::vector<std::string> errors;
// Cookie Parameters - sessionId
try
{
auto cookieHeader = req.get_header_value("Cookie");
if (!cookieHeader.empty())
{
std::string cookieValue;
std::string key = "sessionId=";
size_t start = cookieHeader.find(key);
if (start != std::string::npos)
{
start += key.length();
size_t end = cookieHeader.find(";", start);
if (end == std::string::npos) end = cookieHeader.length();
cookieValue = cookieHeader.substr(start, end - start);
params.m_sessionId = cookieValue;
}
}
}
catch (const std::exception& e)
{
errors.push_back("Invalid cookie parameter 'sessionId': " + std::string(e.what()));
}
// Cookie Parameters - userId
try
{
auto cookieHeader = req.get_header_value("Cookie");
if (!cookieHeader.empty())
{
std::string cookieValue;
std::string key = "userId=";
size_t start = cookieHeader.find(key);
if (start != std::string::npos)
{
start += key.length();
size_t end = cookieHeader.find(";", start);
if (end == std::string::npos) end = cookieHeader.length();
cookieValue = cookieHeader.substr(start, end - start);
params.m_userId = std::stoi(cookieValue);
}
else
{
// Use default value for optional parameter
params.m_userId = 0;
}
}
else
{
// Use default value for optional parameter
params.m_userId = 0;
}
}
catch (const std::exception& e)
{
errors.push_back("Invalid cookie parameter 'userId': " + std::string(e.what()));
}
// Cookie Parameters - preferences
try
{
auto cookieHeader = req.get_header_value("Cookie");
if (!cookieHeader.empty())
{
std::string cookieValue;
std::string key = "preferences=";
size_t start = cookieHeader.find(key);
if (start != std::string::npos)
{
start += key.length();
size_t end = cookieHeader.find(";", start);
if (end == std::string::npos) end = cookieHeader.length();
cookieValue = cookieHeader.substr(start, end - start);
params.m_preferences = cookieValue;
}
else
{
// Use default value for optional parameter
params.m_preferences = "";
}
}
else
{
// Use default value for optional parameter
params.m_preferences = "";
}
}
catch (const std::exception& e)
{
errors.push_back("Invalid cookie parameter 'preferences': " + std::string(e.what()));
}
// Return errors via out-parameter, return false if any errors
if (!errors.empty())
{
paramErrors = std::move(errors);
return false;
}
return true;
}
void Parameters::handleParameterscookiesGetResponse(const ParameterscookiesGetResponse& result, httplib::Response& res)
{
// Single response type
res.status = HTTP_RESPONSE_CODE_TEST_COOKIE_PARAMETERS200_RESPONSE;
nlohmann::json responseJson;
to_json(responseJson, result);
res.set_content(responseJson.dump(), "application/json");
}
bool Parameters::parseParametersheadersGetParams(const httplib::Request& req, Parameters::ParametersheadersGetRequest& params, std::vector<std::string>& paramErrors)
{
std::vector<std::string> errors;
// Header Parameters - X-Api-Version
if (!req.get_header_value("X-Api-Version").empty())
{
params.m_xApiVersion = req.get_header_value("X-Api-Version");
}
// Header Parameters - X-Request-Id
if (!req.get_header_value("X-Request-Id").empty())
{
params.m_xRequestId = req.get_header_value("X-Request-Id");
}
else
{
// Use default value for optional parameter
params.m_xRequestId = "";
}
// Header Parameters - X-Rate-Limit
if (!req.get_header_value("X-Rate-Limit").empty())
{
try
{
params.m_xRateLimit = std::stoi(req.get_header_value("X-Rate-Limit"));
}
catch (const std::exception& e)
{
errors.push_back("Invalid header parameter 'X-Rate-Limit': " + std::string(e.what()));
}
}
else
{
// Use default value for optional parameter
params.m_xRateLimit = 0;
}
// Header Parameters - X-Tags
if (!req.get_header_value("X-Tags").empty())
{
try
{
// Header arrays may be comma-separated
auto val = req.get_header_value("X-Tags");
std::stringstream ss(val);
std::string item;
if (!params.m_xTags.has_value())
{
params.m_xTags = std::vector<std::string>{};
}
while (std::getline(ss, item, ','))
{
if (!item.empty())
{
params.m_xTags->emplace_back(item);
}
}
}
catch (const std::exception& e)
{
errors.push_back("Invalid header parameter 'X-Tags': " + std::string(e.what()));
}
}
// Return errors via out-parameter, return false if any errors
if (!errors.empty())
{
paramErrors = std::move(errors);
return false;
}
return true;
}
void Parameters::handleParametersheadersGetResponse(const ParametersheadersGetResponse& result, httplib::Response& res)
{
std::visit([&](const auto& value)
{
using T = std::decay_t<decltype(value)>;
// Success types
if constexpr (std::is_same_v<T, models::TestHeaderParameters200Response>)
{
res.status = HTTP_RESPONSE_CODE_TEST_HEADER_PARAMETERS200_RESPONSE;
nlohmann::json responseJson;
to_json(responseJson, value);
res.set_content(responseJson.dump(), "application/json");
}
// Error types
else if constexpr (std::is_same_v<T, models::TestHeaderParameters401Response>)
{
res.status = HTTP_RESPONSE_CODE_TEST_HEADER_PARAMETERS401_RESPONSE;
nlohmann::json errorJson = value;
res.set_content(errorJson.dump(), "application/json");
}
}, result);
}
bool Parameters::parseParametersquerypathIdGetParams(const httplib::Request& req, Parameters::ParametersquerypathIdGetRequest& params, std::vector<std::string>& paramErrors)
{
std::vector<std::string> errors;
// Query Parameters - stringParam
if (req.has_param("stringParam"))
{
params.m_stringParam = req.get_param_value("stringParam");
}
// Query Parameters - intParam
if (req.has_param("intParam"))
{
try
{
params.m_intParam = std::stoi(req.get_param_value("intParam"));
}
catch (const std::exception& e)
{
errors.push_back("Invalid query parameter 'intParam': " + std::string(e.what()));
}
}
else
{
// Use default value for optional parameter
params.m_intParam = 42;
}
// Query Parameters - boolParam
if (req.has_param("boolParam"))
{
try
{
params.m_boolParam = (req.get_param_value("boolParam") == "true");
}
catch (const std::exception& e)
{
errors.push_back("Invalid query parameter 'boolParam': " + std::string(e.what()));
}
}
else
{
// Use default value for optional parameter
params.m_boolParam = false;
}
// Query Parameters - arrayParam
if (req.has_param("arrayParam"))
{
try
{
// form/simple: multi-param or comma-separated
size_t count = req.get_param_value_count("arrayParam");
if (!params.m_arrayParam.has_value())
{
params.m_arrayParam = std::vector<std::string>{};
}
if (count > 1)
{
for (size_t i = 0; i < count; ++i)
{
auto val = req.get_param_value("arrayParam", i);
params.m_arrayParam->emplace_back(val);
}
}
else if (count == 1)
{
auto val = req.get_param_value("arrayParam", 0);
std::stringstream ss(val);
std::string item;
while (std::getline(ss, item, ','))
{
if (!item.empty())
{
params.m_arrayParam->emplace_back(item);
}
}
}
}
catch (const std::exception& e)
{
errors.push_back("Invalid query parameter 'arrayParam': " + std::string(e.what()));
}
}
// Query Parameters - spaceDelimited
if (req.has_param("spaceDelimited"))
{
try
{
// form/simple: multi-param or comma-separated
size_t count = req.get_param_value_count("spaceDelimited");
if (!params.m_spaceDelimited.has_value())
{
params.m_spaceDelimited = std::vector<std::string>{};
}
if (count > 1)
{
for (size_t i = 0; i < count; ++i)
{
auto val = req.get_param_value("spaceDelimited", i);
params.m_spaceDelimited->emplace_back(val);
}
}
else if (count == 1)
{
auto val = req.get_param_value("spaceDelimited", 0);
std::stringstream ss(val);
std::string item;
while (std::getline(ss, item, ','))
{
if (!item.empty())
{
params.m_spaceDelimited->emplace_back(item);
}
}
}
}
catch (const std::exception& e)
{
errors.push_back("Invalid query parameter 'spaceDelimited': " + std::string(e.what()));
}
}
// Query Parameters - pipeDelimited
if (req.has_param("pipeDelimited"))
{
try
{
// form/simple: multi-param or comma-separated
size_t count = req.get_param_value_count("pipeDelimited");
if (!params.m_pipeDelimited.has_value())
{
params.m_pipeDelimited = std::vector<int>{};
}
if (count > 1)
{
for (size_t i = 0; i < count; ++i)
{
auto val = req.get_param_value("pipeDelimited", i);
params.m_pipeDelimited->emplace_back(std::stoi(val));
}
}
else if (count == 1)
{
auto val = req.get_param_value("pipeDelimited", 0);
std::stringstream ss(val);
std::string item;
while (std::getline(ss, item, ','))
{
if (!item.empty())
{
params.m_pipeDelimited->emplace_back(std::stoi(item));
}
}
}
}
catch (const std::exception& e)
{
errors.push_back("Invalid query parameter 'pipeDelimited': " + std::string(e.what()));
}
}
// Query Parameters - deepObject
if (req.has_param("deepObject"))
{
try
{
// Parse JSON object from query
auto val = req.get_param_value("deepObject", 0);
params.m_deepObject = nlohmann::json::parse(val).get<models::TestQueryParametersDeepObjectParameter>();
}
catch (const std::exception& e)
{
errors.push_back("Invalid query parameter 'deepObject': " + std::string(e.what()));
}
}
// Path Parameters - pathId (index: 1)
if (req.matches.size() < 1 + 1)
{
errors.push_back("Missing path parameter 'pathId'");
}
else
{
try
{
params.m_pathId = std::stoi(req.matches[1]);
}
catch (const std::exception& e)
{
errors.push_back("Invalid path parameter 'pathId': " + std::string(e.what()));
}
}
// Return errors via out-parameter, return false if any errors
if (!errors.empty())
{
paramErrors = std::move(errors);
return false;
}
return true;
}
void Parameters::handleParametersquerypathIdGetResponse(const ParametersquerypathIdGetResponse& result, httplib::Response& res)
{
// Single response type
res.status = HTTP_RESPONSE_CODE_TEST_QUERY_PARAMETERS200_RESPONSE;
nlohmann::json responseJson;
to_json(responseJson, result);
res.set_content(responseJson.dump(), "application/json");
}
void Parameters::handleParameterscombinedresourceIdPostRequest([[maybe_unused]] const httplib::Request& req, httplib::Response& res)
{
try
{
ParameterscombinedresourceIdPostRequest params;
std::vector<std::string> paramErrors;
if (!parseParameterscombinedresourceIdPostParams(req, params, paramErrors))
{
nlohmann::json errorJson = nlohmann::json::object();
errorJson["message"] = "Invalid parameters";
errorJson["errors"] = paramErrors;
res.status = HTTP_RESPONSE_CODE_ERROR_RESPONSE;
res.set_content(errorJson.dump(), "application/json");
return;
}
auto result = handlePostForParameterscombinedresourceId(params);
handleParameterscombinedresourceIdPostResponse(result, res);
}
catch (const nlohmann::json::parse_error& e)
{
nlohmann::json errorJson = nlohmann::json::object();
errorJson["message"] = "Invalid JSON: " + std::string(e.what());
res.status = HTTP_RESPONSE_CODE_ERROR_RESPONSE;
res.set_content(errorJson.dump(), "application/json");
}
catch (const nlohmann::json::invalid_iterator& e)
{
nlohmann::json errorJson = nlohmann::json::object();
errorJson["message"] = "Invalid JSON: " + std::string(e.what());
res.status = HTTP_RESPONSE_CODE_ERROR_RESPONSE;
res.set_content(errorJson.dump(), "application/json");
}
catch (const nlohmann::json::type_error& e)
{
nlohmann::json errorJson = nlohmann::json::object();
errorJson["message"] = "Invalid JSON: " + std::string(e.what());
res.status = HTTP_RESPONSE_CODE_ERROR_RESPONSE;
res.set_content(errorJson.dump(), "application/json");
}
catch (const nlohmann::json::out_of_range& e)
{
nlohmann::json errorJson = nlohmann::json::object();
errorJson["message"] = "Invalid JSON: " + std::string(e.what());
res.status = HTTP_RESPONSE_CODE_ERROR_RESPONSE;
res.set_content(errorJson.dump(), "application/json");
}
catch (const nlohmann::json::other_error& e)
{
nlohmann::json errorJson = nlohmann::json::object();
errorJson["message"] = "Invalid JSON: " + std::string(e.what());
res.status = HTTP_RESPONSE_CODE_ERROR_RESPONSE;
res.set_content(errorJson.dump(), "application/json");
}
}
void Parameters::handleParameterscookiesGetRequest([[maybe_unused]] const httplib::Request& req, httplib::Response& res)
{
try
{
ParameterscookiesGetRequest params;
std::vector<std::string> paramErrors;
if (!parseParameterscookiesGetParams(req, params, paramErrors))
{
nlohmann::json errorJson = nlohmann::json::object();
errorJson["message"] = "Invalid parameters";
errorJson["errors"] = paramErrors;
res.status = HTTP_RESPONSE_CODE_ERROR_RESPONSE;
res.set_content(errorJson.dump(), "application/json");
return;
}
auto result = handleGetForParameterscookies(params);
handleParameterscookiesGetResponse(result, res);
}
catch (const std::exception& e)
{
nlohmann::json errorJson = nlohmann::json::object();
errorJson["message"] = "Internal error: " + std::string(e.what());
res.status = HTTP_RESPONSE_CODE_INTERNAL_SERVER_ERROR;
res.set_content(errorJson.dump(), "application/json");
}
}
void Parameters::handleParametersheadersGetRequest([[maybe_unused]] const httplib::Request& req, httplib::Response& res)
{
try
{
ParametersheadersGetRequest params;
std::vector<std::string> paramErrors;
if (!parseParametersheadersGetParams(req, params, paramErrors))
{
nlohmann::json errorJson = nlohmann::json::object();
errorJson["message"] = "Invalid parameters";
errorJson["errors"] = paramErrors;
res.status = HTTP_RESPONSE_CODE_ERROR_RESPONSE;
res.set_content(errorJson.dump(), "application/json");
return;
}
auto result = handleGetForParametersheaders(params);
handleParametersheadersGetResponse(result, res);
}
catch (const std::exception& e)
{
nlohmann::json errorJson = nlohmann::json::object();
errorJson["message"] = "Internal error: " + std::string(e.what());
res.status = HTTP_RESPONSE_CODE_INTERNAL_SERVER_ERROR;
res.set_content(errorJson.dump(), "application/json");
}
}
void Parameters::handleParametersquerypathIdGetRequest([[maybe_unused]] const httplib::Request& req, httplib::Response& res)
{
try
{
ParametersquerypathIdGetRequest params;
std::vector<std::string> paramErrors;
if (!parseParametersquerypathIdGetParams(req, params, paramErrors))
{
nlohmann::json errorJson = nlohmann::json::object();
errorJson["message"] = "Invalid parameters";
errorJson["errors"] = paramErrors;
res.status = HTTP_RESPONSE_CODE_ERROR_RESPONSE;
res.set_content(errorJson.dump(), "application/json");
return;
}
auto result = handleGetForParametersquerypathId(params);
handleParametersquerypathIdGetResponse(result, res);
}
catch (const std::exception& e)
{
nlohmann::json errorJson = nlohmann::json::object();
errorJson["message"] = "Internal error: " + std::string(e.what());
res.status = HTTP_RESPONSE_CODE_INTERNAL_SERVER_ERROR;
res.set_content(errorJson.dump(), "application/json");
}
}
void Parameters::registerRoutes(httplib::Server& svr)
{
svr.Post("/parameters/combined/{resourceId}", [this]([[maybe_unused]] const httplib::Request& req, httplib::Response& res)
{
handleParameterscombinedresourceIdPostRequest(req, res);
});
svr.Get("/parameters/cookies", [this]([[maybe_unused]] const httplib::Request& req, httplib::Response& res)
{
handleParameterscookiesGetRequest(req, res);
});
svr.Get("/parameters/headers", [this]([[maybe_unused]] const httplib::Request& req, httplib::Response& res)
{
handleParametersheadersGetRequest(req, res);
});
svr.Get("/parameters/query/{pathId}", [this]([[maybe_unused]] const httplib::Request& req, httplib::Response& res)
{
handleParametersquerypathIdGetRequest(req, res);
});
}
} // namespace api