Skip to content
Open
Show file tree
Hide file tree
Changes from 18 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
generatorName: kotlin-spring
outputDir: samples/server/petstore/kotlin-springboot-include-http-request-context-delegate.yaml
Copy link
Member

@wing328 wing328 Nov 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what about naming the folder without .yaml?

also can we add this to the github action config file to test it in the CI moving forward?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

definitely will rename the folder. And will add to the action config file. Thanks for the guidance!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I implemented the proposed changes, fixed some compilation errors and added more tests.

I really like the robust test system this project has. So many failing commits before I get everything right... Seems like the major reason why it can accept PRs so quickly without becoming a broken mess.

library: spring-boot
inputSpec: modules/openapi-generator/src/test/resources/3_0/kotlin/petstore-with-x-kotlin-implements.yaml
templateDir: modules/openapi-generator/src/main/resources/kotlin-spring
additionalProperties:
documentationProvider: none
annotationLibrary: swagger1
useSwaggerUI: false
serviceImplementation: false
skipDefaultInterface: true
interfaceOnly: false
serializableModel: true
beanValidations: true
includeHttpRequestContext: true
reactive: true
delegatePattern: true
15 changes: 8 additions & 7 deletions bin/configs/kotlin-spring-boot-x-kotlin-implements.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ inputSpec: modules/openapi-generator/src/test/resources/3_0/kotlin/petstore-with
templateDir: modules/openapi-generator/src/main/resources/kotlin-spring
additionalProperties:
documentationProvider: none
annotationLibrary: none
useSwaggerUI: "false"
serviceImplementation: "false"
skipDefaultInterface: "true"
interfaceOnly: "true"
serializableModel: "true"
beanValidations: "true"
annotationLibrary: swagger1
useSwaggerUI: false
serviceImplementation: false
skipDefaultInterface: true
interfaceOnly: true
serializableModel: true
beanValidations: true
includeHttpRequestContext: true
1 change: 1 addition & 0 deletions docs/generators/kotlin-spring.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|exceptionHandler|generate default global exception handlers (not compatible with reactive. enabling reactive will disable exceptionHandler )| |true|
|gradleBuildFile|generate a gradle build file using the Kotlin DSL| |true|
|groupId|Generated artifact package's organization (i.e. maven groupId).| |org.openapitools|
|includeHttpRequestContext|Whether to include HttpServletRequest (blocking) or ServerWebExchange (reactive) as additional parameter in generated methods.| |false|
|interfaceOnly|Whether to generate only API interface stubs without the server files.| |false|
|library|library template (sub-template)|<dl><dt>**spring-boot**</dt><dd>Spring-boot Server application.</dd><dt>**spring-cloud**</dt><dd>Spring-Cloud-Feign client with Spring-Boot auto-configured settings.</dd></dl>|spring-boot|
|modelMutable|Create mutable models| |false|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ public class KotlinSpringServerCodegen extends AbstractKotlinCodegen
public static final String BEAN_QUALIFIERS = "beanQualifiers";

public static final String USE_SPRING_BOOT3 = "useSpringBoot3";
public static final String INCLUDE_HTTP_REQUEST_CONTEXT = "includeHttpRequestContext";
public static final String USE_FLOW_FOR_ARRAY_RETURN_TYPE = "useFlowForArrayReturnType";
public static final String REQUEST_MAPPING_OPTION = "requestMappingMode";
public static final String USE_REQUEST_MAPPING_ON_CONTROLLER = "useRequestMappingOnController";
Expand Down Expand Up @@ -127,6 +128,7 @@ public String getDescription() {
@Setter private boolean serviceImplementation = false;
@Getter @Setter
private boolean reactive = false;
@Setter private boolean includeHttpRequestContext = false;
@Getter @Setter
private boolean useFlowForArrayReturnType = true;
@Setter private boolean interfaceOnly = false;
Expand Down Expand Up @@ -220,6 +222,7 @@ public KotlinSpringServerCodegen() {
" (contexts) added to single project.", beanQualifiers);
addSwitch(USE_SPRING_BOOT3, "Generate code and provide dependencies for use with Spring Boot 3.x. (Use jakarta instead of javax in imports). Enabling this option will also enable `useJakartaEe`.", useSpringBoot3);
addSwitch(USE_FLOW_FOR_ARRAY_RETURN_TYPE, "Whether to use Flow for array/collection return types when reactive is enabled. If false, will use List instead.", useFlowForArrayReturnType);
addSwitch(INCLUDE_HTTP_REQUEST_CONTEXT, "Whether to include HttpServletRequest (blocking) or ServerWebExchange (reactive) as additional parameter in generated methods.", includeHttpRequestContext);
supportedLibraries.put(SPRING_BOOT, "Spring-boot Server application.");
supportedLibraries.put(SPRING_CLOUD_LIBRARY,
"Spring-Cloud-Feign client with Spring-Boot auto-configured settings.");
Expand Down Expand Up @@ -564,6 +567,9 @@ public void processOpts() {
if (additionalProperties.containsKey(USE_SPRING_BOOT3)) {
this.setUseSpringBoot3(convertPropertyToBoolean(USE_SPRING_BOOT3));
}
if (additionalProperties.containsKey(INCLUDE_HTTP_REQUEST_CONTEXT)) {
this.setIncludeHttpRequestContext(convertPropertyToBoolean(INCLUDE_HTTP_REQUEST_CONTEXT));
}
if (isUseSpringBoot3()) {
if (DocumentationProvider.SPRINGFOX.equals(getDocumentationProvider())) {
throw new IllegalArgumentException(DocumentationProvider.SPRINGFOX.getPropertyName() + " is not supported with Spring Boot > 3.x");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ class {{classname}}Controller({{#serviceInterface}}@Autowired(required = true) v
produces = [{{#produces}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/produces}}]{{/hasProduces}}{{#hasConsumes}},
consumes = [{{#consumes}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/consumes}}]{{/hasConsumes}}{{/singleContentTypes}}
)
{{#reactive}}{{^isArray}}suspend {{/isArray}}{{#isArray}}{{^useFlowForArrayReturnType}}suspend {{/useFlowForArrayReturnType}}{{/isArray}}{{/reactive}}fun {{operationId}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>cookieParams}}{{>bodyParams}}{{>formParams}}{{^-last}},{{/-last}}{{/allParams}}): ResponseEntity<{{>returnTypes}}> {
{{#reactive}}{{^isArray}}suspend {{/isArray}}{{#isArray}}{{^useFlowForArrayReturnType}}suspend {{/useFlowForArrayReturnType}}{{/isArray}}{{/reactive}}fun {{operationId}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>cookieParams}}{{>bodyParams}}{{>formParams}}{{^-last}},{{/-last}}{{/allParams}}{{#includeHttpRequestContext}}{{#hasParams}}, {{/hasParams}}{{#swagger1AnnotationLibrary}}@ApiParam(hidden = true) {{/swagger1AnnotationLibrary}}{{#swagger2AnnotationLibrary}}@Parameter(hidden = true) {{/swagger2AnnotationLibrary}}{{#reactive}}exchange: org.springframework.web.server.ServerWebExchange{{/reactive}}{{^reactive}}request: {{javaxPackage}}.servlet.http.HttpServletRequest{{/reactive}}{{/includeHttpRequestContext}}): ResponseEntity<{{>returnTypes}}> {
return {{>returnValue}}
}
{{/operation}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ interface {{classname}}Delegate {
* @see {{classname}}#{{operationId}}
*/
{{#reactive}}{{^isArray}}suspend {{/isArray}}{{#isArray}}{{^useFlowForArrayReturnType}}suspend {{/useFlowForArrayReturnType}}{{/isArray}}{{/reactive}}fun {{operationId}}({{#allParams}}{{{paramName}}}: {{^reactive}}{{>optionalDataType}}{{/reactive}}{{#reactive}}{{^isArray}}{{>optionalDataType}}{{/isArray}}{{#isArray}}{{#isBodyParam}}Flow<{{{baseType}}}>{{/isBodyParam}}{{^isBodyParam}}{{>optionalDataType}}{{/isBodyParam}}{{/isArray}}{{/reactive}}{{^-last}},
{{/-last}}{{/allParams}}): {{#responseWrapper}}{{.}}<{{/responseWrapper}}ResponseEntity<{{>returnTypes}}>{{#responseWrapper}}>{{/responseWrapper}}{{^skipDefaultDelegateInterface}} {
{{/-last}}{{/allParams}}{{#includeHttpRequestContext}}{{#hasParams}},
{{/hasParams}}{{#reactive}}exchange: org.springframework.web.server.ServerWebExchange{{/reactive}}{{^reactive}}request: {{javaxPackage}}.servlet.http.HttpServletRequest{{/reactive}}{{/includeHttpRequestContext}}): {{#responseWrapper}}{{.}}<{{/responseWrapper}}ResponseEntity<{{>returnTypes}}>{{#responseWrapper}}>{{/responseWrapper}}{{^skipDefaultDelegateInterface}} {
{{>methodBody}}{{! prevent indent}}
}{{/skipDefaultDelegateInterface}}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,12 +102,12 @@ interface {{classname}} {
produces = [{{#produces}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/produces}}]{{/hasProduces}}{{#hasConsumes}},
consumes = [{{#consumes}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/consumes}}]{{/hasConsumes}}{{/singleContentTypes}}
)
{{#reactive}}{{^isArray}}suspend {{/isArray}}{{#isArray}}{{^useFlowForArrayReturnType}}suspend {{/useFlowForArrayReturnType}}{{/isArray}}{{/reactive}}fun {{operationId}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>cookieParams}}{{>bodyParams}}{{>formParams}}{{^-last}},{{/-last}}{{/allParams}}): ResponseEntity<{{>returnTypes}}>{{^skipDefaultApiInterface}} {
{{#reactive}}{{^isArray}}suspend {{/isArray}}{{#isArray}}{{^useFlowForArrayReturnType}}suspend {{/useFlowForArrayReturnType}}{{/isArray}}{{/reactive}}fun {{operationId}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>cookieParams}}{{>bodyParams}}{{>formParams}}{{^-last}},{{/-last}}{{/allParams}}{{#includeHttpRequestContext}}{{#hasParams}}, {{/hasParams}}{{#swagger1AnnotationLibrary}}@ApiParam(hidden = true) {{/swagger1AnnotationLibrary}}{{#swagger2AnnotationLibrary}}@Parameter(hidden = true) {{/swagger2AnnotationLibrary}}{{#reactive}}exchange: org.springframework.web.server.ServerWebExchange{{/reactive}}{{^reactive}}request: {{javaxPackage}}.servlet.http.HttpServletRequest{{/reactive}}{{/includeHttpRequestContext}}): ResponseEntity<{{>returnTypes}}>{{^skipDefaultApiInterface}} {
{{^isDelegate}}
return {{>returnValue}}
{{/isDelegate}}
{{#isDelegate}}
return getDelegate().{{operationId}}({{#allParams}}{{{paramName}}}{{^-last}}, {{/-last}}{{/allParams}})
return getDelegate().{{operationId}}({{#allParams}}{{{paramName}}}{{^-last}}, {{/-last}}{{/allParams}}{{#includeHttpRequestContext}}{{#hasParams}}, {{/hasParams}}{{#reactive}}exchange{{/reactive}}{{^reactive}}request{{/reactive}}{{/includeHttpRequestContext}})
{{/isDelegate}}
}{{/skipDefaultApiInterface}}
{{/operation}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ public static void assertFileContains(Path path, String... lines) {
String file = linearize(generatedFile);
assertNotNull(file);
for (String line : lines)
assertTrue(file.contains(linearize(line)), "File does not contain line [" + line + "]");
assertTrue(file.contains(linearize(line)), "File '" + path + "' does not contain line [" + line + "]");
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added this since it simplifies debugging when a unit test fails - it makes it easy to retrieve the file and compare expectation with reality without setting break points, etc.

} catch (IOException e) {
fail("Unable to evaluate file " + path);
}
Expand Down
Loading
Loading