Skip to content

Commit 483dd40

Browse files
committed
Minimal working changes (No Query or Header or Path Parameters handelling)
Resolved include names and generated file names. Adjusted mustache files and aligned properly. Added NLOHMANN_DEFINE_TYPE_INTRUSIVE for json serialization and deserialization.
1 parent 4e9c92e commit 483dd40

28 files changed

Lines changed: 1321 additions & 2153 deletions

File tree

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CppHttplibServerCodegen.java

Lines changed: 100 additions & 164 deletions
Large diffs are not rendered by default.

modules/openapi-generator/src/main/resources/cpp-httplib-server/README.mustache

Lines changed: 18 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -53,20 +53,6 @@ std::string jsonString = json.dump();
5353
// Deserialize from JSON
5454
auto parsedModel = {{vendorExtensions.modelNamespace}}::{{vendorExtensions.modelClassName}}::fromJson(nlohmann::json::parse(jsonString));
5555
```
56-
57-
{{#vendorExtensions.hasEnums}}
58-
#### Working with Enums
59-
60-
This model contains enum types that are implemented as strong C++ enums with proper string conversion:
61-
62-
```cpp
63-
// Converting string to enum
64-
auto enumValue = {{vendorExtensions.modelNamespace}}::{{vendorExtensions.modelClassName}}::<EnumName>FromString("enumValue");
65-
66-
// Converting enum to string
67-
std::string enumString = {{vendorExtensions.modelNamespace}}::{{vendorExtensions.modelClassName}}::<EnumName>ToString(enumValue);
68-
```
69-
{{/vendorExtensions.hasEnums}}
7056
{{/model}}
7157
{{/models}}
7258

@@ -91,19 +77,14 @@ public:
9177
{{#hasAnyResponseSchema}}
9278
{{handlerFunctionResponse}} {{handlerFunctionName}}({{#hasAnyRequestSchema}}const {{handlerFunctionRequest}}& params{{/hasAnyRequestSchema}}) override {
9379
// Access parameters from the params struct:
94-
// - Path parameters: params.m_<paramName>
9580
// - Query parameters: params.m_<paramName>
9681
// - Header parameters: params.m_<paramName>
9782
// - Request body (if present): params.m_request
9883
// Example:
99-
// int id = params.m_id; // path param
100-
// std::string type = params.m_type; // query param
84+
// int id = params.m_id; // query/header param
10185
// std::string token = params.m_token; // header param
10286
// if (params.m_request) { /* use request body */ }
103-
104-
// Enum parameters are automatically converted to their proper type:
105-
// MyEnum enumValue = params.m_enumParam; // model-scoped enum
106-
87+
10788
// Implement your logic here
10889

10990
// For successful response:
@@ -139,37 +120,30 @@ public:
139120

140121
int main() {
141122
// Create server
142-
httplib::Server svr;
123+
auto svr = std::make_unique<httplib::Server>();
143124
144125
// Create API implementation
145-
auto apiImpl = std::make_shared<YourApiImpl>();
126+
auto <your_api>Impl = std::make_shared<YourApiImpl>();
146127
147128
// Register routes
148-
apiImpl->registerRoutes(svr);
129+
<your_api>Impl->RegisterRoutes(std::move(svr));
149130
150131
// Start server on port 8080
151-
svr.listen("localhost", 8080);
132+
svr->listen("localhost", 8080);
152133
153134
return 0;
154135
}
155136
```
156137

157138
## Error Handling
158139

140+
159141
Each API endpoint returns a `std::variant` type that can hold either a success response or one of several error responses.
160142
The server automatically handles this variant and returns the appropriate HTTP status code and JSON body using the generated helper functions.
161143

162144
For each response type (success or error), a corresponding status code constant (e.g., `MYRESPONSE_200`, `MYERROR_400`) is generated and used by the server when returning that type. You do not need to set the status code manually; just return the appropriate type from your handler.
163145

