I have about 40 APIs that have similar base response structure as follows:
{
"lastAccessed": "2015-30-08:14:21:45T",
"createdOn": "2015-30-07:09:04:10T",
"lastModified": "2015-30-08:14:21:45T",
"isReadOnly": "false",
"usersAllowed" : ["Tim", "Matt", "Christine"];
"noOfEntries": 1,
"object": [
"ObjectA": {
//here object A has its own model
}
]
}
So I have a base response class taking a generic of type T as follows:
public class Response<T> {
@ApiModelProperty(value="Last time accessed")
private String lastAccessed;
@ApiModelProperty(value="Time when Created ")
private String createdOn;
private String lastModified;
@ApiModelProperty(value="Created on")
private boolean isReadOnly;
@ApiModelProperty(value="Users that has access to the object.")
private List<String> usersAllowed;
private int noOfEntries;
private T object;
//getters and setters
}
So for the API A, which returns the Object of type with its own fields, I am returning Response as the API response in the controller:
public class A {
@ApiModelProperty(value="Name")
private String name;
@ApiModelProperty(value="OID")
private String id;
//getters and setters
}
In the controller: Response data = new Response(); ResponseEntity response = new ResponseEntity<>(data, HttpStatus.OK);
Is there a way in swagger I can specify the model of the response object recursively? For example, I could have the annotation @ApiOperation(response=Response.class) but that would not have the model for A.
I am using swagger 2 and following resolved this problem for me.
Remove 'response' property from both @ApiResponse
and @ApiOperation
. Then swagger will automatically generate the response class for you for 200 OK from method stubs (irrespective of whether with/without generics in response class).
@ApiOperation(value = "what your operation does")
@ApiResponses(value = { @ApiResponse(code = 200, message = "Success message") })
Update: You can do this simple work around. Just say you want to output Response<MyClass>
as response return type. You can do,
In controller class, specify an empty private class like this
private MyResponseClass extends Response<MyClass>{}
And for the swagger spec, specify like this,
@ApiResponse(code = 200, respone=MyResponseClass.class)
Remember that at the moment, swagger doesn't support generics. Above two are just workarounds.