DEV Community

Cover image for Spring Boot | Using SWAGGER at maximum — All annotations that we should know about in springfox implementation
Paladuta Stefan
Paladuta Stefan

Posted on

Spring Boot | Using SWAGGER at maximum — All annotations that we should know about in springfox implementation

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>();
   }
}
Enter fullscreen mode Exit fullscreen mode

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

Now in present this attribute “description”:

Image description

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>();
   }
}
Enter fullscreen mode Exit fullscreen mode

and the result:

Image description

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>();
   }
}
Enter fullscreen mode Exit fullscreen mode

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

Image description

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>();
 }
}
Enter fullscreen mode Exit fullscreen mode

Image description

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>();
 }
}
Enter fullscreen mode Exit fullscreen mode

Image description

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;
  }
}
Enter fullscreen mode Exit fullscreen mode

Before:
Image description

After:
Image description

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;
  }
}
Enter fullscreen mode Exit fullscreen mode

Before:
Image description

After (also with the @ApiModel annotation from previous chapter):
Image description

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

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";
  }
}
Enter fullscreen mode Exit fullscreen mode

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

but if we call the endpoint:

Image description

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

Top comments (0)