Spring Boot | Using SWAGGER at maximum — All annotations that we should know about in springfox implementation
Tags: springboot, spring, swagger, openapi
Published: 2023-07-15 08:19:15

The main article that bundles all together and redirect to different features that you can implement in swagger UI is present here: https://medium.com/@stefan.paladuta17/spring-boot-using-swagger-at-maximum-9828ae9fb9d0
---
In this article I am going to show the most important annotations I used from the springfox implementation starting on the swagger version2 specifications.

The article will be divided in the following chapters:

- Chapter: @Api annotation
- Chapter: @ApiOperation annotation
- Chapter: @ApiModel annotation
- Chapter: @ApiModelProperty annotation
- Chapter: @ApiIgnore
- Conclusion

---

# Chapter: @Api annotation

If you ever find a tutorial that tells you apply the following snippet of code and everything will work smooth as butter:

```
...
@RestController
@Api( description = "Book controller description | Api Annotation")
public class BookController {
 
   @GetMapping("/books")
   public List<Book> getBooks(){
     return new ArrayList<Book>();
   }
}
```

well wrong. If you follow me and my articles you know that I am a big advocate of creating tutorial materials AND maintaining them up to date as much as possible, as we don’t need more junk on internet but we actually need to filter them and make them better.

So going back to the problem. The lovely description attribute of the annotation @Api used for adding a description has been deprecated. By default, swagger api generates an empty description for the REST API class name.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d1nhteo2vi28s7todj25.png)

Now in present this attribute “description”:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vrmpke6h64i72t9ubtfw.png)

So what is the solution ? Simple, the attribute tags. Example of using the tags attribute:

```
....
@RestController
@Api( tags = "Book controller description | Api Annotation")
public class BookController {
 
   @GetMapping("/books")
   public List<Book> getBooks(){
     return new ArrayList<Book>();
   }
}
```

and the result:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jzz1qsazvkp9i30qqh70.png)


Are there limits and/or tips&tricks you can use ? Well, based on my tests:

Tip&Trick: We can add emojis (:

```
.....
@RestController
@Api( tags = "Secret 📚 endpoints")
public class BookController {
   @GetMapping("/books")
   public List<Book> getBooks(){
      return new ArrayList<Book>();
   }
}
```

Limit: We can’t abuse the number of characters that we write in the tags value, so take care please.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i3l6jy42tdhaszm00216.png)

Tip&Trick: The attribute can actually accept an array of tags (strings) and put the same endpoint in multiple points

Example of the code:

```
package ro.stefan.controller;
import java.util.ArrayList;
import java.util.List;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.annotations.Api;
import ro.stefan.dto.Book;
@RestController
@Api( tags = {"books","store","something else"})
public class BookController {
 
 @GetMapping("/books")
public List<Book> getBooks(){
  return new ArrayList<Book>();
 }
}
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qj1jmelxv62woqp7erku.png)

# Chapter: @ApiOperation annotation

You could further customize the description at an operation level by using @ApiOperation annotation.

```

@RestController
@Api( tags = "Book Store | API annotation")
public class BookController {
 
 @ApiOperation(value = "Recover the collection of all books from the store | API Operation annotation")
 @GetMapping("/books")
 public List<Book> getBooks(){
  return new ArrayList<Book>();
 }
}
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/loq9bxus66fha8cr3yjh.png)

# Chapter: @ApiModel

@ApiModel is an annotation used to enhance the resource model description. We can use @ApiModel for the entire model class.

snippet of some code:

```
import io.swagger.annotations.ApiModel;

@ApiModel(description = "Model retrieved from library system")
public class Book {
  private String title;
  private String author;
  
  public String getTitle() {
    return title;
  }
  public void setTitle(String title) {
    this.title = title;
  }
  
  public String getAuthor() {
    return author;
   }
  public void setAuthor(String author) {
    this.author = author;
  }
}
```

Before:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0wqfkxtaz9wxct3d06vo.png)

After:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r91adu1jr6lmzp45kmka.png)

# Chapter: @ApiModelProperty

@ApiModelProperty like @ApiModel is used enhance the resource model description but in this case for the individual attributes of the model class.

Snippet of some code (also with the @ApiModel annotation from previous chapter):

```
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

@ApiModel(description = "Model retrieved from library system")
public class Book {
  
  @ApiModelProperty(notes = "Title of the book", example = "Inside of this hell")
  private String title;
 
  @ApiModelProperty(notes = "Author of the book", example = "Stefan P.")
  private String author;
  
  public String getTitle() {
    return title;
  }
  public void setTitle(String title) {
    this.title = title;
  }
  public String getAuthor() {
    return author;
  }
  public void setAuthor(String author) {
    this.author = author;
  }
}
```

Before:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ouqpxbq18er78x4rv0s4.png)

After (also with the @ApiModel annotation from previous chapter):
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9zklnbpvjdj83g6hmav7.png)

# Chapter: @ApiIgnore

Let’s say that you have a project and like every new project when you build it you construct an endpoint that must act as test, to see if the base code is working if the C.I./C.D. is fine etc. Over the years I found a lot of endpoints made with this reason that remained until deploy in production. Honestly (in present with my current experience) I think they are very good to have.
An example of what I currently use is an endpoint called /ping that displays the up time of the microservices, the libraries used inside and their versions.

For this example I use the following controller:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/idprtfhy8wk0f65makjm.png)

```
import java.util.ArrayList;
import java.util.List;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import ro.stefan.dto.Book;
import springfox.documentation.annotations.ApiIgnore;

@RestController
@Api( tags = "Book Store | API annotation")
public class BookController {
 
  @ApiOperation(value = "Recover the collection of all books from the store | API Operation annotation.")
  @GetMapping("/books")
  public List<Book> getBooks(){
    return new ArrayList<Book>();
  }
 
  @ApiIgnore 
  @GetMapping("/ping")
  public String ping() {
    return "pong";
  }
}
```

with a simple method /ping that just returns a pong string. So after applying (uncomment) the code we can see that the interface swagger-ui displays nothing regarding /ping

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2g4rtyfj4mp35893pgx0.png)

but if we call the endpoint:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vkuspe4dnxd88n93s7qk.png)

it exists so this is a success we as developers know a secret endpoint ;). And nobody that is consuming our contract (reading the swagger-ui) will know (normally speaking).


---
**Conclusion**: There are many other annotations offered by Spring but in reality this are the ones that I want to focus on because they are the most common ones you will ever see in projects if not more than you will ever see for version 2 of the swagger specifications. The next step is not to learn more annotations on this example/series but to move to the next version (v3 focused on OpenAPI object).

If you want my code you can find it here: https://github.com/Kanames/SpringBoot-SwaggerExamples

If you liked the article please take a minute to offer me a clap 👏 or even buy me a coffee https://www.buymeacoffee.com/stefansplace (;

My original article: https://medium.com/@stefan.paladuta17/spring-boot-using-swagger-at-maximum-all-annotations-that-we-should-know-about-in-springfox-e419e575b078