openapi-generator: [BUG][spring] Enum query parameter parsing fails due to enum constants being generated in uppercase
Description
Even when enum values are lower-case in the specification, openapi-generator produces uppercased enum constants in Java, apparently due to the convention. However, this means that lowercased values in enum query parameters are not parsed correctly, resulting in 400 Bad requests for valid requests.
openapi-generator version
4.0.3, was present in 3.2 as well
OpenAPI declaration file content or url
openapi: 3.0.2
info:
title: Catalog
version: '1.0'
servers:
- url: 'http://localhost:8080'
components:
schemas:
ProductType:
type: string
enum:
- hardware
- SOFTWARE
paths:
/products:
get:
operationId: getProducts
parameters:
- in: query
name: type
schema:
$ref: '#/components/schemas/ProductType'
responses:
'200':
description: Ok
Command line used for generation
java -jar openapi-generator-cli.jar generate -i catalog.yaml -g spring
Steps to reproduce
mvn spring-boot:runcurl -i "http://localhost:8080/products?type=hardware"
Expected outcome: HTTP/1.1 501 due to missing implementation, and no warnings output by Spring. (This is the case for the uppercase type=SOFTWARE)
Actual outcome: HTTP/1.1 400 and the following warning:
2019-07-11 12:29:39.186 WARN 12951 --- [nio-8080-exec-4] .w.s.m.s.DefaultHandlerExceptionResolver : Failed to bind request element:
org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'org.openapitools.model.ProductType'; nested exception is
org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [@io.swagger.annotations.ApiParam @javax.validation.Valid org.openapitools.model.ProductType] for value 'hardware'; nested exception is
java.lang.IllegalArgumentException: No enum constant org.openapitools.model.ProductType.hardware
Spring is trying to do Enum.valueOf(ProductType.class, "hardware") which fails, since openapi-generator produces the constant as ProductType.HARDWARE.
Related issues/PRs
Issue #1927 is related: producing enum in MACRO_CASE also results in non-working @DefaultValue annotations.
Suggest a fix
I would consider just reverting to producing enum constants matching the API specification. If this is considered unacceptable, then probably the way to fix this bug would be to:
- Produce a
model.FooConverter extends java.Beans.PropertyEditorSupportfor each enum schema Foo, implementingsetAsTextutilizingmodel.Foo::fromValue - For each controller where an enum is used as a parameter, add
@InitBinder public void initBinder(WebDataBinder dataBinder) { dataBinder.registerCustomEditor(Foo.class, new FooConverter()) }
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 13
- Comments: 22 (1 by maintainers)
Commits related to this issue
- 64 - Restrict valid parameter for themes in asset search Converter is needed because of https://github.com/OpenAPITools/openapi-generator/issues/3337 — committed to teamdigitale/dati-semantic-backend by ronytw 3 years ago
- openapi: fix enum identitifier https://github.com/OpenAPITools/openapi-generator/issues/3337 — committed to edu-sharing/edu-sharing-community-repository by thomschke 2 years ago
Ran into this issue today. What worked for is creating a custom Converter in Spring boot to convert the Enum to String
same situation
schema
generated enum
Any news regarding this issue?
Not clear from the above if this is solved (I’m using 5.1.1 and still happening), but I found a simple enough way to get around it without needing to customise the enum templates.
Instead of defining the enum values only, add coressponding values under the x-enum-varnames as in the example below. This will overwrite the uppercase constant with the values you specify with no uppercase conversion. i.e.
Generates
Repetitive I know but preferable (for me anyway) to forcing everything to uppercase. Project I’m working on has a lot of configuration and properties identifiers in enums so retaining case sensitivity is essential.
Any updates here? A solution would be greatly appreciated.
Something seems to be wrong in Spring validation as the ENUMs are generated with correct lowercase value. Still values sent with lowercase fail with:
java.lang.IllegalArgumentException: No enum constant nameSpring is not using the generated fromValue method (which works with lowercase) but instead
Enum.valueOf(this.enumType, source.trim())inStringToEnumConverterFactory.I am not sure how that MR fixed anything @tkalliom. It doesn’t generate a converter to register to spring, it just shows what a converter would look like in the samples 🤔