Closed kirillsulim closed 4 months ago
I see the issue..
using x-tension keywords like this is a bit against the philosophy of openapi-processor.
I would like to keep tooling specific stuff out of the OpenAPI description. Let's assume we have multiple consumers of the api. Each consumer may use another programming languages and different tooling. Now we would have to add the x-enumNames
equivalent of each tooling to the OpenAPI... Things get more difficult when we don't have control over the OpenAPI description. We would have to add some pre-processing to add the enum names to the api.
Maybe this is a bit academic. ;-) In most cases this may not be an issue.
The oneOf
enum construction from stackoverflow is interesting. I guess I have see this before but I wonder if anyone is really using it.
I can also imagine to "hide" the x-tension keyword behind a "use at your own risk" option. So I can say here is a solution but it has its drawbacks.
The typical openapi-processor way would be to create some kind of mapping. That would be possible, but I fear this may be cumbersome to work with. Not sure. Probably depends on how many enums I need to map and how often I have to change them.
Hello, Martin!
I think I've understood your point of view. OpenAPI spec should be language independent and restrictions of enum values in .yaml config relates to JSON structure, not Java implementation. So possibly "01" would be absolutely legal enum value in some language and the developer shouldn't restrict enum names for languages in API spec.
It surely would be more convenient for me in my case to use extensions and generate enum with codes. However the main issue her as I think is that I'm trying to describe existing API that wasn't designed with OpenAPI in mind. There wouldn't be such issue if this API was developed with OpenAPI in first place.
Probably there is no much sense in proposed functionality in such case. I will try to use mapping config and describe enums with plain Java. Thanks for your review.
To have better names for enum values, you can create an enum with proper names yourself and tell the processor to use it. This is a strategy if there are only a few enums you like to improve.
For example the enum could look like this (in kotlin, apart from the enum names it is identical to the java enum code generated by the processor):
package io.openapiprocessor.samples
import com.fasterxml.jackson.annotation.JsonCreator
import com.fasterxml.jackson.annotation.JsonValue
import io.openapiprocessor.samples.model.BarBar
enum class NamedEnum(@JsonValue val value: String) {
ONE("1"),
TWO("2");
companion object {
@JsonCreator
fun fromValue(value: String): NamedEnum {
for (v in NamedEnum.entries) {
if (v.value == value) {
return v
}
}
throw IllegalArgumentException(value)
}
}
}
for an OpenAPI enum like this
// OpenAPI snippet
// ...
components:
schemas:
AnEnum:
type: string
enum:
- "1"
- "2"
After telling the processor to use our custom annotation by adding a type mapping
// mapping.yaml
openapi-processor-mapping: v7
options:
// ...
map:
types:
- type: AnEnum => io.openapiprocessor.samples.NamedEnum
the processor will use the custom annotation instead of generating an enum from the OpenAPI description. We can now use NamedEnum.ONE
in our code.
This works if the enum is a property of a (body) schema. If the enum is a query parameter you will probably need a custom Spring converter for string to enum conversion.
here is the Spring converter (kotlin)
package io.openapiprocessor.samples
import org.springframework.core.convert.converter.Converter
class NamedEnumConverter: Converter<String, NamedEnum> {
override fun convert(source: String): NamedEnum {
return NamedEnum.fromValue(source)
}
}
and the code to enable it
package io.openapiprocessor.samples
import org.springframework.context.annotation.Configuration
import org.springframework.format.FormatterRegistry
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer
@Configuration
open class WebConfig : WebMvcConfigurer {
override fun addFormatters(registry: FormatterRegistry) {
registry.addConverter(NamedEnumConverter())
}
}
summarized in an article https://openapiprocessor.io/oap/home/articles/mapping/custom-enum-mapping.html :-)
Thanks. That will be very helpful if someone would have similar issues with existing APIs.
In some of my projects I have to describe an openAPI interface with enum with values like "01", "02", etc. Those are codes for specific business cases. I would like to operate in my code with enum values like
ClientType.BASIC
instead ofClientType._01
or use string values for such cases. As I found out there are some openAPI generators that uses extensions likex-enumNames
for such cases (see this stackowerflow thread for more info).So I propose following logic: For enum schema like:
generate following java code: