Skip to content

Commit b92e778

Browse files
committed
Add support for 'useResponseEntity' in kotlin-spring. Consolidate with the separate flag 'declarativeInterfaceWrapResponses' as these can now be controlled both by one flag. Default to true.
1 parent 0ad3315 commit b92e778

18 files changed

Lines changed: 68 additions & 43 deletions

File tree

bin/configs/kotlin-spring-declarative-interface-reactive-coroutines.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@ additionalProperties:
1111
beanValidations: "true"
1212
interfaceOnly: true
1313
reactive: true
14-
declarativeInterfaceWrapResponses: false
14+
useResponseEntity: false
1515
useFlowForArrayReturnType: false
1616
declarativeInterfaceReactiveMode: "coroutines"

bin/configs/kotlin-spring-declarative-interface-reactive-reactor-wrapped.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@ additionalProperties:
1111
beanValidations: "true"
1212
interfaceOnly: true
1313
reactive: true
14-
declarativeInterfaceWrapResponses: true
14+
useResponseEntity: true
1515
useFlowForArrayReturnType: false
1616
declarativeInterfaceReactiveMode: "reactor"

bin/configs/kotlin-spring-declarative-interface-wrapped.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@ additionalProperties:
1111
beanValidations: "true"
1212
interfaceOnly: true
1313
reactive: false
14-
declarativeInterfaceWrapResponses: true
14+
useResponseEntity: true
1515
useFlowForArrayReturnType: false

bin/configs/kotlin-spring-declarative-interface.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@ additionalProperties:
1111
beanValidations: "true"
1212
interfaceOnly: true
1313
reactive: false
14-
declarativeInterfaceWrapResponses: true
14+
useResponseEntity: true
1515
useFlowForArrayReturnType: false

