Skip to content

Commit 7f7f313

Browse files
committed
Merge branch 'tobiberger-parameter-with-default-value-not-required'
2 parents f09fe07 + e9331fd commit 7f7f313

File tree

4 files changed

+182
-0
lines changed

4 files changed

+182
-0
lines changed

springdoc-openapi-kotlin/src/main/java/org/springdoc/kotlin/SpringDocKotlinConfiguration.kt

+10
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,16 @@ import org.springframework.context.annotation.Configuration
1616
import org.springframework.context.annotation.Lazy
1717
import org.springframework.core.MethodParameter
1818
import org.springframework.core.annotation.AnnotatedElementUtils
19+
import org.springframework.web.bind.annotation.RequestParam
20+
import org.springframework.web.bind.annotation.ValueConstants
1921
import kotlin.coroutines.Continuation
2022
import kotlin.reflect.KParameter
2123
import kotlin.reflect.jvm.kotlinFunction
2224

2325
/**
2426
* The type Spring doc kotlin configuration.
2527
* @author bnasslahsen
28+
* @author tobiberger
2629
*/
2730
@Lazy(false)
2831
@Configuration(proxyBeanMethods = false)
@@ -77,9 +80,16 @@ class SpringDocKotlinConfiguration(objectMapperProvider: ObjectMapperProvider) {
7780
AnnotatedElementUtils.forAnnotations(*methodParameter.parameterAnnotations),
7881
Parameter::class.java
7982
)
83+
val requestParam = AnnotatedElementUtils.findMergedAnnotation(
84+
AnnotatedElementUtils.forAnnotations(*methodParameter.parameterAnnotations),
85+
RequestParam::class.java
86+
)
8087
// Swagger @Parameter annotation takes precedence
8188
if (parameterDoc != null && parameterDoc.required)
8289
parameterModel.required = parameterDoc.required
90+
// parameter is not required if a default value is provided in @RequestParam
91+
else if (requestParam != null && requestParam.defaultValue != ValueConstants.DEFAULT_NONE)
92+
parameterModel.required = false
8393
else
8494
parameterModel.required = kParameter.type.isMarkedNullable == false
8595
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package test.org.springdoc.api.app10
2+
3+
import org.springframework.web.bind.annotation.GetMapping
4+
import org.springframework.web.bind.annotation.RequestParam
5+
import org.springframework.web.bind.annotation.RestController
6+
import test.org.springdoc.api.app8.Greeting
7+
8+
data class Greeting(val greeting: String)
9+
10+
@RestController
11+
class ExampleController {
12+
@GetMapping("/")
13+
fun greet(@RequestParam name: String?) = Greeting("Hello ${name ?: "world"}")
14+
15+
@GetMapping("/test")
16+
fun test(@RequestParam name: String) = Greeting("Hello $name")
17+
18+
@GetMapping("/test-with-default")
19+
fun testWithDefault(@RequestParam(defaultValue = "world") name: String) = Greeting("Hello $name")
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
*
3+
* * Copyright 2019-2023 the original author or authors.
4+
* *
5+
* * Licensed under the Apache License, Version 2.0 (the "License");
6+
* * you may not use this file except in compliance with the License.
7+
* * You may obtain a copy of the License at
8+
* *
9+
* * https://www.apache.org/licenses/LICENSE-2.0
10+
* *
11+
* * Unless required by applicable law or agreed to in writing, software
12+
* * distributed under the License is distributed on an "AS IS" BASIS,
13+
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* * See the License for the specific language governing permissions and
15+
* * limitations under the License.
16+
*
17+
*/
18+
19+
package test.org.springdoc.api.app10
20+
21+
import org.springframework.boot.autoconfigure.SpringBootApplication
22+
import org.springframework.context.annotation.ComponentScan
23+
import test.org.springdoc.api.AbstractKotlinSpringDocTest
24+
25+
class SpringDocApp10Test : AbstractKotlinSpringDocTest() {
26+
27+
@SpringBootApplication
28+
@ComponentScan(basePackages = ["org.springdoc", "test.org.springdoc.api.app10"])
29+
open class DemoApplication
30+
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
{
2+
"openapi": "3.0.1",
3+
"info": {
4+
"title": "OpenAPI definition",
5+
"version": "v0"
6+
},
7+
"servers": [
8+
{
9+
"url": "",
10+
"description": "Generated server url"
11+
}
12+
],
13+
"paths": {
14+
"/": {
15+
"get": {
16+
"tags": [
17+
"example-controller"
18+
],
19+
"operationId": "greet",
20+
"parameters": [
21+
{
22+
"name": "name",
23+
"in": "query",
24+
"required": false,
25+
"schema": {
26+
"type": "string"
27+
}
28+
}
29+
],
30+
"responses": {
31+
"200": {
32+
"description": "OK",
33+
"content": {
34+
"*/*": {
35+
"schema": {
36+
"$ref": "#/components/schemas/Greeting"
37+
}
38+
}
39+
}
40+
}
41+
}
42+
}
43+
},
44+
"/test": {
45+
"get": {
46+
"tags": [
47+
"example-controller"
48+
],
49+
"operationId": "test",
50+
"parameters": [
51+
{
52+
"name": "name",
53+
"in": "query",
54+
"required": true,
55+
"schema": {
56+
"type": "string"
57+
}
58+
}
59+
],
60+
"responses": {
61+
"200": {
62+
"description": "OK",
63+
"content": {
64+
"*/*": {
65+
"schema": {
66+
"$ref": "#/components/schemas/Greeting"
67+
}
68+
}
69+
}
70+
}
71+
}
72+
}
73+
},
74+
"/test-with-default": {
75+
"get": {
76+
"tags": [
77+
"example-controller"
78+
],
79+
"operationId": "testWithDefault",
80+
"parameters": [
81+
{
82+
"name": "name",
83+
"in": "query",
84+
"required": false,
85+
"schema": {
86+
"type": "string",
87+
"default": "world"
88+
}
89+
}
90+
],
91+
"responses": {
92+
"200": {
93+
"description": "OK",
94+
"content": {
95+
"*/*": {
96+
"schema": {
97+
"$ref": "#/components/schemas/Greeting"
98+
}
99+
}
100+
}
101+
}
102+
}
103+
}
104+
}
105+
},
106+
"components": {
107+
"schemas": {
108+
"Greeting": {
109+
"required": [
110+
"greeting"
111+
],
112+
"type": "object",
113+
"properties": {
114+
"greeting": {
115+
"type": "string"
116+
}
117+
}
118+
}
119+
}
120+
}
121+
}

0 commit comments

Comments
 (0)