javaspring-mvcswaggerspringfox

How to represent fields with generic types like List<Something> in swagger-spring-mvc for swagger-codegen


I'm using swagger-spring-mvc 0.9.5 and have fields like this in my response data:

@ApiModelProperty("Some description")
private List<Account> accounts;

Short version of the question: how can I get from this annotated Java to e.g. Objective C via swagger-codegen?

The swagger JSON that gets generated by that is:

accounts: {
  description: "Some description",
  items: {
    type: "Account"
  },
  required: false,
  type: "List"
}

My colleague is feeding this into swagger-codegen to generate Objective C classes, and it's producing code that doesn't compile.

@property (nonatomic, strong) NSArray<Optional, NSArray> *accounts;

because NSArray (inside the < >) isn't a protocol.

The swagger template files (mustache) create a protocol for each model. When that protocol is specified on an array, it is picked up by JSONModel to generate the correct models from the data inside the list / array. So in this case the expected output is

@property (nonatomic, strong) NSArray<Optional, MAAccount> *accounts;

This will create an NSArray of MAAccount's (Account being the object type and MA being a prefix that swagger already has).

If we hand-edit the swagger JSON to change List to array (as suggested in various similar cases), the output is correct, but we want to avoid this manual step.

So I tried to get swagger-spring-mvc to use "array":

@ApiModelProperty(value = "Some description", dataType = "array")
private List<Account> accounts;

But then discovered that dataType is ignored in swagger-spring-mvc 0.9.5, and by the looks of it, in springfox 2.0 it is ignored unless it's a fully-qualified Java class name.

Is there a way to achieve this, either by getting swagger-spring-mvc/springfox to use "array" or by any other means?


Solution

  • For the most part the swagger annotations are only an aid to the springfox engine to infer additional information about the types like description/hidden/readonly etc that are not otherwise available from the type system. It can also used as a crutch to represent types that are not easily inferred. Data types can be overriden, but just for type safety as it was pointed out in the comment.

    Specifically, I read that dataType will be ignored unless it's a fully-qualified class name.

    Like @CupawnTae suggested, version 2.x of springfox supports an option to render generic types with code-generation friendly and language agnostic representations of generic types.

    When creating/configuring your docket you will need to specify that the rendered swagger service description needs to be code-generation friendly using the forCodeGeneration option

    @Bean
    public Docket docket() {
        return new Docket(DocumentationType.SWAGGER_2)
          ...
          .forCodeGeneration(true)
          ...;
    }
    

    This will cause springfox to render generic types like List<String>