[[getting-started]]
== Getting started

This section describes how to get started with Spring REST Docs.



[[getting-started-sample-applications]]
=== Sample applications

If you want to jump straight in, a number of sample applications are available:


[cols="3,2,10"]
.MockMvc
|===
| Sample | Build system | Description

| {samples}/rest-notes-spring-data-rest[Spring Data REST]
| Maven
| Demonstrates the creation of a getting started guide and an API guide for a service
  implemented using http://projects.spring.io/spring-data-rest/[Spring Data REST].

| {samples}/rest-notes-spring-hateoas[Spring HATEOAS]
| Gradle
| Demonstrates the creation of a getting started guide and an API guide for a service
  implemented using http://projects.spring.io/spring-hateoas/[Spring HATEOAS].

|===

[cols="3,2,10"]
.WebTestClient
|===
| Sample | Build system | Description

| {samples}/web-test-client[WebTestClient]
| Gradle
| Demonstrates the use of Spring REST docs with Spring WebFlux's WebTestClient.

|===


[cols="3,2,10"]
.REST Assured
|===
| Sample | Build system | Description

| {samples}/rest-notes-grails[Grails]
| Gradle
| Demonstrates the use of Spring REST docs with https://grails.org[Grails] and
  https://github.com/spockframework/spock[Spock].

| {samples}/rest-assured[REST Assured]
| Gradle
| Demonstrates the use of Spring REST Docs with http://rest-assured.io[REST Assured].

|===


[cols="3,2,10"]
.Advanced
|===
| Sample | Build system | Description

| {samples}/rest-notes-slate[Slate]
| Gradle
| Demonstrates the use of Spring REST Docs with Markdown and
  http://github.com/tripit/slate[Slate].

| {samples}/testng[TestNG]
| Gradle
| Demonstrates the use of Spring REST Docs with http://testng.org[TestNG].

| {samples}/junit5[JUnit 5]
| Gradle
| Demonstrates the use of Spring REST Docs with http://junit.org/junit5/[JUnit 5].

|===

[[getting-started-requirements]]
=== Requirements

Spring REST Docs has the following minimum requirements:

- Java 8
- Spring Framework 5 (5.0.2 or later)

Additionally, the `spring-restdocs-restassured` module has the following minimum
requirements:

- REST Assured 3.0

[[getting-started-build-configuration]]
=== Build configuration

The first step in using Spring REST Docs is to configure your project's build. The
{samples}/rest-notes-spring-hateoas[Spring HATEOAS] and
{samples}/rest-notes-spring-data-rest[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 below.

[source,xml,indent=0,subs="verbatim,attributes",role="primary"]
.Maven
----
	<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>1.5.3</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
	<<getting-started-build-configuration-maven-packaging, 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.

[source,indent=0,subs="verbatim,attributes",role="secondary"]
.Gradle
----
	plugins { <1>
		id "org.asciidoctor.convert" version "1.5.3"
	}

	dependencies {
		asciidoctor 'org.springframework.restdocs:spring-restdocs-asciidoctor:{project-version}' <2>
		testCompile 'org.springframework.restdocs:spring-restdocs-mockmvc:{project-version}' <3>
	}

	ext { <4>
		snippetsDir = file('build/generated-snippets')
	}

	test { <5>
		outputs.dir snippetsDir
	}

	asciidoctor { <6>
		inputs.dir snippetsDir <7>
		dependsOn test <8>
	}
----
<1> Apply the Asciidoctor plugin.
<2> Add a dependency on `spring-restdocs-asciidoctor` in the `asciidoctor` 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.
<3> Add a dependency on `spring-restdocs-mockmvc` in the `testCompile` configuration. If
	you want to use REST Assured rather than MockMvc, add a dependency on
	`spring-restdocs-restassured` instead.
<4> Configure a property to define the output location for generated snippets.
<5> Configure the `test` task to add the snippets directory as an output.
<6> Configure the `asciidoctor` task
<7> Configure the snippets directory as an input.
<8> Make the task depend on the test task so that the tests are run before the
	documentation is created.


[[getting-started-build-configuration-packaging-the-documentation]]
==== Packaging the documentation

You may want to package the generated documentation in your project's jar file, for
example to have it {spring-boot-docs}/#boot-features-spring-mvc-static-content[served as
static content] by Spring Boot. To do so, configure your project's build so that:

1. The documentation is generated before the jar is built
2. The generated documentation is included in the jar

[source,xml,indent=0,role="primary"]
.Maven
----
	<plugin> <1>
		<groupId>org.asciidoctor</groupId>
		<artifactId>asciidoctor-maven-plugin</artifactId>
		<!-- … -->
	</plugin>
	<plugin> <2>
		<artifactId>maven-resources-plugin</artifactId>
		<version>2.7</version>
		<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.
