Skip to content

Commit 396b76a

Browse files
committed
Required field in Schema annotation ignored in Kotlin. Fixes #2021.
1 parent 1e4d934 commit 396b76a

File tree

5 files changed

+180
-0
lines changed

5 files changed

+180
-0
lines changed

springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocKotlinConfiguration.kt

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ open class SpringDocKotlinConfiguration(objectMapperProvider: ObjectMapperProvid
4444
.addRequestWrapperToIgnore(Continuation::class.java)
4545
.replaceWithSchema(ByteArray::class.java, ByteArraySchema())
4646
.addDeprecatedType(Deprecated::class.java)
47+
objectMapperProvider.jsonMapper().registerModule(SpringDocRequiredModule())
4748
objectMapperProvider.jsonMapper().registerModule(KotlinModule.Builder().build())
4849
}
4950

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
*
3+
* *
4+
* * *
5+
* * * * Copyright 2019-2022 the original author or authors.
6+
* * * *
7+
* * * * Licensed under the Apache License, Version 2.0 (the "License");
8+
* * * * you may not use this file except in compliance with the License.
9+
* * * * You may obtain a copy of the License at
10+
* * * *
11+
* * * * https://www.apache.org/licenses/LICENSE-2.0
12+
* * * *
13+
* * * * Unless required by applicable law or agreed to in writing, software
14+
* * * * distributed under the License is distributed on an "AS IS" BASIS,
15+
* * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* * * * See the License for the specific language governing permissions and
17+
* * * * limitations under the License.
18+
* * *
19+
* *
20+
*
21+
*/
22+
23+
package org.springdoc.core.configuration;
24+
25+
import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
26+
import com.fasterxml.jackson.databind.introspect.NopAnnotationIntrospector;
27+
import com.fasterxml.jackson.databind.module.SimpleModule;
28+
import io.swagger.v3.oas.annotations.media.Schema;
29+
30+
/**
31+
* The type Spring doc required module.
32+
*
33+
* @author bnasslahsen
34+
*/
35+
public class SpringDocRequiredModule extends SimpleModule {
36+
37+
@Override
38+
public void setupModule(SetupContext context) {
39+
context.insertAnnotationIntrospector(new RespectSchemaRequiredAnnotationIntrospector());
40+
}
41+
42+
/**
43+
* The type Respect schema required annotation introspector.
44+
*/
45+
private static class RespectSchemaRequiredAnnotationIntrospector extends NopAnnotationIntrospector {
46+
@Override
47+
public Boolean hasRequiredMarker(AnnotatedMember m) {
48+
Schema schemaAnnotation = m.getAnnotation(Schema.class);
49+
return schemaAnnotation != null ? schemaAnnotation.required() : null;
50+
}
51+
}
52+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package test.org.springdoc.api.app9
2+
3+
import io.swagger.v3.oas.annotations.media.Schema
4+
import org.springframework.web.bind.annotation.*
5+
6+
@RestController
7+
@RequestMapping("/api/demo")
8+
class DocumentsApiController {
9+
10+
@GetMapping
11+
suspend fun getDocuments( request: DemoRequest
12+
): DemoDto = DemoDto(42)
13+
}
14+
15+
data class DemoDto(
16+
var id: Long,
17+
)
18+
19+
class DemoRequest {
20+
@field:Schema(required = false, description = "Should not be required")
21+
val nonNullableWithDefault: String = "a default value"
22+
23+
}
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.app9
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 SpringDocApp9Test : AbstractKotlinSpringDocTest() {
26+
27+
@SpringBootApplication
28+
@ComponentScan(basePackages = ["org.springdoc", "test.org.springdoc.api.app9"])
29+
open class DemoApplication
30+
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
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+
"/api/demo": {
15+
"get": {
16+
"tags": [
17+
"documents-api-controller"
18+
],
19+
"operationId": "getDocuments",
20+
"parameters": [
21+
{
22+
"name": "request",
23+
"in": "query",
24+
"required": true,
25+
"schema": {
26+
"$ref": "#/components/schemas/DemoRequest"
27+
}
28+
}
29+
],
30+
"responses": {
31+
"200": {
32+
"description": "OK",
33+
"content": {
34+
"*/*": {
35+
"schema": {
36+
"$ref": "#/components/schemas/DemoDto"
37+
}
38+
}
39+
}
40+
}
41+
}
42+
}
43+
}
44+
},
45+
"components": {
46+
"schemas": {
47+
"DemoRequest": {
48+
"required": [
49+
"nonNullableWithDefault"
50+
],
51+
"type": "object",
52+
"properties": {
53+
"nonNullableWithDefault": {
54+
"type": "string",
55+
"description": "Should not be required"
56+
}
57+
}
58+
},
59+
"DemoDto": {
60+
"required": [
61+
"id"
62+
],
63+
"type": "object",
64+
"properties": {
65+
"id": {
66+
"type": "integer",
67+
"format": "int64"
68+
}
69+
}
70+
}
71+
}
72+
}
73+
}

0 commit comments

Comments
 (0)