Enterprise Java

Spring Boot REST Docs Example

Spring Boot REST APIs are commonly documented using tools such as Swagger/OpenAPI. Another useful option is Spring REST Docs, which generates API documentation from tests. In this article, we will create a simple Spring Boot REST API and use Spring REST Docs to document it. The example uses a small Product API so that the focus remains on understanding REST Docs rather than introducing unnecessary complexity.

1. Introduction

API documentation is an important part of building and maintaining REST APIs because it helps developers understand how an API works and how to consume it correctly. Good documentation typically explains the available endpoints, HTTP methods, request parameters, request and response fields, HTTP status codes, and example requests and responses. Spring REST Docs takes a slightly different approach from tools that generate documentation directly from annotations. With Spring REST Docs, you write tests for your REST endpoints and document the request and response as part of those tests. The generated snippets can then be combined into a larger documentation page. In simple terms, the flow is: REST Controller → Spring Boot API → MockMvc Test → Spring REST Docs → Generated Documentation. The main advantage of this approach is that the documentation is tied to automated tests. If the API response changes and the documented fields are no longer correct, the test can fail instead of allowing outdated documentation to remain unnoticed. This helps keep the API documentation aligned with the actual behavior of the application.

1.1 Understanding REST Docs

Spring REST Docs generates small documentation fragments called snippets. A test can generate snippets for HTTP requests, HTTP responses, request fields, response fields, query parameters, path parameters, request headers, and response headers. These snippets are usually generated as AsciiDoc files and can then be combined to create a complete API documentation page. This approach separates the API documentation content from the application code while still keeping it connected to the tests. Developers can therefore create readable API guides without adding documentation annotations throughout the REST controllers.

1.2 Why Use REST Docs?

Spring REST Docs is useful when you want API documentation to be validated along with the application tests. Since the documentation is generated from actual API tests, it can help reduce the risk of documenting fields or behavior that the API no longer supports. It also keeps the REST controller free from additional documentation annotations and allows the generated snippets to be organized into a readable API guide.

1.3 REST Docs vs Swagger/OpenAPI

Both Spring REST Docs and Swagger/OpenAPI are useful for documenting REST APIs, but they follow different approaches. Spring REST Docs focuses on generating documentation from tests, while Swagger/OpenAPI focuses on defining and describing the API specification. The choice depends on whether the primary requirement is test-verified documentation, an API specification, interactive API exploration, or a combination of these.

Spring REST DocsSwagger/OpenAPI
Documentation is generated from testsDocumentation is commonly generated from API definitions or annotations
Helps verify documentation through testsProvides a machine-readable API specification
Good for creating readable API guidesGood for interactive API exploration and API tooling
Commonly generates AsciiDoc snippetsCommonly uses OpenAPI/Swagger formats

2. Spring REST Docs Example

2.1 Add Maven Dependencies

The following Maven configuration adds Spring Web for creating REST endpoints, Spring Boot Test and MockMvc for testing, and Spring REST Docs for generating API documentation from those tests.

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.restdocs</groupId>
        <artifactId>spring-restdocs-mockmvc</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

The spring-boot-starter-web dependency provides the components required to create REST APIs, while spring-boot-starter-test provides the testing support required by the application. The spring-restdocs-mockmvc dependency integrates Spring REST Docs with MockMvc so that API documentation snippets can be generated when the controller tests are executed.

2.2 Create the Product Model

Next, create a simple Product model to represent the data returned by the REST API. For this example, the model contains only an ID, name, and price.

package com.example.demo.product;

public record Product(Long id, String name, double price) { }

The Product is defined as a Java record, which provides a concise way to create an immutable data object. It contains three fields: id identifies the product, name stores the product name, and price stores its price. Spring Boot automatically serializes this object into JSON when it is returned from a REST controller.

2.3 Create the REST Controller

Next, create a REST controller with a simple GET endpoint that accepts a product ID and returns the corresponding product. For this example, the controller returns a fixed product so that we can focus on Spring REST Docs without adding database or service-layer code.

package com.example.demo.product;

import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/products")
public class ProductController {

    @GetMapping("/{id}")
    public Product getProduct(@PathVariable Long id) {
        return new Product(id, "Laptop", 75000.0);
    }
}

The @RestController annotation marks the class as a REST controller, while @RequestMapping("/products") defines the base URL for the endpoints. The @GetMapping("/{id}") annotation maps HTTP GET requests to the getProduct() method, and @PathVariable reads the product ID from the URL. For example, a request to GET /products/1 returns a Product object with ID 1, which Spring Boot automatically converts into a JSON response.

2.4 Create the REST Docs Test

Now create a test for the controller using MockMvc. The test will call the REST endpoint, verify the HTTP response, and generate documentation snippets for the path parameter and response fields.

package com.example.demo.product;