<3> Copy the generated documentation into the build output's `static/docs` directory,
from where it will be included in the jar file.

[source,indent=0,role="secondary"]
.Gradle
----
	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.



[[getting-started-documentation-snippets]]
=== Generating documentation snippets
Spring REST Docs uses Spring MVC's
{spring-framework-docs}/testing.html#spring-mvc-test-framework[test framework],
Spring WebFlux's {spring-framework-docs}/testing.html#webtestclient[`WebTestClient`] or
http://www.rest-assured.io[REST Assured] to make requests to the service that you are
documenting. It then produces documentation snippets for the request and the resulting
response.



[[getting-started-documentation-snippets-setup]]
==== Setting up your tests

Exactly how you setup your tests depends on the test framework that you're using.
Spring REST Docs provides first-class support for JUnit 4 and JUnit 5. Other frameworks,
such as TestNG, are also supported although slightly more setup is required.

[[getting-started-documentation-snippets-setup-junit]]
===== 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's annotated as a JUnit `@Rule`.


[source,java,indent=0]
----
@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:

[cols="2,5"]
|===
| Build tool | Output directory

| Maven
| `target/generated-snippets`

| Gradle
| `build/generated-snippets`

|===

The default can be overridden by providing an output directory when creating the
`JUnitRestDocumentation` instance:

[source,java,indent=0]
----
@Rule
public JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation("custom");
----

Next, provide an `@Before` method to configure MockMvc, WebTestClient or REST Assured:

[source,java,indent=0,role="primary"]
.MockMvc
----
include::{examples-dir}/com/example/mockmvc/ExampleApplicationTests.java[tags=setup]
----
<1> The `MockMvc` instance is configured using a `MockMvcRestDocumentationConfigurer`. An
instance of this class can be obtained from the static `documentationConfiguration()`
method on `org.springframework.restdocs.mockmvc.MockMvcRestDocumentation`.

[source,java,indent=0,role="secondary"]
.WebTestClient
----
include::{examples-dir}/com/example/webtestclient/ExampleApplicationTests.java[tags=setup]
----
<1> The `WebTestClient` instance is configured by adding a
`WebTestclientRestDocumentationConfigurer` as an `ExchangeFilterFunction`.  An instance of
this class can be obtained from the static `documentationConfiguration()` method on
`org.springframework.restdocs.webtestclient.WebTestClientRestDocumentation`.

[source,java,indent=0,role="secondary"]
.REST Assured
----
include::{examples-dir}/com/example/restassured/ExampleApplicationTests.java[tags=setup]
----
<1> REST Assured is configured by adding a `RestAssuredRestDocumentationConfigurer` as a
`Filter`. An instance of this class can be obtained from the static
`documentationConfiguration()` method on `RestAssuredRestDocumentation` in the
`org.springframework.restdocs.restassured3` package.

The configurer applies sensible defaults and also provides an API for customizing the
configuration. Refer to the <<configuration, configuration section>> for more information.



[[getting-started-documentation-snippets-setup-junit-5]]
===== 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:

