📘 Premium Read: Access my best content on Medium member-only articles — deep dives into Java, Spring Boot, Microservices, backend architecture, interview preparation, career advice, and industry-standard best practices.
✅ Some premium posts are free to read — no account needed. Follow me on Medium to stay updated and support my writing.
🎓 Top 10 Udemy Courses (Huge Discount): Explore My Udemy Courses — Learn through real-time, project-based development.
▶️ Subscribe to My YouTube Channel (172K+ subscribers): Java Guides on YouTube
In order to generate the Swagger documentation, swagger-core offers a set of annotations to declare and manipulate the output. The swagger-core output is compliant with Swagger Specification.
Each annotation also has links to its javadocs . The javadocs provide you with additional information about each annotation, especially dealing with some edge cases. Check out javadocs of these annotations on Swagger Annotations JavaDocs.
If you are not familiar with Swagger, you should visit its web page to learn more before continuing with this article.
Let's list all Swagger core annotations that are RESTFul API Documentation in Java.
Quick Annotation Overview
Name | Description |
---|---|
@Api | Marks a class as a Swagger resource. |
@ApiImplicitParam | Represents a single parameter in an API Operation. |
@ApiImplicitParams | A wrapper to allow a list of multiple ApiImplicitParam objects. |
@ApiModel | Provides additional information about Swagger models. |
@ApiModelProperty | Adds and manipulates data of a model property. |
@ApiOperation | Describes an operation or typically an HTTP method against a specific path. |
@ApiParam | Adds additional meta-data for operation parameters. |
@ApiResponse | Describes a possible response of an operation. |
@ApiResponses | A wrapper to allow a list of multiple ApiResponse objects. |
@Authorization | Declares an authorization scheme to be used on a resource or an operation. |
@AuthorizationScope | Describes an OAuth2 authorization scope. |
@Api
The @Api is used to declare a Swagger resource API. It serves a double purpose - it affects the Resource Listing and the API Declaration. Only classes that are annotated with @Api will be scanned by Swagger.@Path("/pet")
@Api(value = "/pet", description = "Operations about pets")
@Produces({"application/json", "application/xml"})
public class PetResource {
...
}
apis
array): {
"path": "/pet",
"description": "Operations about pets"
}
@ApiOperation
@ApiOperation
is used to declare a single operation within an API resource. An operation is considered a unique combination of a path and a HTTP method. Only methods that are annotated with @ApiOperation
will be scanned and added the API Declaration.@Api
would affect the API Object instead as it sets the path. @GET
@Path("/findByStatus")
@ApiOperation(value = "Finds Pets by status",
notes = "Multiple status values can be provided with comma seperated strings",
response = Pet.class,
responseContainer = "List")
public Response findPetsByStatus(...) { ... }
value
of the annotation is a short description on the API. Since this is displayed in the list of operations in Swagger-UI and the location is limited in size, this should be kept short (preferably shorter than 120 characters). The notes
allows you to give significantly more details about the operations (e.g. you can include request samples and responses here). response
is the return type of the method. Notice that the actual method declaration returns a Response
but that is a general-purpose JAX-RS class and not the actual response sent to the user. If the returned object is the actual result, it can be used directly instead of declaring it in the annotation. Since we want to return a list of pets, we declare that using the responseContainer
. Keep in mind that Java has type erasure, so using generics in the return type may not be parsed properly, and the response
should be used directly. The @GET
JAX-RS annotation will be used as the (HTTP) method
field of the operation, and the @Path
would tell us the path of the operation (operations are grouped under the same path, one for each HTTP method used). {
"path": "/pet/findByStatus",
"operations": [
{
"method": "GET",
"summary": "Finds Pets by status",
"notes": "Multiple status values can be provided with comma seperated strings",
"type": "array",
"items": {
"$ref": "Pet"
},
"nickname": "findPetsByStatus",
.
.
.
@ApiResponses, @ApiResponse
@ApiResponse
describes a concrete possible response. It cannot be used directly on the method and needs to be included in the array value of @ApiResponses
(whether there's one response or more). @ApiResponses(value = { @ApiResponse(code = 400, message = "Invalid ID supplied"),
@ApiResponse(code = 404, message = "Pet not found") })
public Response getPetById(...) {...}
@Authorization, @AuthorizationScope
@ApiOperation(value = "Add a new pet to the store",
authorizations = {
@Authorization(
value="petoauth",
scopes = {
@AuthorizationScope(
scope = "add:pet",
description = "allows adding of pets")
}
)
}
)
public Response addPet(...) {...}
"authorizations": {
"petoauth": [
{
"scope": "add:pet",
"description": "allows adding of pets"
}
]
}
@ApiParam
The @ApiParam is used solely with the JAX-RS parameter annotations (@PathParam, @QueryParam, @HeaderParam, @FormParam and in JAX-RS 2, @BeanParam). While swagger-core scans these annotations by default, the @ApiParam can be used to add more details on the parameters or change the values as they are read from the code.Swagger will pick up the value() of these annotations and use them as the parameter name, and based on the annotation it will also set the parameter type. For the body parameter (the single input parameter of a JAX-RS method), the name will automatically be set as a body (as required by the Swagger Specification). Swagger will also use the value of @DefaultValue as the default value property if one exists.
@Path("/{username}")
@ApiOperation(value = "Updated user",
notes = "This can only be done by the logged in user.")
public Response updateUser(
@ApiParam(value = "name that need to be updated", required = true) @PathParam("username") String username,
@ApiParam(value = "Updated user object", required = true) User user) {...}
"parameters": [
{
"name": "username",
"description": "name that need to be updated",
"required": true,
"type": "string",
"paramType": "path",
"allowMultiple": false
},
{
"name": "body",
"description": "Updated user object",
"required": true,
"type": "User",
"paramType": "body",
"allowMultiple": false
}
]
@ApiImplicitParam, @ApiImplicitParams
- Using Servlets which don't use JAX-RS annotations.
- Wanting to hide a parameter as it is defined and override it with a completely different definition.
- Describe a parameter that is used by a filter or another resource prior to reaching the JAX-RS implementation.
When defining parameters implicitly, it's important to set name, dataType, and paramType for Swagger's definitions to be proper.
@ApiImplicitParams({
@ApiImplicitParam(name = "name", value = "User's name", required = true, dataType = "string", paramType = "query"),
@ApiImplicitParam(name = "email", value = "User's email", required = false, dataType = "string", paramType = "query"),
@ApiImplicitParam(name = "id", value = "User ID", required = true, dataType = "long", paramType = "query")
})
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {...}
"parameters": [
{
"name": "name",
"description": "User's name",
"required": true,
"type": "string",
"paramType": "query",
"allowMultiple": false
},
{
"name": "email",
"description": "User's email",
"required": false,
"type": "string",
"paramType": "query",
"allowMultiple": false
},
{
"name": "id",
"description": "User ID",
"required": true,
"type": "integer",
"format": "int64",
"paramType": "query",
"allowMultiple": false
}
]
@ApiModel
@ApiModel
allows you to manipulate the meta data of a model from a simple description or name change to a definition of polymorphism.@ApiModel
to change the name of the model and add a description to it:@ApiModel(value="DifferentModel", description="Sample model for the documentation")
class OriginalModel {...}
"DifferentModel": {
"id": "DifferentModel",
"description": "Sample model for the documentation",
.
.
}
discriminator
and the subTypes
fields. Both must be used for the Swagger output to be valid.discriminator
field must be a field at the top model which will be used to determine which sub model is being used. For example, if you have an Animal
class with Cat
, Dog
and Chicken
as sub classes, the animalType
field could be used as the discriminator to determine which animal is actually being used.subTypes
must list the classes of the inheriting models. The classes themselves don't have to inherit from the super type. In fact, Swagger will not automatically read the extending classes and you have to manually describe these classes in the subTypes
in order for them to be parsed.@ApiModel(value="SuperModel", discriminator = "foo", subTypes = {SubModel.class})
public class SuperModel {...}
@ApiModel(value="SubModel")
public class SubModel {...}
"SuperModel": {
"id": "SuperModel",
"required": [
"foo"
],
"properties": {
"foo": {
"type": "string"
}
},
"subTypes": ["SubModel"],
"discriminator": "foo"
},
"SubModel": {
"id": "SubModel",
"properties": {
...
},
}
@ApiModelProperty
@ApiModelProperty
allows controlling Swagger-specific definitions such as allowed values, and additional notes. It also offers additional filtering properties in case you want to hide the property in certain scenarios. @ApiModelProperty(value = "pet status in the store", allowableValues = "available,pending,sold")
public String getStatus() {
return status;
}
status
is a String, we document it as having only three possible values. "properties": {
...,
"status": {
"type": "string",
"description": "pet status in the store",
"enum": [
"available",
"pending",
"sold"
]
}
}
Check out usage of these annotations in this article - Spring Boot 2 RESTful API Documentation with Swagger 2 Tutorial
Comments
Post a Comment
Leave Comment