Creating a REST API using Spring Boot + Tests + Documentation [part 05]
Tags: webdev, java, swagger, documentation
Published: 2023-02-01 18:16:34

Hello!

I'm back in this tutorial to teach you how to develop a REST API using Spring Boot. As I said earlier, this tutorial is divided into 5 parts as shown in the following table:


|   **Part**  |        **Content**        |
|:-----------:|:-------------------------:|
|   Part 01   |    [Application Startup](https://dev.to/franciscotis/creating-a-rest-api-using-spring-boot-tests-documentation-part-01-2262)    |
|   Part 02   |   [Settings and Database](https://dev.to/franciscotis/creating-a-rest-api-using-spring-boot-tests-documentation-part-02-1a4i)   |
|   Part 03   |     [API Implementation](https://dev.to/franciscotis/creating-a-rest-api-using-spring-boot-tests-documentation-part-03-1m5e)    |
|   Part 04   |      [Tests + Coverage](https://dev.to/franciscotis/creating-a-rest-api-using-spring-boot-tests-documentation-part-04-4190)     |
| **Part 05** | **Swagger Documentation** |

It is expected that from this final part you will learn the following:

- Use of Swagger for project documentation.


Remembering that in this tutorial the following tools are used:

- JDK 17
- IntelliJ
- Insomnia
- Maven
- MySQL database


---

We arrived at our last part of the tutorial. In the [previous part](https://dev.to/franciscotis/creating-a-rest-api-using-spring-boot-tests-documentation-part-04-4190) you learned how to do unit and integration tests. In addition to also checking the coverage of tests performed.

In this last part, which will be a little shorter, you'll learn how to document your API.

When we work with an API we have to keep in mind that other developers will want access to it. Not necessarily to your source code, but to the responses from requests.

Therefore, we need to create documentation that will visually present all possible access routes of our system and their responses.

---

## **Step 01 - Added the SpringDoc library**

We will be using [Swagger](https://swagger.io) which is already well known for documenting APIs 

To use it within our application, we will have to add the [Spring Doc](https://springdoc.org) dependency within the `pom.xml` file:

```

<dependency>
   <groupId>org.springdoc</groupId>
   <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
   <version>2.0.2</version>
</dependency>

```

By doing this (and restarting your server), we can access the URL http://localhost:8080/swagger-ui/index.html and the following screen will be seen:


![Swagger initial screen](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cjttgved09bs44byms32.png)

As you can see, Swagger already mapped all the routes we created in the system, but it didn't complete all the necessary information for a good documentation. For example, clicking to see more information about the following route:

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

It only shows that the response will be a String, instead of showing the actual content. Therefore, we will have to make the following modification to our controller:

```

package com.simplelibrary.simplelibraryAPI.controller;

import com.simplelibrary.simplelibraryAPI.dto.BookRequestDTO;
import com.simplelibrary.simplelibraryAPI.dto.BookResponseDTO;
import com.simplelibrary.simplelibraryAPI.model.Book;
import com.simplelibrary.simplelibraryAPI.service.BookService;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.util.UriComponentsBuilder;

import java.io.IOException;

@RestController
@RequestMapping("books")
public class BookController {

@Autowired
private BookService bookService;


@ApiResponse(
            content = { @Content(mediaType = "application/json", array = @ArraySchema(schema = @Schema(implementation = BookResponseDTO.class)))})
@GetMapping
public ResponseEntity<Page<BookResponseDTO>> getAllBooks(@PageableDefault(size=10, sort={"title"}) Pageable pagination) throws IOException {
    var page = bookService.getAllBooks(pagination);
    return ResponseEntity.ok(page);
}

    @ApiResponse(
            content = { @Content(mediaType = "application/json", schema = @Schema(implementation = BookResponseDTO.class))})

@GetMapping("/{id}")
public ResponseEntity show(@PathVariable Long id){
    var book = bookService.show(id);
    return ResponseEntity.ok(book);
}


@ApiResponse(
            content = { @Content(mediaType = "application/json", schema = @Schema(implementation = Book.class))})
@PostMapping
    public ResponseEntity store(@RequestBody @Valid BookRequestDTO bookRequest, UriComponentsBuilder uriBuilder) throws IOException {
        var book = bookService.store(bookRequest);
        var uri = uriBuilder.path("/books/{id}").buildAndExpand(book.getId()).toUri();
        return ResponseEntity.created(uri).body(book);
    }

@ApiResponse(
            content = { @Content(mediaType = "application/json", schema = @Schema(implementation = Book.class))})
@PutMapping("/{id}")
    public ResponseEntity update(@PathVariable Long id, @RequestBody @Valid BookRequestDTO bookRequest){
    var book = bookService.update(id, bookRequest);
    return ResponseEntity.ok(book);

}

@DeleteMapping("/{id}")
    public ResponseEntity delete(@PathVariable Long id){
    bookService.delete(id);
    return ResponseEntity.noContent().build();
}




}


```

Note that the `@ApiResponse` annotation has been added. Inside it, we put what will be the response content of each route. So, when checking the same route:

![Updated route description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/otmjmjtcfhj3nwh6gdvx.png)

You can, if you want, create requests from this screen by clicking on the _Try it out_ button:

![Request](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zd6rkiv6ycxosq91jrge.png)


![Response](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ptl1of778eaonfen6q0n.png)

---
## **What we learned in this tutorial**

Well folks, I hope you enjoyed this sequel of the Spring Boot tutorial. I believe that with the knowledge gained from these 5 parts, you can start moving towards creating more robust applications.

Don't stick to just what was taught in this tutorial, be free to modify any piece of code that was added here. Any questions you can contact me! 

Remembering once again, the complete project you can find [HERE](https://github.com/franciscotis/simple-library-api)