[source,java,indent=0]
----
@ExtendWith(RestDocumentationExtension.class)
public class JUnit5ExampleTests {
----

For testing a typical Spring application the `SpringExtension` should also be applied:

[source,java,indent=0]
----
@ExtendWith({RestDocumentationExtension.class, SpringExtension.class})
public class JUnit5ExampleTests {
----

The `RestDocumentationExtension` is automatically configured with an output directory
based on your project's build tool:

[cols="2,5"]
|===
| Build tool | Output directory

| Maven
| `target/generated-snippets`

| Gradle
| `build/generated-snippets`

|===



Next, provide a `@BeforeEach` method to configure MockMvc, WebTestClient, or REST Assured:

[source,java,indent=0,role="primary"]
.MockMvc
----
include::{examples-dir}/com/example/mockmvc/ExampleApplicationJUnit5Tests.java[tags=setup]
----
<1> The `MockMvc` instance is configured using a `MockMvcRestDocumentationConfigurer`. An
instance of this class can be obtained from the static `documentationConfiguration()`
method on `org.springframework.restdocs.mockmvc.MockMvcRestDocumentation`.

[source,java,indent=0,role="secondary"]
.WebTestClient
----
include::{examples-dir}/com/example/webtestclient/ExampleApplicationJUnit5Tests.java[tags=setup]
----
<1> The `WebTestClient` instance is configured by adding a
`WebTestClientRestDocumentationConfigurer` as an `ExchangeFilterFunction`.  An instance of
this class can be obtained from the static `documentationConfiguration()` method on
`org.springframework.restdocs.webtestclient.WebTestClientRestDocumentation`.

[source,java,indent=0,role="secondary"]
.REST Assured
----
include::{examples-dir}/com/example/restassured/ExampleApplicationJUnit5Tests.java[tags=setup]
----
<1> REST Assured is configured by adding a `RestAssuredRestDocumentationConfigurer` as a
`Filter`. An instance of this class can be obtained from the static
`documentationConfiguration()` method on `RestAssuredRestDocumentation` in the
`org.springframework.restdocs.restassured3` package.

The configurer applies sensible defaults and also provides an API for customizing the
configuration. Refer to the <<configuration, configuration section>> for more information.



===== Setting up your tests without JUnit
[[getting-started-documentation-snippets-setup-manual]]

The configuration when JUnit is not being used is largely similar to when it is being
used. This section describes the key differences. The {samples}/testng[TestNG sample] also
illustrates the approach.

The first difference is that `ManualRestDocumentation` should be used in place of
`JUnitRestDocumentation` and there's no need for the `@Rule` annotation:

[source,java,indent=0]
----
private ManualRestDocumentation restDocumentation = new ManualRestDocumentation();
----

Secondly, `ManualRestDocumentation.beforeTest(Class, String)`
must be called before each test. This can be done as part of the method that is
configuring MockMvc, WebTestClient, or REST Assured:

[source,java,indent=0,role="primary"]
.MockMvc
----
include::{examples-dir}/com/example/mockmvc/ExampleApplicationTestNgTests.java[tags=setup]
----

[source,java,indent=0,role="secondary"]
.WebTestClient
----
include::{examples-dir}/com/example/webtestclient/ExampleApplicationTestNgTests.java[tags=setup]
----

[source,java,indent=0,role="secondary"]
.REST Assured
----
include::{examples-dir}/com/example/restassured/ExampleApplicationTestNgTests.java[tags=setup]
----

Lastly, `ManualRestDocumentation.afterTest` must be called after each test. For example,
with TestNG:

[source,java,indent=0]
----
include::{examples-dir}/com/example/restassured/ExampleApplicationTestNgTests.java[tags=teardown]
----

[[getting-started-documentation-snippets-invoking-the-service]]
==== Invoking the RESTful service

Now that the testing framework has been configured, it can be used to invoke the RESTful
service and document the request and response. For example:

[source,java,indent=0,role="primary"]
.MockMvc
----
include::{examples-dir}/com/example/mockmvc/InvokeService.java[tags=invoke-service]
----
<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`
that will be located beneath the configured output directory. The snippets are written by
a `RestDocumentationResultHandler`. An instance of this class can be obtained from the
static `document` method on
`org.springframework.restdocs.mockmvc.MockMvcRestDocumentation`.

[source,java,indent=0,role="secondary"]
.WebTestClient
----
include::{examples-dir}/com/example/webtestclient/InvokeService.java[tags=invoke-service]
----
<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`
that will be located beneath the configured output directory. The snippets are written by
a `Consumer` of the `ExchangeResult`. Such a consumer can be obtained from the static
`document` method on `org.springframework.restdocs.webtestclient.WebTestClientRestDocumentation`.

[source,java,indent=0,role="secondary"]
.REST Assured
----
include::{examples-dir}/com/example/restassured/InvokeService.java[tags=invoke-service]
----
<1> Apply the specification that was initialised 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`
that will be located beneath the configured output directory. The snippets are written by
a `RestDocumentationFilter`. An instance of this class can be obtained from the
static `document` method on `RestAssuredRestDocumentation`  in the
`org.springframework.restdocs.restassured3` 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`

Refer to <<documenting-your-api>> for more information about these and other snippets
that can be produced by Spring REST Docs.



[[getting-started-using-the-snippets]]
=== Using the snippets

Before using the generated snippets, a `.adoc` source file must be created. You can name
the file whatever you like as long as it has a `.adoc` suffix. The result HTML file will
have the same name but with a `.html` suffix. The default location of the source files and
the resulting HTML files depends on whether you are using Maven or Gradle:

[cols="2,5,8"]
|===
| Build tool | Source files | Generated files

| Maven
| `src/main/asciidoc/*.adoc`
| `target/generated-docs/*.html`

| Gradle
| `src/docs/asciidoc/*.adoc`
| `build/asciidoc/html5/*.html`

|===

The generated snippets can then be included in the manually created Asciidoctor file from
above using the
http://asciidoctor.org/docs/asciidoc-syntax-quick-reference/#include-files[include macro].
The `snippets` attribute that is automatically set by `spring-restdocs-asciidoctor`
configured in the <<getting-started-build-configuration, build
configuration>> can be used to reference the snippets output directory. For example:

[source,adoc,indent=0]
----
\include::{snippets}/index/curl-request.adoc[]
----
