I’m generating OpenAPI 3.0 documentation from annotated java code. But the issue is that when I add @Schema annotation to enum all the values disappear. I'm using Thorntail 2.3.0.Final with microprofile-openapi fraction.

I know I can just change the .yaml file but I need my yaml to be generated directly from Java code.

Here is my minimal example on github:https://github.com/pkristja/openApiEnumSchema

Source code for enum:

package com.example.openapiexample.model;import com.fasterxml.jackson.annotation.JsonCreator;import com.fasterxml.jackson.annotation.JsonValue;import org.eclipse.microprofile.openapi.annotations.media.Schema;@Schema(description = "<div class=\\\"renderedMarkdown\\\"><p>Rank of developer.</p>\\n\" +\n" +" \"<p>Valid values are:</p>\\n\" +\n" +" \"<ul>\\n\" +\n" +" \"<li>'JUNIOR_DEVELOPER_1': Text for junior 1.\\n\" +\n" +" \"<li>'JUNIOR_DEVELOPER_2': Text for junior 2.\\n\" +\n" +" \"<li>'JUNIOR_DEVELOPER_3': Text for junior 3.\\n\" +\n" +" \"<li>'SENIOR_DEVELOPER_1': Text for senior 1.\\n\" +\n" +" \"<li>'SENIOR_DEVELOPER_2': Text for senior 1.\\n\" +\n" +" \"<li>'SENIOR_DEVELOPER_3': Text for senior 1.\\n\" +\n" +" \"</ul>\\n\" +\n" +" \"<p>Random text...\\n\" +\n" +" \"and has to be added to this API definition as well.</p></div>",enumeration = {"junior_developer_1", "junior_developer_2", "junior_developer_3","senior_developer_1", "senior_developer_2", "senior_developer_3"})public enum Rank {JUNIOR_DEVELOPER_1("junior_developer_1"),JUNIOR_DEVELOPER_2("junior_developer_2"),JUNIOR_DEVELOPER_3("junior_developer_3"),SENIOR_DEVELOPER_1("senior_developer_1"),SENIOR_DEVELOPER_2("senior_developer_2"),SENIOR_DEVELOPER_3("senior_developer_3");private String value;Rank(String value) {this.value = value;}@Override@JsonValuepublic String toString() {return String.valueOf(value);}@JsonCreatorpublic static Rank fromValue(String text) {for (Rank b : Rank.values()) {if (String.valueOf(b.value).equals(text)) {return b;}}return null;}}

And source code for Object including enum:

package com.example.openapiexample.model;import lombok.Data;import org.eclipse.microprofile.openapi.annotations.media.Schema;@Data@Schema(description = "Schema for Developer object...")public class Developer {@Schema(required = true, description = "First name of the developer")private String firstName;@Schema(required = true, description = "Last name of the developer")private String lastName;@Schema(required = true, implementation = Rank.class)private Rank developerRank;}

Snipped of generated OpenAPI 3.0 documentation:

 schemas:Developer:description: Schema for Developer object...required:- developerRank- firstName- lastNameproperties:developerRank:description: |-<div class=\"renderedMarkdown\"><p>Rank of developer.</p>\n" +"<p>Valid values are:</p>\n" +"<ul>\n" +"<li>'JUNIOR_DEVELOPER_1': Text for junior 1.\n" +"<li>'JUNIOR_DEVELOPER_2': Text for junior 2.\n" +"<li>'JUNIOR_DEVELOPER_3': Text for junior 3.\n" +"<li>'SENIOR_DEVELOPER_1': Text for senior 1.\n" +"<li>'SENIOR_DEVELOPER_2': Text for senior 2.\n" +"<li>'SENIOR_DEVELOPER_3': Text for senior 3.\n" +"</ul>\n" +"<p>Random text...\n" +"and has to be added to this API definition as well.</p></div>type: stringproperties:value:type: stringfirstName:description: First name of the developertype: stringlastName:description: Last name of the developertype: string

But if I remove @Schema annotation before enum in Developer class I get generated enum values but without description and required value like this:

schemas:Developer:description: Schema for Developer object...required:- firstName- lastNameproperties:developerRank:enum:- JUNIOR_DEVELOPER_1- JUNIOR_DEVELOPER_2- JUNIOR_DEVELOPER_3- SENIOR_DEVELOPER_1- SENIOR_DEVELOPER_2- SENIOR_DEVELOPER_3type: stringfirstName:description: First name of the developertype: stringlastName:description: Last name of the developertype: string

Is there a way I can have have both enum values and description or am I doing something wrong?

1

Best Answer


You can use the @Schema for the enum to indicate it to use the value property instead of the name property by specifying the implementation class.

For example

@Schema(implementation = Rank::class)public enum Rank {JUNIOR_DEVELOPER_1("junior_developer_1"),JUNIOR_DEVELOPER_2("junior_developer_2"),JUNIOR_DEVELOPER_3("junior_developer_3"),SENIOR_DEVELOPER_1("senior_developer_1"),SENIOR_DEVELOPER_2("senior_developer_2"),SENIOR_DEVELOPER_3("senior_developer_3");private String value;Rank(String value) {this.value = value;}:}