Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for multiple allowable values #1037

Closed
smwurster opened this issue Nov 5, 2015 · 23 comments
Closed

Support for multiple allowable values #1037

smwurster opened this issue Nov 5, 2015 · 23 comments
Labels
Milestone

Comments

@smwurster
Copy link

What is the current support for an ApiModelProperty being a List and declaring allowableValues?

If I have a request object whose type is just a standard type (e.g. String), then the generated swagger spec will show the type as string and enum containing the allowable values. Likewise, all of the allowable values will display properly on the swagger UI page.

If I have a request object whose type is a List, then the generated swagger spec will show the type as array, but there will be an items entry with type string and enum containing the allowable values. The set of allowable values will not be displayed at all on the swagger UI page.

If I run swagger-codegen for Java against this spec file I end up getting an error when it tries to generate the model for the request object. The failure seems to indicate that it thinks the value type itself is an ArrayList instead of just the (generated) enum.

I don't know if this problem lies within springfox or the swagger-codegen, but the fact that the UI page doesn't display the set of allowable values leads me to think this is an issue with springfox.

@dilipkrish
Copy link
Member

This is by design. I know the swagger ui and the swagger editor don't render this correctly. This might be a problem with the code gen too.

@dilipkrish dilipkrish added this to the 2.3.0 milestone Nov 6, 2015
@smwurster
Copy link
Author

By "by design", do you mean the JSON spec file meets the swagger spec for this type of case?

@dilipkrish
Copy link
Member

"By design" meaning this is the best way to describe this in the spec such that its semantically equivalent to the json that is serialized over the wire.

@smwurster
Copy link
Author

Okay.

So does there need to be a change made in springfox to get the swagger ui to display all of the allowable options correctly? Or does there only need to be a change made in swagger ui?

If no change is needed in springfox then obviously there is a defect in the code gen. So I guess it just comes down to whether springfox needs an update or not. 😄

@dilipkrish
Copy link
Member

I would venture to say that swagger-ui doesn't render correctly.

I would also venture out and say after some investigation right now, that there is a feature that springfox doesn't support.... yet

Given

  @RequestMapping(value = "/enums", method = RequestMethod.GET, produces = { MediaTypes.HAL_JSON_VALUE })
  @ResponseBody
  public HttpEntity<List<AnEnum>> getEnums() {
    throw new UnsupportedOperationException();
  }

Generates this:

{
    "/upload/enums": {
        "get": {
            "consumes": [
                "application/json"
            ],
            "operationId": "getEnumsUsingGET",
            "produces": [
                "application/hal+json"
            ],
            "responses": {
                "200": {
                    "description": "OK",
                    "schema": {
                        "items": {
                            "type": "string"
                           // SHOULD ALSO GENERATE this
                           // "enum": [
                           //     "ONE",
                           //   "TWO"
                           // ]
                        },
                        "type": "array"
                    }
                },
                "401": {
                    "description": "Unauthorized"
                },
                "403": {
                    "description": "Forbidden"
                },
                "404": {
                    "description": "Not Found"
                }
            },
            "summary": "getEnums",
            "tags": [
                "file-upload-controller"
            ]
        }
    }
}

@dilipkrish dilipkrish modified the milestones: 2.4.0, 2.3.0 Nov 6, 2015
@dilipkrish
Copy link
Member

Thanks for persisting 🤘 I've made it a feature request

@smwurster
Copy link
Author

Cool. I'll post a JSON snippet tomorrow that shows what I'm currently getting. Thanks.

@smwurster
Copy link
Author

Here is what the Java looks like that I'm dealing with:

@ApiModelProperty(value="a list of values", allowableValues="foo,bar,baz", required=false)
public void setValues(List<String> values) {
    this.values = values;
}

And here is the resulting part from the swagger spec file:

"values": {
    "type": "array",
    "description":  "a list of values",
    "items": {
        "type": "string",
        "enum": [
            "foo",
            "bar",
            "baz"
        ]
    }
}