docs/generators/kotlin-spring.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ These options may be applied as additional-properties (cli) or configOptions (pl
2828
|beanQualifiers|Whether to add fully-qualifier class names as bean qualifiers in @Component and @RestController annotations. May be used to prevent bean names clash if multiple generated libraries (contexts) added to single project.| |false|
2929
|configPackage|configuration package for generated code| |org.openapitools.configuration|
3030
|declarativeInterfaceReactiveMode|What type of reactive style to use in Spring Http declarative interface|<dl><dt>**coroutines**</dt><dd>Use kotlin-idiomatic 'suspend' functions</dd><dt>**reactor**</dt><dd>Use reactor return wrappers 'Mono' and 'Flux'</dd></dl>|coroutines|
31-
|declarativeInterfaceWrapResponses|Whether (when false) to return actual type (e.g. List&lt;Fruit&gt;) and handle non 2xx responses via exceptions or (when true) return entire ResponseEntity (e.g. ResponseEntity&lt;List&lt;Fruit&gt;&gt;)| |false|
3231
|delegatePattern|Whether to generate the server files using the delegate pattern| |false|
3332
|documentationProvider|Select the OpenAPI documentation provider.|<dl><dt>**none**</dt><dd>Do not publish an OpenAPI specification.</dd><dt>**source**</dt><dd>Publish the original input OpenAPI specification.</dd><dt>**springfox**</dt><dd>Generate an OpenAPI 2 (fka Swagger RESTful API Documentation Specification) specification using SpringFox 2.x. Deprecated (for removal); use springdoc instead.</dd><dt>**springdoc**</dt><dd>Generate an OpenAPI 3 specification using SpringDoc.</dd></dl>|springdoc|
3433
|enumPropertyNaming|Naming convention for enum properties: 'camelCase', 'PascalCase', 'snake_case', 'UPPERCASE', and 'original'| |original|
@@ -56,6 +55,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
5655
|useBeanValidation|Use BeanValidation API annotations to validate data types| |true|
5756
|useFeignClientUrl|Whether to generate Feign client with url parameter.| |true|
5857
|useFlowForArrayReturnType|Whether to use Flow for array/collection return types when reactive is enabled. If false, will use List instead.| |true|
58+
|useResponseEntity|Whether (when false) to return actual type (e.g. List&lt;Fruit&gt;) and handle non-happy path responses via exceptions flow or (when true) return entire ResponseEntity (e.g. ResponseEntity&lt;List&lt;Fruit&gt;&gt;). If disabled, method are annotated using a @ResponseStatus annotation, which has the status of the first response declared in the Api definition| |true|
5959
|useSpringBoot3|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`.| |false|
6060
|useSwaggerUI|Open the OpenApi specification in swagger-ui. Will also import and configure needed dependencies| |true|
6161
|useTags|Whether to use tags for creating interface and controller class names| |false|

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

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ public class KotlinSpringServerCodegen extends AbstractKotlinCodegen
8585
public static final String DELEGATE_PATTERN = "delegatePattern";
8686
public static final String USE_TAGS = "useTags";
8787
public static final String BEAN_QUALIFIERS = "beanQualifiers";
88-
public static final String DECLARATIVE_INTERFACE_WRAP_RESPONSES = "declarativeInterfaceWrapResponses";
88+
public static final String USE_RESPONSE_ENTITY = "useResponseEntity";
8989
public static final String DECLARATIVE_INTERFACE_REACTIVE_MODE = "declarativeInterfaceReactiveMode";
9090

9191
public static final String USE_SPRING_BOOT3 = "useSpringBoot3";
@@ -109,6 +109,7 @@ public enum DeclarativeInterfaceReactiveMode {
109109
}
110110
}
111111

112+
112113
public enum RequestMappingMode {
113114
api_interface("Generate the @RequestMapping annotation on the generated Api Interface."),
114115
controller("Generate the @RequestMapping annotation on the generated Api Controller Implementation."),
@@ -155,7 +156,7 @@ public String getDescription() {
155156
@Setter protected boolean useTags = false;
156157
@Setter private boolean beanQualifiers = false;
157158
@Setter private DeclarativeInterfaceReactiveMode declarativeInterfaceReactiveMode = DeclarativeInterfaceReactiveMode.coroutines;
158-
@Setter private boolean declarativeInterfaceWrapResponses = false;
159+
@Setter private boolean useResponseEntity = true;
159160

160161
@Getter @Setter
161162
protected boolean useSpringBoot3 = false;
@@ -242,9 +243,9 @@ public KotlinSpringServerCodegen() {
242243
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);
243244
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);
244245
addSwitch(INCLUDE_HTTP_REQUEST_CONTEXT, "Whether to include HttpServletRequest (blocking) or ServerWebExchange (reactive) as additional parameter in generated methods.", includeHttpRequestContext);
245-
addSwitch(DECLARATIVE_INTERFACE_WRAP_RESPONSES,
246-
"Whether (when false) to return actual type (e.g. List<Fruit>) and handle non 2xx responses via exceptions or (when true) return entire ResponseEntity (e.g. ResponseEntity<List<Fruit>>)",
247-
declarativeInterfaceWrapResponses);
246+
addSwitch(USE_RESPONSE_ENTITY,
247+
"Whether (when false) to return actual type (e.g. List<Fruit>) and handle non-happy path responses via exceptions flow or (when true) return entire ResponseEntity (e.g. ResponseEntity<List<Fruit>>). If disabled, method are annotated using a @ResponseStatus annotation, which has the status of the first response declared in the Api definition",
248+
useResponseEntity);
248249
supportedLibraries.put(SPRING_BOOT, "Spring-boot Server application.");
249250
supportedLibraries.put(SPRING_CLOUD_LIBRARY,
250251
"Spring-Cloud-Feign client with Spring-Boot auto-configured settings.");
@@ -468,6 +469,11 @@ public void processOpts() {
468469
additionalProperties.put(CodegenConstants.LIBRARY, library);
469470
}
470471

472+
if(additionalProperties.containsKey(USE_RESPONSE_ENTITY)) {
473+
this.setUseResponseEntity(Boolean.parseBoolean(additionalProperties.get(USE_RESPONSE_ENTITY).toString()));
474+
}
475+
writePropertyBack(USE_RESPONSE_ENTITY, useResponseEntity);
476+
471477
// Set basePackage from invokerPackage
472478
if (!additionalProperties.containsKey(BASE_PACKAGE)
473479
&& additionalProperties.containsKey(CodegenConstants.INVOKER_PACKAGE)) {

modules/openapi-generator/src/main/resources/kotlin-spring/api.mustache

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ import io.swagger.annotations.AuthorizationScope
2020
{{/swagger1AnnotationLibrary}}
2121
import org.springframework.http.HttpStatus
2222
import org.springframework.http.MediaType
23+
{{#useResponseEntity}}
2324
import org.springframework.http.ResponseEntity
25+
{{/useResponseEntity}}
2426

2527
import org.springframework.web.bind.annotation.*
2628
{{#useBeanValidation}}
@@ -63,6 +65,9 @@ import kotlin.collections.Map
6365
class {{classname}}Controller({{#serviceInterface}}@Autowired(required = true) val service: {{classname}}Service{{/serviceInterface}}) {
6466
{{#operation}}
6567

68+
{{^useResponseEntity}}
69+
@ResponseStatus({{#springHttpStatus}}{{#responses.0}}{{{code}}}{{/responses.0}}{{/springHttpStatus}})
70+
{{/useResponseEntity}}
6671
{{#swagger2AnnotationLibrary}}
6772
@Operation(
6873
summary = "{{{summary}}}",
@@ -89,7 +94,7 @@ class {{classname}}Controller({{#serviceInterface}}@Autowired(required = true) v
8994
produces = [{{#produces}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/produces}}]{{/hasProduces}}{{#hasConsumes}},
9095
consumes = [{{#consumes}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/consumes}}]{{/hasConsumes}}{{/singleContentTypes}}
9196
)
92-
{{#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}}> {
97+
{{#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}}): {{#useResponseEntity}}ResponseEntity<{{/useResponseEntity}}{{>returnTypes}}{{#useResponseEntity}}>{{/useResponseEntity}} {
9398
return {{>returnValue}}
9499
}
95100
{{/operation}}

modules/openapi-generator/src/main/resources/kotlin-spring/apiDelegate.mustache

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ package {{package}}
44
{{/imports}}
55
import org.springframework.http.HttpStatus
66
import org.springframework.http.MediaType
7+
{{#useResponseEntity}}
78
import org.springframework.http.ResponseEntity
9+
{{/useResponseEntity}}
810
import org.springframework.web.context.request.NativeWebRequest
911
{{#appendRequestToHandler}}
1012
import org.springframework.http.server.reactive.ServerHttpRequest
@@ -32,7 +34,7 @@ interface {{classname}}Delegate {
3234
*/
3335
{{#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}},
3436
{{/-last}}{{/allParams}}{{#includeHttpRequestContext}}{{#hasParams}},
35-
{{/hasParams}}{{#reactive}}exchange: org.springframework.web.server.ServerWebExchange{{/reactive}}{{^reactive}}request: {{javaxPackage}}.servlet.http.HttpServletRequest{{/reactive}}{{/includeHttpRequestContext}}): ResponseEntity<{{>returnTypes}}>{{^skipDefaultDelegateInterface}} {
37+
{{/hasParams}}{{#reactive}}exchange: org.springframework.web.server.ServerWebExchange{{/reactive}}{{^reactive}}request: {{javaxPackage}}.servlet.http.HttpServletRequest{{/reactive}}{{/includeHttpRequestContext}}): {{#useResponseEntity}}ResponseEntity<{{/useResponseEntity}}{{>returnTypes}}{{#useResponseEntity}}>{{/useResponseEntity}}{{^skipDefaultDelegateInterface}} {
3638
{{>methodBody}}{{! prevent indent}}
3739
}{{/skipDefaultDelegateInterface}}
3840

modules/openapi-generator/src/main/resources/kotlin-spring/apiInterface.mustache

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ import io.swagger.annotations.AuthorizationScope
2525
{{/swagger1AnnotationLibrary}}
2626
import org.springframework.http.HttpStatus
2727
import org.springframework.http.MediaType
28+
{{#useResponseEntity}}
2829
import org.springframework.http.ResponseEntity
30+
{{/useResponseEntity}}
2931

3032
import org.springframework.web.bind.annotation.*
3133
{{#useBeanValidation}}
@@ -74,6 +76,9 @@ interface {{classname}} {
7476
{{/isDelegate}}
7577
{{#operation}}
7678

79+
{{^useResponseEntity}}
80+
@ResponseStatus({{#springHttpStatus}}{{#responses.0}}{{{code}}}{{/responses.0}}{{/springHttpStatus}})
81+
{{/useResponseEntity}}
7782
{{#swagger2AnnotationLibrary}}
7883
@Operation(
7984
tags = [{{#tags}}"{{{name}}}",{{/tags}}],
@@ -102,7 +107,7 @@ interface {{classname}} {
102107
produces = [{{#produces}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/produces}}]{{/hasProduces}}{{#hasConsumes}},
103108
consumes = [{{#consumes}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/consumes}}]{{/hasConsumes}}{{/singleContentTypes}}
104109
)
105-
{{#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}} {
110+
{{#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}}): {{#useResponseEntity}}ResponseEntity<{{/useResponseEntity}}{{>returnTypes}}{{#useResponseEntity}}>{{/useResponseEntity}}{{^skipDefaultApiInterface}} {
106111
{{^isDelegate}}
107112
return {{>returnValue}}
108113
{{/isDelegate}}

modules/openapi-generator/src/main/resources/kotlin-spring/api_test.mustache

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,12 @@ import org.junit.jupiter.api.Test
77
import kotlinx.coroutines.flow.Flow
88
import kotlinx.coroutines.test.runBlockingTest
99
{{/reactive}}
10+
{{^useResponseEntity}}
11+
import org.springframework.http.HttpStatus
12+
{{/useResponseEntity}}
13+
{{#useResponseEntity}}
1014
import org.springframework.http.ResponseEntity
15+
{{/useResponseEntity}}
1116

1217
class {{classname}}Test {
1318
@@ -30,7 +35,7 @@ class {{classname}}Test {
3035
val {{{paramName}}}: {{>optionalDataType}} = TODO()
3136
{{/allParams}}
3237
{{#includeHttpRequestContext}}val {{#reactive}}exchange: org.springframework.web.server.ServerWebExchange{{/reactive}}{{^reactive}}request: {{javaxPackage}}.servlet.http.HttpServletRequest{{/reactive}} = TODO(){{/includeHttpRequestContext}}
33-
val response: ResponseEntity<{{>returnTypes}}> = api.{{operationId}}({{#allParams}}{{{paramName}}}{{^-last}}, {{/-last}}{{/allParams}}{{#includeHttpRequestContext}}{{#hasParams}}, {{/hasParams}}{{#reactive}}exchange{{/reactive}}{{^reactive}}request{{/reactive}}{{/includeHttpRequestContext}})
38+
val response: {{#useResponseEntity}}ResponseEntity<{{/useResponseEntity}}{{>returnTypes}}{{#useResponseEntity}}>{{/useResponseEntity}} = api.{{operationId}}({{#allParams}}{{{paramName}}}{{^-last}}, {{/-last}}{{/allParams}}{{#includeHttpRequestContext}}{{#hasParams}}, {{/hasParams}}{{#reactive}}exchange{{/reactive}}{{^reactive}}request{{/reactive}}{{/includeHttpRequestContext}})
3439

3540
// TODO: test validations
3641
}

0 commit comments

Comments
 (0)