import org.junit.jupiter.api.Test;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders;

import org.springframework.test.web.servlet.MockMvc;

import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.payload.PayloadDocumentation.*;
import static org.springframework.restdocs.request.RequestDocumentation.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@WebMvcTest(ProductController.class)
public class ProductControllerTest {

  @Autowired
  private MockMvc mockMvc;

  @Test
  void shouldGetProduct() throws Exception {
    mockMvc.perform(RestDocumentationRequestBuilders.get("/products/{id}", 1))
      .andExpect(status().isOk())
      .andDo(
        document(
          "get-product",
          pathParameters(parameterWithName("id").description("The product ID")),
          responseFields(
            fieldWithPath("id").description("The product ID"),
            fieldWithPath("name").description("The product name"),
            fieldWithPath("price").description("The product price"))
        )
      );
  }
}

The @WebMvcTest annotation loads the web layer and focuses the test on ProductController. MockMvc sends a simulated GET request to /products/1 without starting a real web server, while andExpect(status().isOk()) verifies that the endpoint returns HTTP 200. The document() method generates a REST Docs snippet named get-product. The pathParameters() section documents the id path parameter, while responseFields() describes the id, name, and price fields returned in the JSON response.

2.5 Configure the Maven Plugin

To generate a complete HTML documentation page from the REST Docs snippets, we can use the Asciidoctor Maven plugin. Add the following configuration to the pom.xml file:

<build>
    <plugins>

        <plugin>
            <groupId>org.asciidoctor</groupId>
            <artifactId>asciidoctor-maven-plugin</artifactId>
            <version>2.2.6</version>

            <executions>
                <execution>
                    <id>generate-docs</id>
                    <phase>prepare-package</phase>

                    <goals>
                        <goal>process-asciidoc</goal>
                    </goals>

                    <configuration>
                        <backend>html</backend>
                        <doctype>book</doctype>
                    </configuration>
                </execution>
            </executions>
        </plugin>

    </plugins>
</build>

The asciidoctor-maven-plugin processes the AsciiDoc source and converts it into HTML. The prepare-package phase ensures that the documentation is generated as part of the Maven build, while the html backend specifies that the output should be an HTML document.

2.6 Create the API Documentation

Next, create the src/docs/asciidoc/index.adoc file. This file acts as the main documentation page and includes the REST Docs snippets generated by the controller test.

= Product API

== Get Product

Get a product using its ID.

=== Request

include::{snippets}/get-product/http-request.adoc[]

=== Path Parameters

include::{snippets}/get-product/path-parameters.adoc[]

=== Response

include::{snippets}/get-product/http-response.adoc[]

=== Response Fields

include::{snippets}/get-product/response-fields.adoc[]

The include statements insert the corresponding snippets generated by the test into the final documentation. For example, http-request.adoc contains the HTTP request, while path-parameters.adoc and response-fields.adoc contain the documented parameters and response fields.

2.7 Generate the Documentation

Once the controller test and REST Docs configuration are in place, run the Maven test command to execute the test and generate the REST Docs snippets.

mvn clean test

If the test passes, REST Docs generates the documentation snippets under target/generated-snippets/get-product/. You should see files such as http-request.adoc, http-response.adoc, path-parameters.adoc, and response-fields.adoc.

For example, the generated documentation can contain a request similar to the following:

GET /products/1 HTTP/1.1
Host: localhost:8080

The generated response documentation will describe the HTTP status and JSON response returned by the API:

HTTP/1.1 200 OK
Content-Type: application/json

{
  "id": 1,
  "name": "Laptop",
  "price": 75000.0
}

The path-parameters.adoc snippet documents the id parameter, while response-fields.adoc documents the id, name, and price fields. These generated snippets are then used by the Asciidoctor configuration to build the complete API documentation.

To generate the complete HTML documentation, run the Maven package command:

mvn package

During the build, Asciidoctor processes the index.adoc file and includes the generated REST Docs snippets. The resulting HTML documentation can then be found under the Maven build output directory, typically target/generated-docs/.

3. Conclusion

Spring REST Docs provides a practical way to create REST API documentation directly from automated tests. In this example, we created a simple Spring Boot REST API, tested it using MockMvc, documented the request parameters and response fields, and generated reusable documentation snippets from the test. The main benefit of this approach is that the documentation is connected to the API tests. When the API structure changes, the documentation test can also detect mismatches, helping reduce the risk of outdated API documentation. Spring REST Docs is therefore a good choice when you want readable API documentation that is verified as part of your test suite, without adding documentation annotations throughout your REST controllers.

Yatin Batra

An experience full-stack engineer well versed with Core Java, Spring/Springboot, MVC, Security, AOP, Frontend (Angular & React), and cloud technologies (such as AWS, GCP, Jenkins, Docker, K8).
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Back to top button