Files
spring-restdocs/docs/src/docs/asciidoc/getting-started.adoc
Andy Wilkinson 37e16bc308 Polish contribution
This commit polishes the HTTPie request snippet contribution made in
b26d8c0. It makes the following significant changes:

- Applies project’s coding conventions for formatting and the like
- Moves to a composition-based approach for sharing functionality
  between the curl and HTTPie snippets by replacing AbstractCliSnippet
  with CliOperationRequest.
- Introduces a single package for CLI command snippets, thereby allowing
  more code to be package-private.

See gh-207
2016-03-09 17:38:04 +00:00

398 lines
13 KiB
Plaintext

[[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"]
|===
| Sample | Build system | Description
| {samples}/rest-assured[REST Assured]
| Gradle
| Demonstrates the use of Spring REST Docs with http://rest-assured.io[REST Assured].
| {samples}/rest-notes-slate[Slate]
| Gradle
| Demonstrates the use of Spring REST Docs with Markdown and
http://github.com/tripit/slate[Slate].
| {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].
| {samples}/testng[TestNG]
| Gradle
| Demonstrates the use of Spring REST Docs with http://testng.org[TestNG].
|===
[[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>
<properties> <2>
<snippetsDirectory>${project.build.directory}/generated-snippets</snippetsDirectory>
</properties>
<build>
<plugins>
<plugin> <3>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<includes>
<include>**/*Documentation.java</include>
</includes>
</configuration>
</plugin>
<plugin> <4>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctor-maven-plugin</artifactId>
<version>1.5.2</version>
<executions>
<execution>
<id>generate-docs</id>
<phase>package</phase> <6>
<goals>
<goal>process-asciidoc</goal>
</goals>
<configuration>
<backend>html</backend>
<doctype>book</doctype>
<attributes>
<snippets>${snippetsDirectory}</snippets> <5>
</attributes>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
----
<1> Add a dependency on `spring-restdocs-mockmvc` in the `test` scope. If you want to use
REST Assured rather than MockMvc, add a dependency on `spring-restdocs-restassured`
instead.
<2> Configure a property to define the output location for generated snippets.
<3> Add the SureFire plugin and configure it to include files whose names end with
`Documentation.java`.
<4> Add the Asciidoctor plugin
<5> Define an attribute named `snippets` that can be used when including the generated
snippets in your documentation.
<6> [[getting-started-build-configuration-maven-plugin-phase]] If you want to
<<getting-started-build-configuration-maven-packaging, package the documentation>> in your
project's jar you should use the `prepare-package` phase.
[source,groovy,indent=0,subs="verbatim,attributes",role="secondary"]
.Gradle
----
plugins { <1>
id "org.asciidoctor.convert" version "1.5.2"
}
dependencies { <2>
testCompile 'org.springframework.restdocs:spring-restdocs-mockmvc:{project-version}'
}
ext { <3>
snippetsDir = file('build/generated-snippets')
}
test { <4>
outputs.dir snippetsDir
}
asciidoctor { <5>
attributes 'snippets': snippetsDir <6>
inputs.dir snippetsDir <7>
dependsOn test <8>
}
----
<1> Apply the Asciidoctor plugin.
<2> 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.
<3> Configure a property to define the output location for generated snippets.
<4> Configure the `test` task to add the snippets directory as an output.
<5> Configure the `asciidoctor` task
<6> Define an attribute named `snippets` that can be used when including the generated
snippets in your documentation.
<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-gradle-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",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,groovy,indent=0,role="secondary"]
.Gradle
----
jar {
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-framework-docs}/#spring-mvc-test-framework[Spring's MVC Test framework] 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. Other frameworks, such as TestNG,
are also supported although slightly more setup is required.
[[getting-started-documentation-snippets-setup-junit]]
===== Setting up your JUnit tests
When using JUnit, the first step in generating documentation snippets is to declare a
`public` `JUnitRestDocumentation` field that's annotated as a JUnit `@Rule`. The
`JUnitRestDocumentation` rule is configured with the output directory into which generated
snippets should be written. This output directory should match the snippets directory that
you have configured in your `build.gradle` or `pom.xml` file.
For Maven (`pom.xml` that will typically be `target/generated-snippets` and for
Gradle (`build.gradle`) it will typically be `build/generated-snippets`:
[source,java,indent=0,role="primary"]
.Maven
----
@Rule
public JUnitRestDocumentation restDocumentation =
new JUnitRestDocumentation("target/generated-snippets");
----
[source,java,indent=0,role="secondary"]
.Gradle
----
@Rule
public JUnitRestDocumentation restDocumentation =
new JUnitRestDocumentation("build/generated-snippets");
----
Next, provide an `@Before` method to configure MockMvc 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"]
.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
`org.springframework.restdocs.restassured.RestAssuredRestDocumentation`.
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,role="primary"]
.Maven
----
private ManualRestDocumentation restDocumentation =
new ManualRestDocumentation("target/generated-snippets");
----
[source,java,indent=0,role="secondary"]
.Gradle
----
private ManualRestDocumentation restDocumentation =
new ManualRestDocumentation("build/generated-snippets");
----
Secondly, `ManualRestDocumentation.beforeTest(Class, String)`
must be called before each test. This can be done as part of the method that is
configuring MockMVC 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"]
.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"]
.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
`org.springframework.restdocs.restassured.RestAssuredRestDocumentation`.
<4> Invoke the root (`/`) of the service.
<5> Assert that the service produce the expected response.
By default, four 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`
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
The generated snippets can be included in your documentation using the
http://asciidoctor.org/docs/asciidoc-syntax-quick-reference/#include-files[include macro].
The `snippets` attribute specified 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[]
----