openapi-generator
openapi-generator copied to clipboard
[BUG] [kotlin-spring] MissingKotlinParameterException instead of BeanValidation exception for missing required property
Bug Report Checklist
- [x] Have you provided a full/minimal spec to reproduce the issue?
- [x] Have you validated the input using an OpenAPI validator (example)?
- [x] What's the version of OpenAPI Generator used?
- [x] Have you search for related issues/PRs?
- [ ] What's the actual output vs expected output?
- [ ] [Optional] Bounty to sponsor the fix (example)
Description
I defined a required property but instead of getting a bean validation exception, I get a MissingKotlinParameterException:
com.fasterxml.jackson.module.kotlin.MissingKotlinParameterException: Instantiation of [simple type, class dto.Component] value failed for JSON property type due to missing (therefore NULL) value for creator parameter type which is a non-nullable type
at [Source: (PushbackInputStream); line: 1, column: 2] (through reference chain: dto.Component["type"])
Here is the generated DTO:
data class Component (
@get:NotNull
@ApiModelProperty(required = true, value = "")
@JsonProperty("type") val type: kotlin.String,
@ApiModelProperty(value = "")
@JsonProperty("model") val model: kotlin.String? = null
)
It seems validation is done after the dto is instantiated... and as a required field is null, it can't create a new instance of this dto.
openapi-generator version
kotlin-spring with 4.2.2
OpenAPI declaration file content or url
Component:
type: object
required:
- type
properties:
type:
type: string
model:
type: string
👍 Thanks for opening this issue! 🏷 I have applied any labels matching special text in your issue.
The team will review the labels and make any necessary changes.
Thanks for the issue!
I've confirmed the steps below reproduces the issue:
issue5121.yaml
openapi: 3.0.2
servers:
- url: 'http://localhost:8080'
info:
version: 1.0.0
title: OpenAPI Petstore
paths:
/pet:
post:
description: test
operationId: findPets
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Component'
description: test requestBody
required: true
responses:
'200':
description: successful operation
content:
application/json:
schema:
type: string
components:
schemas:
Component:
type: object
required:
- type
properties:
type:
type: string
model:
type: string
# Generate `kotlin-spring` server
$ java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar \
generate \
-g kotlin-spring \
-i issue5121.yaml \
-o /tmp/issue5121 \
--additional-properties swaggerAnnotations=true
# Run the generated server
$ cd /tmp/issue5121
$ gradle bootRun
# Send a POST request w/o `type` which is required field.
$ curl -v -X POST "http://localhost:8080/pet" \
-H "accept: application/json" \
-H "Content-Type: application/json" \
-d "{\"model\":\"string\"}" | jq
...
...
{
"timestamp": "2020-02-05T02:24:59.628+0000",
"status": 400,
"error": "Bad Request",
"message": "JSON parse error: Instantiation of [simple type, class org.openapitools.model.Component] value failed for JSON property type due to missing (therefore NULL) value for creator parameter type which is a non-nullable type; nested exception is com.fasterxml.jackson.module.kotlin.MissingKotlinParameterException: Instantiation of [simple type, class org.openapitools.model.Component] value failed for JSON property type due to missing (therefore NULL) value for creator parameter type which is a non-nullable type\n at [Source: (PushbackInputStream); line: 1, column: 18] (through reference chain: org.openapitools.model.Component[\"type\"])",
"path": "/pet"
}
If declear nullable and embed @field:Notnull :
data class Component(
@field:NotNull
@ApiModelProperty(example = "null", required = true, value = "")
@JsonProperty("type") val type: kotlin.String?,
@ApiModelProperty(example = "null", value = "")
@JsonProperty("model") val model: kotlin.String? = null
)
This issue will be solved. What do you think about this solution? @ackintosh @cthiebault
It would work... but it's too bad to have a poor model with non null field becoming nullable because of validation :( Maybe related to https://stackoverflow.com/a/41994512/386713 ?
Hmm... I can't think of other way. 🤔 💦
Technical Committee (Kotlin): @jimschubert @dr4ke616 @karismann @Zomzog @andrewemery @4brunu
Do you have any ideas?
Seems like a secondary constructor with and JsonCreator might work best, maybe also Delegates.notNull.
I'm not sure when I'd have time to look into, though.
I think you can set empty string as default value. Jackson should be able to parse it successfully.
@field:NotNull
@ApiModelProperty(example = "null", required = true, value = "")
@JsonProperty("type") val type: kotlin.String = '',
Guys please pay attention to this one, it messes up the validation flow and makes us devs do weird things to make it work.
@zipper2110 may I know if you can contribute a PR to start with?
quite an old story, any update on this?