restdocs-api-spec icon indicating copy to clipboard operation
restdocs-api-spec copied to clipboard

Document array of string/enum?

Open rivendell10 opened this issue 3 years ago • 4 comments

By using this library to document my rest API I struggled to document an array of enums. My model contains a list of simple Enums.

Model:

private List<StateValue> state =
      Lists.newArrayList(
          StateValue.SUCCESS,
          StateValue.ERROR,
          StateValue.WARNING);

By describing my model with the following line

fieldWithPath("state").type(JsonFieldType.ARRAY).description("array of states")

i got this as result:

state:
          type: array
          description: array of states
          items:
            oneOf:
            - type: object
            - type: boolean
            - type: string
            - type: number

The expected result should be like

"state" : {
            "type" : "array",
            "description" : "array of states",
            "items" : {
              "type": "string",
              "enum": [
                "SUCCESS",
                "ERROR",
                "WARNING"
              ]
            }
          },

I looked at the implementation of this plugin and tried to find a workaround for this problem. By describing the "state" field in my model with the type of "Enum" I got at least the enum documented in the right way.

 fieldWithPath("state")
                  .type("ENUM")
                  .description("array of states")
                  .attributes(key("enumValues").value(List.of(StateValue.values())))));

Result:

"state" : {
            "type" : "string",
            "description" : "Array of journey states",
            "enum" : [ "SUCCESS", "ERROR", "WARNING" ]
          },

I found a similar issue here #87 which is marked as fixed but it did not work.

Is there a way to document an array of enums correctly in regards to openApi3 specifications? Is there a way to fix this issue in time?

I also want to mention that the documentation about document enums could be improved. Nothing was found about it in the library documentation. Only looking at the implementation I was able to document a simple Enum.

rivendell10 avatar Nov 12 '20 06:11 rivendell10

Hey @rivendell10 ,

thanks for reaching out!

Afaics, #87 and related changes are correct regarding OpenAPI 2/3 generation and try to document possible enum values for fields using idiomatic Spring restdocs.

However, I can acknowledge that arrays of enum values weren't considered.

ozscheyge avatar Nov 24 '20 14:11 ozscheyge

The items.type part of this issue should be fixed with https://github.com/ePages-de/restdocs-api-spec/pull/186

This leaves to check, whether possible enum values are correctly rendered in the generated JSON schema.

ozscheyge avatar Aug 25 '21 16:08 ozscheyge

Related: possible values for Header-/ParameterDescriptors https://github.com/ePages-de/restdocs-api-spec/issues/95

ozscheyge avatar Feb 18 '22 00:02 ozscheyge

We had same issue. But, we've added some workaround by introducing wrapper to set additional attributes which was introduced in #186.

For example, if you would like to document collection of enum. You can do as followings.


    private static Attribute[] getAttributesForItemsType(Class<?> clazz) {
        String itemsType = determineOpenApiFieldType(clazz);
        if (itemsType.equals("enum")) {
            List<?> possibleValues = possibleEnumValues(clazz);
            String formattedEnumValues = formattedEnumValues(possibleValues);

            // add enum related attributes
            return new Attribute[]{
                key("enumValues").value(possibleValues), key("itemsType").value(itemsType)};
        } else {
            return new Attribute[]{key("itemsType").value(itemsType)};
        }
    }

The thing is that the field should be array type, which you don't need explicitly set it. And the item type should be passed with itemsType key in attributes. And if the itemsType value is enum, then you should pass enum possible values with enumValues key in the attributes as well.

In order to do so, you can create your own FieldDescriptor wrapper having following similar methods.

public FieldDescriptor withPath(String path);

In that method, you can check the each field type with reflection and if the filed type is kind of collection, you could set additional attributes to describe the element type of the collection.

Kieun avatar Sep 01 '23 12:09 Kieun