Swagger Annotations for Rest API Documentation


In this article, we will explore all Swagger core annotations used for RESTFul API Documentation in Java.

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

NameDescription
@ApiMarks a class as a Swagger resource.
@ApiImplicitParamRepresents a single parameter in an API Operation.
@ApiImplicitParamsA wrapper to allow a list of multiple ApiImplicitParam objects.
@ApiModelProvides additional information about Swagger models.
@ApiModelPropertyAdds and manipulates data of a model property.
@ApiOperationDescribes an operation or typically an HTTP method against a specific path.
@ApiParamAdds additional meta-data for operation parameters.
@ApiResponseDescribes a possible response of an operation.
@ApiResponsesA wrapper to allow a list of multiple ApiResponse objects.
@AuthorizationDeclares an authorization scheme to be used on a resource or an operation.
@AuthorizationScopeDescribes 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.

Example: A JAX-RS usage would be:
@Path("/pet")
@Api(value = "/pet", description = "Operations about pets")
@Produces({"application/json", "application/xml"})
public class PetResource {
 ...
}
Here we have a Pet resource that is exposed on /pet. The @Api here states that the documentation of this resource will be hosted under /pet as well and there’s a description given to this resource. Swagger will pick up on the @Produces annotation but you can override this value if you wish.
The output of the Resource Listing would be (as a value in the apis array):
    {
      "path": "/pet",
      "description": "Operations about pets"
    }
For further details about this annotation, usage and edge cases, check out the javadocs.

@ApiOperation

The @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.
The annotation will affect two parts of the Swagger output, the API Object, which would be created one per path, and the Operation Object, which would be created one per @ApiOperation. Remember that when using Servlets, the @Api would affect the API Object instead as it sets the path.
A JAX-RS usage would be:
 @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(...) { ... }
The 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).
The output would be:
    {
      "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",
          .
          .
          .
For further details about this annotation, usage and edge cases, check out the javadocs.

@ApiResponses, @ApiResponse

It's a common practice to return errors (or other success messages) using HTTP status codes. While the general return type of an operation is defined in the @ApiOperation, the rest of the return codes should be described using these annotations.
The @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).
If the response is accompanied by a body, the body model can be described as well (one model per response).
There's no difference in usage between usages (JAX-RS, Servlets or otherwise):
  @ApiResponses(value = { @ApiResponse(code = 400, message = "Invalid ID supplied"),
      @ApiResponse(code = 404, message = "Pet not found") })
  public Response getPetById(...) {...}

@Authorization, @AuthorizationScope

These annotations are used as input to @Api and @ApiOperation only, and not directly on the resources and operations. Once you've declared and configured which authorization schemes you support in your API, you can use this annotation to note which authorization scheme is required on a resource or a specific operation. The @AuthorizationScope is specific to the case of an OAuth2 authorization scheme where you may want to specify specific supported scopes.
The behavior between the implementations (JAX-RS, Servlets or otherwise) is the same:
  @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(...) {...}
In this case, we declare that the addPet operation uses the petoauth authorization scheme (we'll assume it is an OAuth2 authorization scheme). Then using the @AuthorizationScope we fine-tune the definition by saying it requires the add:pet scope. As mentioned above, you can see that @AuthorizationScope is used as an input to @Authorization, and that in turn is used as input to @ApiOperation. Remember, these annotations can only be used as input to @Api and @ApiOperation. Using any of them directly on a class or a method will be ignored.
The output would be:
  "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) {...}
Here we have two parameters. The first, username which is a part of the path. The second is the body, in this case, a User object. Note that both parameters have the required property set to true. For the @PathParam, this is redundant as it is mandatory by default and cannot be overridden.
The output would be:
 "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
            }
          ]
For further details about this annotation, usage and edge cases, check out the javadocs.

@ApiImplicitParam, @ApiImplicitParams

You may wish you describe operation parameters manually. This can be for various reasons, for example:
  • 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.
Since there can be several parameters to be included, the @ApiImplicitParams allows for multiple @ApiImplicitParam definitions.
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 {...}
In the above sample, we can see a Servlet definition with several parameters. The dataType can be either a primitive or a class name. The paramType can be any of the parameter types that are supported by Swagger (refer to the javadocs or the spec for further details).
 "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

Swagger-core builds the model definitions based on the references to them throughout the API introspection. The @ApiModel allows you to manipulate the meta data of a model from a simple description or name change to a definition of polymorphism.
At its basic functionality, you can use @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 {...}
Here we change the name of the model from OriginalModel to DifferentModel.
The output would be:
 "DifferentModel": {
      "id": "DifferentModel",
      "description": "Sample model for the documentation",
      .
      .
  }
To support polymorphism and inheritance, we use the discriminator and the subTypes fields. Both must be used for the Swagger output to be valid.
The 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 CatDog and Chicken as sub classes, the animalType field could be used as the discriminator to determine which animal is actually being used.
The 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 {...}
The above snippet is a simple sample of how inheritance can be described. Notice SubModel does not extend SuperModel. In the same way, you can add multiple inheriting classes. There can be any number of inheritance levels.
The output for this would be:
"SuperModel": {
  "id": "SuperModel",
  "required": [
    "foo"
  ],
  "properties": {
    "foo": {
      "type": "string"
    }
  },
  "subTypes": ["SubModel"],
  "discriminator": "foo"
},
"SubModel": {
  "id": "SubModel",
  "properties": {
     ...
  },
}
For further details about this annotation, usage and edge cases, check out the javadocs.

@ApiModelProperty

While swagger-core will introspect fields and setters/getters, it will also read and process JAXB annotations. The @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;
  }
This is a simple example of adding a short description to the model property. It can also be observed that while status is a String, we document it as having only three possible values.
The output of it would be:
  "properties": {
        ...,
        "status": {
          "type": "string",
          "description": "pet status in the store",
          "enum": [
            "available",
            "pending",
            "sold"
          ]
        }
      }
For further details about this annotation, usage and edge cases, check out the javadocs.
Check out usage of these annotations in this article - Spring Boot 2 RESTful API Documentation with Swagger 2 Tutorial

Free Spring Boot Tutorial | Full In-depth Course | Learn Spring Boot in 10 Hours


Watch this course on YouTube at Spring Boot Tutorial | Fee 10 Hours Full Course

Comments