164-
Error handling for invalid parameters or JSON is performed automatically in the generated route registration code. The server includes automatic handling for:
165-
166-
- Invalid JSON in request body
167-
- Type errors in request parameters
168-
- Invalid arguments (e.g., trying to parse a non-numeric string as a number)
169-
- Out-of-range values
170-
- Missing required parameters
171-
172-
You can customize error responses by returning the appropriate error type from your handler.
146+
Error handling for invalid parameters or JSON is performed automatically in the generated route registration code. You can customize error responses by returning the appropriate error type from your handler.
173147

174148
## Working with Optional Fields
175149

@@ -184,44 +158,18 @@ if (model.getOptionalField()) {
184158
}
185159
```
186160

187-
## Parameter Handling
188-
189-
### Path Parameters
190-
191-
Path parameters are extracted directly from URL path segments:
192-
193-
```cpp
194-
// For a path like /users/{userId}/items/{itemId}
195-
auto userId = params.m_userId; // Value from URL path
196-
auto itemId = params.m_itemId; // Value from URL path
197-
```
198-
199-
### Query Parameters
200-
201-
Query parameters are extracted from the URL query string:
202-
203-
```cpp
204-
// For a URL like /users?filter=active&limit=10
205-
auto filter = params.m_filter; // "active"
206-
auto limit = params.m_limit; // 10
207-
```
208-
209-
### Header Parameters
210-
211-
Header parameters are extracted from HTTP request headers:
212-
213-
```cpp
214-
// For a header like "Authorization: Bearer token123"
215-
auto auth = params.m_authorization; // "Bearer token123"
216-
```
217-
218-
### Enum Parameters
219-
220-
Enum parameters (in path, query, or header) are automatically converted to their enum type:
161+
## Additional Resources
221162

163+
- [cpp-httplib Documentation](https://github.com/yhirose/cpp-httplib)
164+
- [nlohmann/json Documentation](https://github.com/nlohmann/json)
165+
- [OpenAPI Generator Documentation](https://openapi-generator.tech/docs/generators/)
222166
```cpp
223-
// If 'status' is an enum type defined in the API
224-
auto statusParam = params.m_status; // Already converted to proper enum type
167+
if (model.getOptionalField()) {
168+
// Field is present
169+
auto value = *model.getOptionalField();
170+
} else {
171+
// Field is not present
172+
}
225173
```
226174

227175
## Additional Resources
Lines changed: 76 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -1,119 +1,101 @@
11
{{>License}}
22

33
#pragma once
4-
#include <httplib.h>
5-
{{#includeVariantHeader}}{{{includeVariantHeader}}}{{/includeVariantHeader}}
6-
{{#includeOptionalHeader}}{{{includeOptionalHeader}}}{{/includeOptionalHeader}}
4+
75
{{#modelsUsed}}
8-
#include "models/{{.}}.h"
6+
#include "models/{{{.}}}.h"
97
{{/modelsUsed}}
108

9+
#include <httplib.h>
10+
{{#includeVariantHeader}}{{{includeVariantHeader}}}{{/includeVariantHeader}}
11+
{{#includeOptionalHeader}}{{{includeOptionalHeader}}}{{/includeOptionalHeader}}
1112
namespace {{apiNamespace}} {
12-
1313
class {{apiClassnameInPascalCase}} {
1414
public:
1515
{{apiClassnameInPascalCase}}() = default;
1616
virtual ~{{apiClassnameInPascalCase}}() = default;
17-
// Register all the routes with the server instance from derived class.
1817
void registerRoutes(httplib::Server& svr);
19-
// ======================================
20-
// ===== Response type declarations =====
21-
// ======================================
22-
{{#operations}}
23-
{{#operation}}
24-
{{#vendorExtensions}}
25-
{{#hasAnyResponseSchema}}
26-
// Response type for [{{handlerFunctionName}}]
27-
using {{responseType}} = std::variant<{{^errorCodeToTypes}}{{#successType}}{{successType}}>;{{/successType}}{{/errorCodeToTypes}}{{#errorCodeToTypes}}
28-
{{#successType}}{{successType}}// success type{{/successType}}
29-
, {{errorType}}{{#-last}}>;{{/-last}}{{#-first}}// error types{{/-first}}{{/errorCodeToTypes}}
18+
{{#operations}}
19+
{{#operation}}
20+
{{#vendorExtensions}}
21+
{{#hasAnyRequestSchema}}
22+
{{#-first}}
23+
// =========================
24+
// ===== Request types =====
25+
// =========================
26+
{{/-first}}
3027

31-
{{/hasAnyResponseSchema}}
32-
{{/vendorExtensions}}
33-
{{/operation}}
34-
{{/operations}}
35-
// ======================================
36-
// ===== Request type declarations =====
37-
// ======================================
38-
{{#operations}}
39-
{{#operation}}
40-
{{#vendorExtensions}}
41-
{{#hasAnyRequestSchema}}
42-
// Request type for [{{handlerFunctionName}}]
28+
/**
29+
* @brief Request type for {{handlerFunctionName}}.
30+
*/
4331
struct {{requestType}}
4432
{
45-
{{#requestModel}} std::optional<{{vendorExtensions.requestModelNamespace}}::{{vendorExtensions.requestModel}}> m_request;{{/requestModel}}{{#pathParams}}{{#vendorExtensions.isArray}}
46-
{{{dataType}}} m_{{paramName}};{{/vendorExtensions.isArray}}{{^vendorExtensions.isArray}}{{#vendorExtensions.isEnum}}{{#vendorExtensions.enumModelClass}}
47-
{{vendorExtensions.requestModelNamespace}}::{{vendorExtensions.enumModelClass}}::{{{vendorExtensions.enumName}}} m_{{paramName}} = {{vendorExtensions.requestModelNamespace}}::{{vendorExtensions.enumModelClass}}::{{vendorExtensions.enumName}}::unknown;{{/vendorExtensions.enumModelClass}}{{^vendorExtensions.enumModelClass}}
48-
{{vendorExtensions.requestModelNamespace}}::{{{vendorExtensions.enumName}}} m_{{paramName}} = {{vendorExtensions.requestModelNamespace}}::{{vendorExtensions.enumName}}::unknown;{{/vendorExtensions.enumModelClass}}{{/vendorExtensions.isEnum}}{{^vendorExtensions.isEnum}}{{#vendorExtensions.isLong}}
49-
{{{dataType}}} m_{{paramName}};{{/vendorExtensions.isLong}}{{^vendorExtensions.isLong}}{{#vendorExtensions.isInt}}
50-
{{{dataType}}} m_{{paramName}};{{/vendorExtensions.isInt}}{{/vendorExtensions.isLong}}{{#vendorExtensions.isFloat}}
51-
{{{dataType}}} m_{{paramName}};{{/vendorExtensions.isFloat}}{{#vendorExtensions.isBool}}
52-
{{{dataType}}} m_{{paramName}};{{/vendorExtensions.isBool}}{{#vendorExtensions.isDouble}}
53-
{{{dataType}}} m_{{paramName}};{{/vendorExtensions.isDouble}}{{#vendorExtensions.isString}}
54-
{{{dataType}}} m_{{paramName}};{{/vendorExtensions.isString}}{{/vendorExtensions.isEnum}}{{/vendorExtensions.isArray}}{{/pathParams}}{{#queryParams}}{{#vendorExtensions.isArray}}
55-
{{{dataType}}} m_{{paramName}};{{/vendorExtensions.isArray}}{{^vendorExtensions.isArray}}{{#vendorExtensions.isEnum}}{{#vendorExtensions.enumModelClass}}
56-
{{vendorExtensions.requestModelNamespace}}::{{vendorExtensions.enumModelClass}}::{{{vendorExtensions.enumName}}} m_{{paramName}} = {{vendorExtensions.requestModelNamespace}}::{{vendorExtensions.enumModelClass}}::{{vendorExtensions.enumName}}::unknown;{{/vendorExtensions.enumModelClass}}{{^vendorExtensions.enumModelClass}}
57-
{{vendorExtensions.requestModelNamespace}}::{{{vendorExtensions.enumName}}} m_{{paramName}} = {{vendorExtensions.requestModelNamespace}}::{{vendorExtensions.enumName}}::unknown;{{/vendorExtensions.enumModelClass}}{{/vendorExtensions.isEnum}}{{^vendorExtensions.isEnum}}{{#vendorExtensions.isLong}}
58-
{{{dataType}}} m_{{paramName}};{{/vendorExtensions.isLong}}{{^vendorExtensions.isLong}}{{#vendorExtensions.isInt}}
59-
{{{dataType}}} m_{{paramName}};{{/vendorExtensions.isInt}}{{/vendorExtensions.isLong}}{{#vendorExtensions.isFloat}}
60-
{{{dataType}}} m_{{paramName}};{{/vendorExtensions.isFloat}}{{#vendorExtensions.isBool}}
61-
{{{dataType}}} m_{{paramName}};{{/vendorExtensions.isBool}}{{#vendorExtensions.isDouble}}
62-
{{{dataType}}} m_{{paramName}};{{/vendorExtensions.isDouble}}{{#vendorExtensions.isString}}
63-
{{{dataType}}} m_{{paramName}};{{/vendorExtensions.isString}}{{/vendorExtensions.isEnum}}{{/vendorExtensions.isArray}}{{/queryParams}}{{#headerParams}}{{#vendorExtensions.isArray}}
64-
{{{dataType}}} m_{{paramName}};{{/vendorExtensions.isArray}}{{^vendorExtensions.isArray}}{{#vendorExtensions.isEnum}}{{#vendorExtensions.enumModelClass}}
65-
{{vendorExtensions.requestModelNamespace}}::{{vendorExtensions.enumModelClass}}::{{{vendorExtensions.enumName}}} m_{{paramName}} = {{vendorExtensions.requestModelNamespace}}::{{vendorExtensions.enumModelClass}}::{{vendorExtensions.enumName}}::unknown;{{/vendorExtensions.enumModelClass}}{{^vendorExtensions.enumModelClass}}
66-
{{vendorExtensions.requestModelNamespace}}::{{{vendorExtensions.enumName}}} m_{{paramName}} = {{vendorExtensions.requestModelNamespace}}::{{vendorExtensions.enumName}}::unknown;{{/vendorExtensions.enumModelClass}}{{/vendorExtensions.isEnum}}{{^vendorExtensions.isEnum}}{{#vendorExtensions.isLong}}
67-
{{{dataType}}} m_{{paramName}};{{/vendorExtensions.isLong}}{{^vendorExtensions.isLong}}{{#vendorExtensions.isInt}}
68-
{{{dataType}}} m_{{paramName}};{{/vendorExtensions.isInt}}{{/vendorExtensions.isLong}}{{#vendorExtensions.isFloat}}
69-
{{{dataType}}} m_{{paramName}};{{/vendorExtensions.isFloat}}{{#vendorExtensions.isBool}}
70-
{{{dataType}}} m_{{paramName}};{{/vendorExtensions.isBool}}{{#vendorExtensions.isDouble}}
71-
{{{dataType}}} m_{{paramName}};{{/vendorExtensions.isDouble}}{{#vendorExtensions.isString}}
72-
{{{dataType}}} m_{{paramName}};{{/vendorExtensions.isString}}{{/vendorExtensions.isEnum}}{{/vendorExtensions.isArray}}{{/headerParams}}
33+
{{#requestModel}}std::optional<{{requestModelNamespace}}::{{requestModel}}> m_request;{{/requestModel}}{{^requestModel}}// No Schema Types defined{{/requestModel}}
34+
{{#queryParams}}{{{dataType}}} m_{{paramName}};{{/queryParams}}{{^queryParams}}// Query Params not available{{/queryParams}}
35+
{{#headerParams}}{{{dataType}}} m_{{paramName}};{{/headerParams}}{{^headerParams}}// Header Params not available{{/headerParams}}
7336
};
7437

75-
{{/hasAnyRequestSchema}}
76-
{{/vendorExtensions}}
77-
{{/operation}}
78-
{{/operations}}
79-
// ===== Pure virtual functions to he handled by derived classes =====
80-
{{#operations}}
81-
{{#operation}}
82-
{{#vendorExtensions}}
38+
{{/hasAnyRequestSchema}}
39+
{{/vendorExtensions}}
40+
{{/operation}}
41+
{{/operations}}
42+
43+
{{#operations}}
44+
{{#operation}}
45+
{{#vendorExtensions}}
46+
{{#hasAnyResponseSchema}}
47+
{{#-first}}
48+
// ==========================
49+
// ===== Response types =====
50+
// ==========================
51+
{{/-first}}
8352
/**
84-
{{#hasAnyRequestSchema}}
85-
* @param {{requestType}} - struct containing all the query parameters and headers and schemas as available.
86-
{{/hasAnyRequestSchema}}
87-
{{#hasAnyResponseSchema}}
88-
* @return {{responseType}} - The response type returned by the handler.
89-
{{/hasAnyResponseSchema}}
53+
* @brief Response type for {{handlerFunctionName}}.
54+
*/
55+
using {{responseType}} = std::variant<
56+
{{#successType}}{{successType}}{{/successType}}{{^errorTypes}}>;{{/errorTypes}}
57+
{{#errorTypes}} , {{{.}}}{{#-last}}>;{{/-last}}
58+
{{/errorTypes}}
59+
60+
{{/hasAnyResponseSchema}}
61+
{{/vendorExtensions}}
62+
{{/operation}}
63+
{{/operations}}
64+
// ============================================================
65+
// ===== Pure virtual functions to be handled by the user =====
66+
// ============================================================
67+
{{#operations}}
68+
{{#operation}}
69+
{{#vendorExtensions}}
70+
/**
71+
{{#hasAnyRequestSchema}}
72+
* {{requestType}} - struct containing all the query parameters and headers and schemas as available.
73+
{{/hasAnyRequestSchema}}
74+
{{#hasAnyResponseSchema}}
75+
* @return {{responseType}} The response type returned by the handler.
76+
{{/hasAnyResponseSchema}}
9077
*/
9178
virtual {{#hasAnyResponseSchema}}{{responseType}}{{/hasAnyResponseSchema}}{{^hasAnyResponseSchema}}void{{/hasAnyResponseSchema}} {{handlerFunctionName}}({{#hasAnyRequestSchema}}const {{requestType}}& params{{/hasAnyRequestSchema}})=0;
9279

93-
{{/vendorExtensions}}
94-
{{/operation}}
95-
{{/operations}}
80+
{{/vendorExtensions}}
81+
{{/operation}}
82+
{{/operations}}
9683
private:
97-
// --- Helper function declarations ---
98-
{{#operations}}
99-
{{#operation}}
100-
{{#vendorExtensions}}
101-
{{#hasAnyRequestSchema}}
102-
static {{requestType}} parse{{requestType}}(const httplib::Request& req);
103-
{{/hasAnyRequestSchema}}
104-
{{/vendorExtensions}}
105-
{{/operation}}
106-
{{/operations}}
107-
108-
{{#operations}}
109-
{{#operation}}
110-
{{#vendorExtensions}}
111-
{{#hasAnyResponseSchema}}
84+
// ========================================
85+
// ===== Helper function declarations =====
86+
// ========================================
87+
{{#operations}}
88+
{{#operation}}
89+
{{#vendorExtensions}}
90+
{{#hasAnyRequestSchema}}
91+
static {{requestType}} parse{{operationIdPascalCase}}Params(const httplib::Request& req);
92+
{{/hasAnyRequestSchema}}
93+
{{#hasAnyResponseSchema}}
11294
static void handle{{responseType}}(const {{responseType}}& result, httplib::Response& res);
113-
{{/hasAnyResponseSchema}}
114-
{{/vendorExtensions}}
115-
{{/operation}}
116-
{{/operations}}
95+
{{/hasAnyResponseSchema}}
96+
{{/vendorExtensions}}
97+
{{/operation}}
98+
{{/operations}}
11799
};
118100

119-
} // namespace {{apiNamespace}}
101+
} // namespace {{apiNamespace}}

0 commit comments

Comments
 (0)