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.
To update the Box class to use generics, you create a generic type declaration by changing the code "public class Box" to "public class Box<T>". This introduces the type variable, T, that can be used anywhere inside the class. As you can see, all occurrences of Object are replaced by T.
Generic Methods A type parameter, also known as a type variable, is an identifier that specifies a generic type name. The type parameters can be used to declare the return type and act as placeholders for the types of the arguments passed to the generic method, which are known as actual type arguments.
Generic classes encapsulate operations that are not specific to a particular data type. The most common use for generic classes is with collections like linked lists, hash tables, stacks, queues, trees, and so on.
The annotation may be used to define a Schema for a set of elements of the OpenAPI spec, and/or to define additional properties for the schema. It is applicable e.g. to parameters, schema classes (aka "models"), properties of such models, request and response content, header.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With