DEV Community

Cover image for OpenApi - Java Annotation for Better Api Documentation
Spencer Forrest for opt-nc

Posted on

OpenApi - Java Annotation for Better Api Documentation

What is OpenAPI ?

Definition:

standard[] on how APIs are described [...] focused on creating, evolving and promoting a vendor neutral description format. The OpenAPI Specification was originally based on the Swagger Specification, donated by SmartBear Software.

OpenApis.org

OpenApi and Swagger UI

OpenApi can be used to document a web api and Swagger-ui to display it in a user friendly way. The combination of both tools make it possible to play with the documented API to try it out and have a better understanding of what it does and how to use it.

1. The documentation displays what resources the API provides:

  • JSON objects to expect
  • Structure of those JSON objects
  • Http Methods to expect

2. The documentation displays how to access them:

  • Http Methods to use
  • Paths to use
  • What query parameters to use
  • What JSON objects to send if any
  • Structure of those JSON objects

There are screenshots below of such documentation using Swagger UI on a Java Spring Boot project dedicated to retrieve data from https://www.domaine.nc via a HTTP API.

For more information about domaine.nc: See its Dev.to serie

Full Documentation

Get a domaines .SVG expiration badge

Those pieces of information are essential for the understanding and good use of the HTTP API.

Unknown need

An open source project dedicated to memes, imgflip-api, is documented in part thanks to Swagger UI.

Adriens & Ronny.S – the two contributors of this project

wanted to have a custom and richer API than the official one [...] with Swagger documentation

– Source: readme.md

See screenshots below of this project documentation:

Full documentation

Top memes of the last 30 days

As highlighted on the pictures, this documentation is richer and, thus, more precise than the previous example.

The details added compared to the previous example are:

  • Textual description of the API
  • Textual description of the resources provided by the API
  • Textual description of the request parameters accepted by the API:
    • Path
    • Query

Those details might seem a bit unnecessary if the API ressources, request parameters and response bodies are named well enough to communicate the API's intent. However, "the devil is in the details".

In the first example, it seems like there was enough information to infer the intent of each resource put at our disposal until we look at the "badge" resource.

Get a domaines .SVG expiration badge

The intent of this resource is not precise. It provides a badge in a .svg format but does not give any information about the badge itself.

There are two plausible solutions to this issue:

  1. Rename the resource from "badge.svg" to "expiration-date-and-status-badge.svg"
  2. Add a concise description to the resource (see screenshots below)

Description of the .SVG expiration badge request

Java Annotation for Better Documentation

There is below a snippet from imgflip-api - PublishedMemesController.java:

@RestController
@Tag(name = "Published memes", description = "Published memes related resources")
@RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE)
public class PublishedMemesController {

    ...

    @GetMapping("/top/{stream}/last/30d")
    @Operation(summary = "Get the top memes since last 30 days for a stream",
            description = "Top meme's list (page) since 30 last days for a stream and given page number.")
    public List<PublishedMeme> getTop30d(
            @Parameter(description = "Stream name", example = "gaming") @PathVariable String stream,
            @Parameter(description = "Page number") @RequestParam(value="page", defaultValue = "1") int page) throws IOException{
        return publishedMemesService.getTopThirtyDayPageOfHotStream(stream, page);
    }

    ...

}
Enter fullscreen mode Exit fullscreen mode

The java annotation for describing grouped resources is:

@Tag(name = "Published memes", 
     description = "Published memes related resources")
Enter fullscreen mode Exit fullscreen mode

Full documentation

The java annotation used for describing a resource is:

@Operation(summary = "Get the top memes since last 30 days for a stream",
           description = "Top meme's list (page) since 30 last days for a stream and given page number.")
Enter fullscreen mode Exit fullscreen mode

The java annotation used for describing request paths and queries is:

@Parameter(description = "Stream name", example = "gaming")
...
@Parameter(description = "Page number")
Enter fullscreen mode Exit fullscreen mode

Top memes of the last 30 days

There are also annotations to describe the potential responses a user can receive.

