You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This guide walks you through the process of generating documention for the HTTP endpoints in a Spring application.
What you’ll build
You’ll build a simple Spring application with some HTTP endpoints exposing an API. You will test just the web layer using JUnit and Spring’s MockMvc, and then you will use the same tests to generate documentation for the API using Spring REST Docs.
Like most Spring Getting Started guides, you can start from scratch and complete each step, or you can bypass basic setup steps that are already familiar to you. Either way, you end up with working code.
Download and unzip the source repository for this guide, or clone it using Git: git clone https://github.com/spring-guides/gs-testing-restdocs.git
It collects all the jars on the classpath and builds a single, runnable "über-jar", which makes it more convenient to execute and transport your service.
It searches for the public static void main() method to flag as a runnable class.
It provides a built-in dependency resolver that sets the version number to match Spring Boot dependencies. You can override any version you wish, but it will default to Boot’s chosen set of versions.
Build with Maven
First you set up a basic build script. You can use any build system you like when building apps with Spring, but the code you need to work with Maven is included here. If you’re not familiar with Maven, refer to Building Java Projects with Maven.
Create the directory structure
In a project directory of your choosing, create the following subdirectory structure; for example, with mkdir -p src/main/java/hello on *nix systems:
It collects all the jars on the classpath and builds a single, runnable "über-jar", which makes it more convenient to execute and transport your service.
It searches for the public static void main() method to flag as a runnable class.
It provides a built-in dependency resolver that sets the version number to match Spring Boot dependencies. You can override any version you wish, but it will default to Boot’s chosen set of versions.
@SpringBootApplication is a convenience annotation that adds all of the following:
@Configuration tags the class as a source of bean definitions for the application context.
@EnableAutoConfiguration tells Spring Boot to start adding beans based on classpath settings, other beans, and various property settings.
Normally you would add @EnableWebMvc for a Spring MVC app, but Spring Boot adds it automatically when it sees spring-webmvc on the classpath. This flags the application as a web application and activates key behaviors such as setting up a DispatcherServlet.
@ComponentScan tells Spring to look for other components, configurations, and services in the the hello package, allowing it to find the HelloController.
The main() method uses Spring Boot’s SpringApplication.run() method to launch an application. Did you notice that there wasn’t a single line of XML? No web.xml file either. This web application is 100% pure Java and you didn’t have to deal with configuring any plumbing or infrastructure.
Build an executable JAR
You can run the application from the command line with Gradle or Maven. Or you can build a single executable JAR file that contains all the necessary dependencies, classes, and resources, and run that. This makes it easy to ship, version, and deploy the service as an application throughout the development lifecycle, across different environments, and so forth.
If you are using Gradle, you can run the application using ./gradlew bootRun. Or you can build the JAR file using ./gradlew build. Then you can run the JAR file:
If you are using Maven, you can run the application using ./mvnw spring-boot:run. Or you can build the JAR file with ./mvnw clean package. Then you can run the JAR file:
java -jar target/gs-testing-restdocs-0.1.0.jar
The procedure above will create a runnable JAR. You can also opt to build a classic WAR file instead.
Logging output is displayed. The service should be up and running within a few seconds.
Test the application
Now that the application is running, you can test it. If it is running you can load the home page on http://localhost:8080. But to give yourself more confidence that the application is working when you make changes, you want to automate the testing. You also want to publish documentation for the HTTP endpoint and you can generate the dynamic parts of that as part of the tests using Spring REST Docs.
The first thing you can do is write a simple sanity check test that will fail if the application context cannot start. First add Spring Test and Spring REST Docs as dependencies to your project, in the test scope. If you are using Maven:
You have included the "mockmvc" flavour of REST Docs which uses Spring MockMvc to capture the HTTP content. If your own app is not using Spring MVC there is also a "restassured" flavour which works with full stack integration tests.
Then create a test case with the @RunWith and @SpringBootTest annotations and an empty test method:
You can run this test in your IDE or on the command line (mvn test or gradle test) and it should pass.
It’s nice to have a sanity check like that, but you should also write some tests that assert the behaviour of our application. A useful approach is to test only the MVC layer, where Spring handles the incoming HTTP request and hands it off to your controller. To do that you can use Spring’s MockMvc, and ask for that to be injected for us by using the @WebMvcTest annotation on the test case:
The test above makes (mock) HTTP requests and asserts the responses. The HTTP API that you have created has dynamic content (at least in principle), so it would be really nice to be able to spy on the tests and syphon off the HTTP requests for use in the documentation. Spring REST Docs allows you to do this by generating "snippets". You can get this working really easily, just by adding an annotation to your test and an extra "assertion". Here’s the complete test:
The new annotation is @AutoConfigureRestDocs (from Spring Boot), which takes as an argument a directory location for the generated snippets. And the new assertion is MockMvcRestDocumentation.document, which takes as an argument a string identifier for the snippets.
Gradle users might prefer to use build instead of target as an output directory, but really it doesn’t matter. It’s up to you to choose.
Run this test and then look in target/snippets. You should find a directory called home (the identifier) containing Asciidoctor snippets:
The default snippets are in Asciidoctor format, for the HTTP request and response, plus command line examples for curl and httpie (two common and popular command line HTTP clients).
You can create additional snippets by adding arguments to the document() assertion in the test. For example, you can document each of the fields in a JSON response using the PayloadDocumentation.responseFields() snippet:
src/test/java/hello/WebLayerTest.java
this.mockMvc.perform(get("/"))
...
.andDo(document("home", responseFields(
fieldWithPath("message").description("The welcome message for the user.")
));
If you try this and execute the test you should find an additional snippet file called "response-fields.adoc", containing a table of field anames and descriptions. If you omit a field or get its name wrong the test will fail - this is the power of REST Docs.
You can create custom snippets, and also change the format of the snippets and customize things like the hostname. Check the documentation of Spring REST Docs for more detail.
Using the Snippets
To use the generated snippets you would want to have some Asciidoctor content in the project, and then include the snippets at build time. To see this working, create a new file src/main/asciidoc/index.adoc and include the snippets as desired. For example
src/main/asciidoc/index.adoc
= Getting Started With Spring REST Docs
This is an example output for a service running at http://localhost:8080:
.requestinclude::{snippets}/home/http-request.adoc[].responseinclude::{snippets}/home/http-response.adoc[]
As you can see the format is very simple, and in fact you always get the same message.
The main feature of this is that it includes 2 of the snippets, using the Asciidoctor include directive (the colons and the trailing brackets tell the parser to do something special on those lines). Notice that the path to the included snippets is expressed as a placeholder - an "attribute" in Asciidoctor - called {snippets}. The only other markup in this simple case is the "=" at the top, which is a level 1 section heading, and the "." before the captions ("request" and "response") on the snippets.
Then in the build configuration you would need to process this source file into your chosen documentation format. For example using Maven to generate HTML (target/generated-docs is generated when you do mvnw package):
The Asciidoctor Gradle plugin is not in Maven Central, so you also have to add jcenter() to the buildscipt dependencies in Gradle.
The default location for asciidoctor sources in Gradle is src/doc/asciidoc. We only need to set the sourceDir because we changed the location to match the default for Maven.
Summary
Congratulations! You’ve just developed a Spring application and documented it using Spring Restdocs. You could publish the HTML documentation you created to a static website, or package it up and serve it from the application itself. Your documentation will always be up to date, and tests will fail your build if it is not.
Creating API Documentation with Restdocs
This guide walks you through the process of generating documention for the HTTP endpoints in a Spring application.
What you’ll build
You’ll build a simple Spring application with some HTTP endpoints exposing an API. You will test just the web layer using JUnit and Spring’s
MockMvc
, and then you will use the same tests to generate documentation for the API using Spring REST Docs.What you’ll need
How to complete this guide
Like most Spring Getting Started guides, you can start from scratch and complete each step, or you can bypass basic setup steps that are already familiar to you. Either way, you end up with working code.
To start from scratch, move on to Build with Gradle.
To skip the basics, do the following:
git clone https://github.com/spring-guides/gs-testing-restdocs.git
gs-testing-restdocs/initial
When you’re finished, you can check your results against the code in
gs-testing-restdocs/complete
.Build with Gradle
First you set up a basic build script. You can use any build system you like when building apps with Spring, but the code you need to work with Gradle and Maven is included here. If you’re not familiar with either, refer to Building Java Projects with Gradle or Building Java Projects with Maven.
Create the directory structure
In a project directory of your choosing, create the following subdirectory structure; for example, with
mkdir -p src/main/java/hello
on *nix systems:Create a Gradle build file
Below is the initial Gradle build file.
build.gradle
The Spring Boot gradle plugin provides many convenient features:
public static void main()
method to flag as a runnable class.Build with Maven
First you set up a basic build script. You can use any build system you like when building apps with Spring, but the code you need to work with Maven is included here. If you’re not familiar with Maven, refer to Building Java Projects with Maven.
Create the directory structure
In a project directory of your choosing, create the following subdirectory structure; for example, with
mkdir -p src/main/java/hello
on *nix systems:pom.xml
The Spring Boot Maven plugin provides many convenient features:
public static void main()
method to flag as a runnable class.Build with your IDE
Create a simple application
Create a new controller for your Spring application:
src/main/java/hello/HomeController.java
Make the application executable
Create a "main" class that you can use to launch the application:
src/main/java/hello/Application.java
@SpringBootApplication
is a convenience annotation that adds all of the following:@Configuration
tags the class as a source of bean definitions for the application context.@EnableAutoConfiguration
tells Spring Boot to start adding beans based on classpath settings, other beans, and various property settings.@EnableWebMvc
for a Spring MVC app, but Spring Boot adds it automatically when it sees spring-webmvc on the classpath. This flags the application as a web application and activates key behaviors such as setting up aDispatcherServlet
.@ComponentScan
tells Spring to look for other components, configurations, and services in the thehello
package, allowing it to find theHelloController
.The
main()
method uses Spring Boot’sSpringApplication.run()
method to launch an application. Did you notice that there wasn’t a single line of XML? No web.xml file either. This web application is 100% pure Java and you didn’t have to deal with configuring any plumbing or infrastructure.Build an executable JAR
You can run the application from the command line with Gradle or Maven. Or you can build a single executable JAR file that contains all the necessary dependencies, classes, and resources, and run that. This makes it easy to ship, version, and deploy the service as an application throughout the development lifecycle, across different environments, and so forth.
If you are using Gradle, you can run the application using
./gradlew bootRun
. Or you can build the JAR file using./gradlew build
. Then you can run the JAR file:If you are using Maven, you can run the application using
./mvnw spring-boot:run
. Or you can build the JAR file with./mvnw clean package
. Then you can run the JAR file:Logging output is displayed. The service should be up and running within a few seconds.
Test the application
Now that the application is running, you can test it. If it is running you can load the home page on http://localhost:8080. But to give yourself more confidence that the application is working when you make changes, you want to automate the testing. You also want to publish documentation for the HTTP endpoint and you can generate the dynamic parts of that as part of the tests using Spring REST Docs.
The first thing you can do is write a simple sanity check test that will fail if the application context cannot start. First add Spring Test and Spring REST Docs as dependencies to your project, in the test scope. If you are using Maven:
pom.xml
or if you are using Gradle:
build.gradle
Then create a test case with the
@RunWith
and@SpringBootTest
annotations and an empty test method:src/test/java/hello/ApplicationTest.java
You can run this test in your IDE or on the command line (
mvn test
orgradle test
) and it should pass.It’s nice to have a sanity check like that, but you should also write some tests that assert the behaviour of our application. A useful approach is to test only the MVC layer, where Spring handles the incoming HTTP request and hands it off to your controller. To do that you can use Spring’s
MockMvc
, and ask for that to be injected for us by using the@WebMvcTest
annotation on the test case:src/test/java/hello/WebLayerTest.java
Generate Snippets for Documentation
The test above makes (mock) HTTP requests and asserts the responses. The HTTP API that you have created has dynamic content (at least in principle), so it would be really nice to be able to spy on the tests and syphon off the HTTP requests for use in the documentation. Spring REST Docs allows you to do this by generating "snippets". You can get this working really easily, just by adding an annotation to your test and an extra "assertion". Here’s the complete test:
src/test/java/hello/WebLayerTest.java
The new annotation is
@AutoConfigureRestDocs
(from Spring Boot), which takes as an argument a directory location for the generated snippets. And the new assertion isMockMvcRestDocumentation.document
, which takes as an argument a string identifier for the snippets.Run this test and then look in
target/snippets
. You should find a directory calledhome
(the identifier) containing Asciidoctor snippets:The default snippets are in Asciidoctor format, for the HTTP request and response, plus command line examples for
curl
andhttpie
(two common and popular command line HTTP clients).You can create additional snippets by adding arguments to the
document()
assertion in the test. For example, you can document each of the fields in a JSON response using thePayloadDocumentation.responseFields()
snippet:src/test/java/hello/WebLayerTest.java
If you try this and execute the test you should find an additional snippet file called "response-fields.adoc", containing a table of field anames and descriptions. If you omit a field or get its name wrong the test will fail - this is the power of REST Docs.
Using the Snippets
To use the generated snippets you would want to have some Asciidoctor content in the project, and then include the snippets at build time. To see this working, create a new file
src/main/asciidoc/index.adoc
and include the snippets as desired. For examplesrc/main/asciidoc/index.adoc
The main feature of this is that it includes 2 of the snippets, using the Asciidoctor
include
directive (the colons and the trailing brackets tell the parser to do something special on those lines). Notice that the path to the included snippets is expressed as a placeholder - an "attribute" in Asciidoctor - called{snippets}
. The only other markup in this simple case is the "=" at the top, which is a level 1 section heading, and the "." before the captions ("request" and "response") on the snippets.Then in the build configuration you would need to process this source file into your chosen documentation format. For example using Maven to generate HTML (
target/generated-docs
is generated when you domvnw package
):pom.xml
or if you are using Gradle (
build/asciidoc
is generated when you dogradlew asciidoctor
):build.gradle
Summary
Congratulations! You’ve just developed a Spring application and documented it using Spring Restdocs. You could publish the HTML documentation you created to a static website, or package it up and serve it from the application itself. Your documentation will always be up to date, and tests will fail your build if it is not.
See Also
The following guides may also be helpful:
The text was updated successfully, but these errors were encountered: