Getting started
This section describes how to get started with Spring REST Docs.
Sample Applications
If you want to jump straight in, a number of sample applications are available.
Requirements
Spring REST Docs has the following minimum requirements:
-
Java 17
-
Spring Framework 6
Additionally, the spring-restdocs-restassured
module requires REST Assured 5.2.
Build configuration
The first step in using Spring REST Docs is to configure your project’s build.
The Spring HATEOAS and Spring Data REST samples contain a build.gradle
and pom.xml
, respectively, that you may wish to use as a reference.
The key parts of the configuration are described in the following listings:
<dependency> (1)
<groupId>org.springframework.restdocs</groupId>
<artifactId>spring-restdocs-mockmvc</artifactId>
<version>{project-version}</version>
<scope>test</scope>
</dependency>
<build>
<plugins>
<plugin> (2)
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctor-maven-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<id>generate-docs</id>
<phase>prepare-package</phase> (3)
<goals>
<goal>process-asciidoc</goal>
</goals>
<configuration>
<backend>html</backend>
<doctype>book</doctype>
</configuration>
</execution>
</executions>
<dependencies>
<dependency> (4)
<groupId>org.springframework.restdocs</groupId>
<artifactId>spring-restdocs-asciidoctor</artifactId>
<version>{project-version}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
1 | Add a dependency on spring-restdocs-mockmvc in the test scope.
If you want to use WebTestClient or REST Assured rather than MockMvc, add a dependency on spring-restdocs-webtestclient or spring-restdocs-restassured respectively instead. |
2 | Add the Asciidoctor plugin. |
3 | Using prepare-package allows the documentation to be included in the package. |
4 | Add spring-restdocs-asciidoctor as a dependency of the Asciidoctor plugin.
This will automatically configure the snippets attribute for use in your .adoc files to point to target/generated-snippets .
It will also allow you to use the operation block macro. |
plugins { (1)
id "org.asciidoctor.jvm.convert" version "3.3.2"
}
configurations {
asciidoctorExt (2)
}
dependencies {
asciidoctorExt 'org.springframework.restdocs:spring-restdocs-asciidoctor:{project-version}' (3)
testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc:{project-version}' (4)
}
ext { (5)
snippetsDir = file('build/generated-snippets')
}
test { (6)
outputs.dir snippetsDir
}
asciidoctor { (7)
inputs.dir snippetsDir (8)
configurations 'asciidoctorExt' (9)
dependsOn test (10)
}
1 | Apply the Asciidoctor plugin. |
2 | Declare the asciidoctorExt configuration for dependencies that extend Asciidoctor. |
3 | Add a dependency on spring-restdocs-asciidoctor in the asciidoctorExt configuration.
This will automatically configure the snippets attribute for use in your .adoc files to point to build/generated-snippets .
It will also allow you to use the operation block macro. |
4 | Add a dependency on spring-restdocs-mockmvc in the testImplementation configuration.
If you want to use WebTestClient or REST Assured rather than MockMvc, add a dependency on spring-restdocs-webtestclient or spring-restdocs-restassured respectively instead. |
5 | Configure a snippetsDir property that defines the output location for generated snippets. |
6 | Make Gradle aware that running the test task will write output to the snippetsDir. This is required for incremental builds. |
7 | Configure the asciidoctor task. |
8 | Make Gradle aware that running the task will read input from the snippetsDir. This is required for incremental builds. |
9 | Configure the use of the asciidoctorExt configuration for extensions. |
10 | Make the task depend on the test task so that the tests are run before the documentation is created. |
Packaging the Documentation
You may want to package the generated documentation in your project’s jar file — for example, to have it served as static content by Spring Boot. To do so, configure your project’s build so that:
-
The documentation is generated before the jar is built
-
The generated documentation is included in the jar
The following listings show how to do so in both Maven and Gradle:
<plugin> (1)
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctor-maven-plugin</artifactId>
<!-- … -->
</plugin>
<plugin> (2)
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy-resources</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration> (3)
<outputDirectory>
${project.build.outputDirectory}/static/docs
</outputDirectory>
<resources>
<resource>
<directory>
${project.build.directory}/generated-docs
</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
1 | The existing declaration for the Asciidoctor plugin. |
2 | The resource plugin must be declared after the Asciidoctor plugin as they are bound to the same phase (prepare-package ) and the resource plugin must run after the Asciidoctor plugin to ensure that the documentation is generated before it’s copied.
If you are not using Spring Boot and its plugin management, declare the plugin with an appropriate <version> . |
3 | Copy the generated documentation into the build output’s static/docs directory, from where it will be included in the jar file. |
bootJar {
dependsOn asciidoctor (1)
from ("${asciidoctor.outputDir}/html5") { (2)
into 'static/docs'
}
}
1 | Ensure that the documentation has been generated before the jar is built. |
2 | Copy the generated documentation into the jar’s static/docs directory. |
Generating Documentation Snippets
Spring REST Docs uses Spring MVC’s test framework, Spring WebFlux’s WebTestClient
, or REST Assured to make requests to the service that you are documenting.
It then produces documentation snippets for the request and the resulting response.
Setting up Your Tests
Exactly how you set up your tests depends on the test framework that you use. Spring REST Docs provides first-class support for JUnit 5 and JUnit 4. JUnit 5 is recommended. Other frameworks, such as TestNG, are also supported, although slightly more setup is required.
Setting up Your JUnit 5 Tests
When using JUnit 5, the first step in generating documentation snippets is to apply the RestDocumentationExtension
to your test class.
The following example shows how to do so:
@ExtendWith(RestDocumentationExtension.class)
public class JUnit5ExampleTests {
When testing a typical Spring application, you should also apply the SpringExtension
:
@ExtendWith({RestDocumentationExtension.class, SpringExtension.class})
public class JUnit5ExampleTests {
The RestDocumentationExtension
is automatically configured with an output directory based on your project’s build tool:
Build tool | Output directory |
---|---|
Maven |
|
Gradle |
|
If you are using JUnit 5.1, you can override the default by registering the extension as a field in your test class and providing an output directory when creating it. The following example shows how to do so:
public class JUnit5ExampleTests {
@RegisterExtension
final RestDocumentationExtension restDocumentation = new RestDocumentationExtension ("custom");
}
Next, you must provide a @BeforeEach
method to configure MockMvc or WebTestClient, or REST Assured.
The following listings show how to do so:
private MockMvc mockMvc;
@BeforeEach
void setUp(WebApplicationContext webApplicationContext, RestDocumentationContextProvider restDocumentation) {
this.mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
.apply(documentationConfiguration(restDocumentation)) (1)
.build();
}
1 | The MockMvc instance is configured by using a MockMvcRestDocumentationConfigurer .
You can obtain an instance of this class from the static documentationConfiguration() method on org.springframework.restdocs.mockmvc.MockMvcRestDocumentation . |
private WebTestClient webTestClient;
@BeforeEach
void setUp(ApplicationContext applicationContext, RestDocumentationContextProvider restDocumentation) {
this.webTestClient = WebTestClient.bindToApplicationContext(applicationContext)
.configureClient()
.filter(documentationConfiguration(restDocumentation)) (1)
.build();
}
1 | The WebTestClient instance is configured by adding a WebTestClientRestDocumentationConfigurer as an ExchangeFilterFunction .
You can obtain an instance of this class from the static documentationConfiguration() method on org.springframework.restdocs.webtestclient.WebTestClientRestDocumentation . |
private RequestSpecification spec;
@BeforeEach
void setUp(RestDocumentationContextProvider restDocumentation) {
this.spec = new RequestSpecBuilder().addFilter(documentationConfiguration(restDocumentation)) (1)
.build();
}
1 | REST Assured is configured by adding a RestAssuredRestDocumentationConfigurer as a Filter .
You can obtain an instance of this class from the static documentationConfiguration() method on RestAssuredRestDocumentation in the org.springframework.restdocs.restassured package. |
The configurer applies sensible defaults and also provides an API for customizing the configuration. See the configuration section for more information.
Setting up Your JUnit 4 Tests
When using JUnit 4, the first step in generating documentation snippets is to declare a public
JUnitRestDocumentation
field that is annotated as a JUnit @Rule
.
The following example shows how to do so:
@Rule
public JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation();
By default, the JUnitRestDocumentation
rule is automatically configured with an output directory based on your project’s build tool:
Build tool | Output directory |
---|---|
Maven |
|
Gradle |
|
You can override the default by providing an output directory when you create the JUnitRestDocumentation
instance.
The following example shows how to do so:
@Rule
public JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation("custom");
Next, you must provide an @Before
method to configure MockMvc or WebTestClient, or REST Assured.
The following examples show how to do so:
private MockMvc mockMvc;
@Autowired
private WebApplicationContext context;
@Before
public void setUp() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
.apply(documentationConfiguration(this.restDocumentation)) (1)
.build();
}
1 | The MockMvc instance is configured by using a MockMvcRestDocumentationConfigurer .
You can obtain an instance of this class from the static documentationConfiguration() method on org.springframework.restdocs.mockmvc.MockMvcRestDocumentation . |
private WebTestClient webTestClient;
@Autowired
private ApplicationContext context;
@Before
public void setUp() {
this.webTestClient = WebTestClient.bindToApplicationContext(this.context)
.configureClient()
.filter(documentationConfiguration(this.restDocumentation)) (1)
.build();
}
1 | The WebTestClient instance is configured by adding a WebTestclientRestDocumentationConfigurer as an ExchangeFilterFunction .
You can obtain an instance of this class from the static documentationConfiguration() method on org.springframework.restdocs.webtestclient.WebTestClientRestDocumentation . |
private RequestSpecification spec;
@Before
public void setUp() {
this.spec = new RequestSpecBuilder().addFilter(documentationConfiguration(this.restDocumentation)) (1)
.build();
}
1 | REST Assured is configured by adding a RestAssuredRestDocumentationConfigurer as a Filter .
You can obtain an instance of this class from the static documentationConfiguration() method on RestAssuredRestDocumentation in the org.springframework.restdocs.restassured package. |
The configurer applies sensible defaults and also provides an API for customizing the configuration. See the configuration section for more information.
Setting up your tests without JUnit
The configuration when JUnit is not being used is largely similar to when it is being used. This section describes the key differences. The TestNG sample also illustrates the approach.
The first difference is that you should use ManualRestDocumentation
in place of JUnitRestDocumentation
.
Also, you do not need the @Rule
annotation.
The following example shows how to use ManualRestDocumentation
:
private ManualRestDocumentation restDocumentation = new ManualRestDocumentation();
Secondly, you must call ManualRestDocumentation.beforeTest(Class, String)
before each test.
You can do so as part of the method that configures MockMvc, WebTestClient, or REST Assured.
The following examples show how to do so:
private MockMvc mockMvc;
@Autowired
private WebApplicationContext context;
@BeforeMethod
public void setUp(Method method) {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
.apply(documentationConfiguration(this.restDocumentation))
.build();
this.restDocumentation.beforeTest(getClass(), method.getName());
}
private WebTestClient webTestClient;
@Autowired
private ApplicationContext context;
@BeforeMethod
public void setUp(Method method) {
this.webTestClient = WebTestClient.bindToApplicationContext(this.context)
.configureClient()
.filter(documentationConfiguration(this.restDocumentation)) (1)
.build();
this.restDocumentation.beforeTest(getClass(), method.getName());
}
private RequestSpecification spec;
@BeforeMethod
public void setUp(Method method) {
this.spec = new RequestSpecBuilder().addFilter(documentationConfiguration(this.restDocumentation)).build();
this.restDocumentation.beforeTest(getClass(), method.getName());
}
Finally, you must call ManualRestDocumentation.afterTest
after each test.
The following example shows how to do so with TestNG:
@AfterMethod
public void tearDown() {
this.restDocumentation.afterTest();
}
Invoking the RESTful Service
Now that you have configured the testing framework, you can use it to invoke the RESTful service and document the request and response. The following examples show how to do so:
this.mockMvc.perform(get("/").accept(MediaType.APPLICATION_JSON)) (1)
.andExpect(status().isOk()) (2)
.andDo(document("index")); (3)
1 | Invoke the root (/ ) of the service and indicate that an application/json response is required. |
2 | Assert that the service produced the expected response. |
3 | Document the call to the service, writing the snippets into a directory named index (which is located beneath the configured output directory).
The snippets are written by a RestDocumentationResultHandler .
You can obtain an instance of this class from the static document method on org.springframework.restdocs.mockmvc.MockMvcRestDocumentation . |
this.webTestClient.get()
.uri("/")
.accept(MediaType.APPLICATION_JSON) (1)
.exchange()
.expectStatus()
.isOk() (2)
.expectBody()
.consumeWith(document("index")); (3)
1 | Invoke the root (/ ) of the service and indicate that an application/json response is required. |
2 | Assert that the service produced the expected response. |
3 | Document the call to the service, writing the snippets into a directory named index (which is located beneath the configured output directory).
The snippets are written by a Consumer of the ExchangeResult .
You can obtain such a consumer from the static document method on org.springframework.restdocs.webtestclient.WebTestClientRestDocumentation . |
RestAssured.given(this.spec) (1)
.accept("application/json") (2)
.filter(document("index")) (3)
.when()
.get("/") (4)
.then()
.assertThat()
.statusCode(is(200)); (5)
1 | Apply the specification that was initialized in the @Before method. |
2 | Indicate that an application/json response is required. |
3 | Document the call to the service, writing the snippets into a directory named index (which is located beneath the configured output directory).
The snippets are written by a RestDocumentationFilter .
You can obtain an instance of this class from the static document method on RestAssuredRestDocumentation in the org.springframework.restdocs.restassured package. |
4 | Invoke the root (/ ) of the service. |
5 | Assert that the service produce the expected response. |
By default, six snippets are written:
-
<output-directory>/index/curl-request.adoc
-
<output-directory>/index/http-request.adoc
-
<output-directory>/index/http-response.adoc
-
<output-directory>/index/httpie-request.adoc
-
<output-directory>/index/request-body.adoc
-
<output-directory>/index/response-body.adoc
See Documenting your API for more information about these and other snippets that can be produced by Spring REST Docs.
Using the Snippets
Before using the generated snippets, you must create an .adoc
source file.
You can name the file whatever you like as long as it has a .adoc
suffix.
The resulting HTML file has the same name but with a .html
suffix.
The default location of the source files and the resulting HTML files depends on whether you use Maven or Gradle:
Build tool | Source files | Generated files |
---|---|---|
Maven |
|
|
Gradle |
|
|
You can then include the generated snippets in the manually created Asciidoc file (described earlier in this section) by using the include macro.
You can use the snippets
attribute that is automatically set by spring-restdocs-asciidoctor
configured in the build configuration to reference the snippets output directory.
The following example shows how to do so:
include::{snippets}/index/curl-request.adoc[]