There is below a snippet for domaine-nc-api with the controller responsible to provide a badge.svg:


    @Operation(summary = "Get the svg badge of the specified domain with expiration date and lastUpdate color.",
               description = "Color scheme is: "
                             + "<ul><li>green: domain is valid</li>"
                             + "<li>red: domain is expired</li>"
                             + "<li>yellow: domain is about to expire</li></ul>")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200",
                         description = "Retrieve the badge.svg thanks to the redirect",
                         content = @Content(mediaType = "image/svg+xml")),
            @ApiResponse(responseCode = "303",
                         description = "Redirect to https://img.shields.io/badge/{domaine-name}-{expiration-date}-{color}",
                         content = @Content(mediaType = "image/svg+xml")),
            @ApiResponse(responseCode = "400",
                         description = "Bad request. Invalid extension",
                         content = @Content(mediaType = MediaType.ALL_VALUE)),
            @ApiResponse(responseCode = "404",
                         description = "Domaine not found",
                         content = @Content(mediaType = MediaType.ALL_VALUE))
    })
    @GetMapping(value = "/{name}/{extension}/badge.svg")
    public ResponseEntity<Object> redirectToExternalUrl(
            @Parameter(description = "domain name") @PathVariable(value = "name") String name,
            @Parameter(description = "domain extension") @PathVariable(value = "extension") String extension) { ... }

Enter fullscreen mode Exit fullscreen mode

This is the corresponding documentation:

Description of the .SVG expiration badge

The annotations below have already been introduced:

@Operation(summary = "Get the svg badge of the specified domain with expiration date and lastUpdate color.",
           description = "Color scheme is: "
                         + "<ul><li>green: domain is valid</li>"
                         + "<li>red: domain is expired</li>"
                         + "<li>yellow: domain is about to expire</li></ul>")

...

@Parameter(description = "domain name")
@Parameter(description = "domain extension")

Enter fullscreen mode Exit fullscreen mode

This is the documentation produced by using them:

Description of the .SVG expiration badge request

The annotations used to describe the potential responses are the following:


@ApiResponses(value = {
        @ApiResponse(responseCode = "200",
                     description = "Retrieve the badge.svg thanks to the redirect",
                     content = @Content(mediaType = "image/svg+xml")),
        @ApiResponse(responseCode = "303",
                     description = "Redirect to https://img.shields.io/badge/{domaine-name}-{expiration-date}-{color}",
                     content = @Content(mediaType = "image/svg+xml")),
        @ApiResponse(responseCode = "400",
                     description = "Bad request. Invalid extension",
                     content = @Content(mediaType = MediaType.ALL_VALUE)),
        @ApiResponse(responseCode = "404",
                     description = "Domaine not found",
                     content = @Content(mediaType = MediaType.ALL_VALUE))
})
Enter fullscreen mode Exit fullscreen mode

This is the documentation produce with Swagger UI:

Description of the .SVG expiration badge responses

Thanks to this documentation, the user knows what errors it might receive and the corresponding issues he needs to solve.

The documentation also shows the "happy path" to retrieve the badge.svg and, in this particular example, the intermediary step to get one: the use of a third party HTTP API through a HTTP 303 See Other redirection – shield.io.

💰 Day to Day Impact

Developers who care about the documentation of their HTTP API will use those annotations for the Spring Boot projects they are in charge of. Those annotations will help them to write concise and precise descriptions of their API.

They are short and easy to use which helps developers to document their code in an effective and efficient way.

By using those annotations developers will reap the benefits of a well documented API:

  • Less time spent to answer clients' questions such as:
    • What does this API do ?
    • How to use this API ?
    • What response is it supposed to send ?
    • What does the body response (JSON object) represent ?
  • Less frustrated clients
  • More clients
  • More happy clients ❤️

Happy Documenting !

Top comments (5)

Collapse
 
adriens profile image
adriens

You have been quoted @hakumennc 😎

Collapse
 
adriens profile image
adriens

Great job @spencer_forrest_opt : this is a very useful content that makes our APIs even better

Collapse
 
adriens profile image
adriens
Collapse
 
adriens profile image
adriens
Collapse
 
tammynoel profile image
TammyNoel

Which annotation is used in class to describe our API in Swagger ? دعاء قوي لجلب الحبيب