Open API 3 Specs Generation
This is probably more of a limitation with the Open Api spec generation, but I'm curious as to why this is happening.
I'm building a proof of concept using the Open Api Schema annotations to generate the Open Api Spec document. And I get a spec document that doesn't seem to be usable to figure out the deserialization.
There doesn't seem to be a link between the CodifiedEnum and the Known Unknown objects.
Here's a code snippet of the Response class:
@ApiModel(
description = "An order from a customer"
)
data class Order(
//...
@Schema(
name = "status",
example = "DRAFT",
description = "The status of the order",
required = true
)
@Serializable(with = OrderStatus.CodifiedSerializer::class)
val status: CodifiedEnum<OrderStatus, String>,
// ...
}
Here's a code snippet of the OrderStatus enum:
@ApiModel(
description = "All order statuses"
)
enum class OrderStatus(override val code: String) : Codified<String> {
DRAFT("DRAFT"), PROCESSED("PROCESSED"), CANCELLED("CANCELLED");
object CodifiedSerializer : KSerializer<CodifiedEnum<OrderStatus, String>> by codifiedEnumSerializer()
}
The generated open api spec:
Order:
required:
- id
- status
type: object
properties:
id:
type: string
description: The order identifier
example: 2c93808457d787030157e02e7be22210
status:
$ref: '#/components/schemas/CodifiedEnumOrderStatusString'
CodifiedEnumOrderStatusString:
type: object
description: The status of the order
example: DRAFT
allOf:
- $ref: '#/components/schemas/CodifiedEnum'
CodifiedEnum:
type: object
Known:
required:
- value
type: object
allOf:
- $ref: '#/components/schemas/CodifiedEnumOrderStatusString'
- type: object
properties:
value:
type: string
- $ref: '#/components/schemas/CodifiedEnum'
Unknown:
required:
- value
type: object
allOf:
- $ref: '#/components/schemas/CodifiedEnumOrderStatusString'
- type: object
properties:
value:
type: object
- $ref: '#/components/schemas/CodifiedEnum'
Hi there. I'm not familiar with the OpenAPI specs, let alone its generation process, so sorry if my answer isn't helpful.
I wonder what exactly you would expect the generated spec to look like in your case.
I think that for the receiver, the use of the CodifiedEnum wrapper can act as a defense mechanism. Its use instead of the enum alone is a safeguard against unexpected compatibility problems or lack of proper API specification. That being said, I think you shouldn't need to expose (via OpenAPI spec) the fact you use CodifiedEnum as a protection measure. The clients of your API should send you one of the values you support (i.e. the "known" ones), shouldn't they?
Therefore, if I were you, I would probably aim to generate a specification that doesn't mention CodifiedEnum at all. Ideally, the specification should only mention the original enum OrderStatus but with the custom values (i.e. val code: String) instead of the enums' names (in your case, they are the same, but in general, they don't have to).
To add up to what @azabost said the primary aim of the Codified libs is to make it easier to keep code forward compatible regarding enums. That's more often the case of a client code, i.e. the code that receives enum values.
In other words if we expect our API clients to send us property attribute with fixed possible values (e.g. colour: "BLUE" or colour: "GREEN") then in the OpenAPI definition we have the standard enum definition. Even if in our DTOs we use Codified the OpenAPI definition should use regular enum definition. I suppose that should be possible currently by adding a properly configured @Schema annotation to the val status.
If we want our API to expose a property that has values from a known set and can have arbitrary values then I'd first check if it is possible to represent such a thing in the OpenAPI spec. If it is, we might need to add an extension to the Codified suite to handle that.