As noted, the swagger ui is not showing the available options (foo, bar, baz).

Is this JSON style correct, or should it be defined differently for this case? The answer to that will lead me to look more into submitting issues against swagger-ui and swagger-codegen.

Thanks!

@dilipkrish
Copy link
Member

@smwurster Im assuming that by this 👇

And here is the resulting part from the swagger spec file:

you mean that this is what you expect to be rendered

@smwurster
Copy link
Author

you mean that this is what you expect to be rendered

No, that's what I am getting. Is that to be expected? That is, is it valid?

To compare, this is what you get when you just have a single String as the type:

"someValue": {
    "type": "string",
    "description": "asdf",
    "enum": [
        "foo",
        "bar"
    ]
}

For this case, swagger-ui will show the options and the code generator never complains.

@dilipkrish
Copy link
Member

Ok cool .. the problem isn't as bad as I thought then. Just to restate the problem on springfox's end. When we have a parameter (not model property) that is a list of enums the rendered output is missing the enum under the items property, like you have above.

@smwurster
Copy link
Author

So is the items property supposed to be there for model classes that declare allowable values but only support one at a time?

@dilipkrish
Copy link
Member

No thats not what I meant...

When you have a List<SomeEnum> as a property, it seems like its working fine.

e.g. this totally seems to be working

requestMapping(SomeModel model) 

class SomeModel {
   List<SomeEnum> enums;
}

e.g. this totally seems to be working

but this does not work as expected.

requestMapping(List<SomeEnum> enums) 

@smwurster
Copy link
Author

In my case, I have this:

@ApiOperation(...)
void requestMapping(SomeModel model);

class SomeModel {
    @ApiModelProperty(allowableValues="Foo,Bar,Baz")
    List<String> getThings();
}

This is not working as I expect. The JSON spec file looks different for this compared to this model:

class SomeModel {
    @ApiModelProperty(allowableValues="Foo,Bar,Baz")
    String getThing();
}

The second option works as I expect in the UI, and the Java code is generated correctly. The first option does not display correctly in the UI, and the Java code fails to generate.

So where do the defects reside: springfox, swagger-ui, and/or swagger-codegen?

@smwurster
Copy link
Author

From what I can tell, this is what the JSON should look like for my case:

"values": {
    "type": "array",
    "description": "a list of values",
    "items": {
        "type": "string"
    },
    "enum": [
        "foo",
        "bar",
        "baz"
    ]
}

Note that the enums are at the top-level in the values element, while the items element only contains the type. When the JSON is formatted this way the swagger-ui online editor will show all of the allowable options correctly. Likewise, the swagger-codegen will not fail to generate Java code, and will properly define this entry as a list (which it is in Java).

dilipkrish added a commit that referenced this issue Feb 9, 2016
@dilipkrish
Copy link
Member

Ended up reverting the fix as I realized the swagger models do not support enums in array types :(

@smwurster
Copy link
Author

My comment from November 9th 2015 shows what the output is supposed to look like. As I noted in that comment, the swagger-ui online editor will accept that (or at least it did at the time) and will show all of the allowable values correctly.

dilipkrish added a commit that referenced this issue Feb 9, 2016
@dilipkrish
Copy link
Member

@smwurster was a lil' confused with all the different things that the enums could surface in. This is now fixed for any parameter (except for body parameters which does not support enums)

@smwurster
Copy link
Author

Cool. I'm looking forward to the next release.

dilipkrish added a commit that referenced this issue Feb 10, 2016
@smwurster
Copy link
Author

This is still broken in 2.4.0 (sorry, just checking this now). There is no change to the generated JSON between 2.2.2 and 2.4.0 for this scenario.

@dilipkrish
Copy link
Member

@smwurster perhaps create a new issue? It gets real confusing after a long thread what the original issue was?

@smwurster
Copy link
Author

Will do.

@smwurster
Copy link
Author

Submitted #1329

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants