Update README and reference docs to avoid duplication of content

This commit is contained in:
Andy Wilkinson
2015-06-24 11:45:30 +01:00
parent 1ae014dc53
commit 8a0b07576d
9 changed files with 182 additions and 429 deletions

View File

@@ -1,6 +1,6 @@
# Contributing to Spring REST Docs
Spring REST docs is released under the Apache 2.0 license. If you would like to
Spring REST Docs is released under the Apache 2.0 license. If you would like to
contribute something, or simply want to work with the code, this document should help you
to get started.
@@ -36,10 +36,7 @@ None of these is essential for a pull request, but they will all help
### Building from source
To build the source you will need to use Java 8 the main project only requires Java 7
but the sample projects use Java 8.
The code can be built with Gradle:
To build the source you will need Java 7 or later. The code is built with Gradle:
```
$ ./gradlew build

434
README.md
View File

@@ -1,407 +1,47 @@
# Spring REST docs [![Build status][10]][11]
# Spring REST Docs [![Build status][1]][2]
## Overview
The primary goal of this project is to make it easy to document RESTful services by
combining content that's been hand-written with auto-generated examples produced
with the [Spring MVC Test][2] framework. The result is intended to be an easy-to-read
user guide, akin to [GitHub's API documentation][3] for example, rather than the fully
automated, dense API documentation produced by tools like [Swagger][4].
combining content that's been hand-written using [Asciidoctor][3] with auto-generated
examples produced with the [Spring MVC Test][4] framework. The result is intended to be
an easy-to-read user guide, akin to [GitHub's API documentation][5] for example, rather
than the fully automated, dense API documentation produced by tools like [Swagger][6].
For a broader introduction see the Documenting RESTful APIs presentation. Both the
[slides][9] and a [video recording][13] are available.
## Quickstart
The project requires Spring Framework 4.1 and Java 7 or later. Snapshots are published to
`https://repo.spring.io/snapshot`. Alternatively, it can be built locally using Gradle:
```
$ ./gradlew build install
```
The quickest way to get started is to look at one of the two sample projects. Both
projects implement a RESTful service for creating tagged notes and illustrate the use
of Maven or Gradle. The two projects have different implementations:
`rest-notes-spring-hateoas` is implemented using Spring MVC and Spring Hateoas where as
`rest-notes-spring-data-rest` is implemented using Spring Data REST.
Every example request and response in the documentation is auto-generated using custom
Spring MVC Test result handlers. This ensures that the examples match the service that
they are documenting.
### Building a sample with Gradle
To see the sample project's documentation, move into its directory and use Gradle to
build it. For example:
```
$ cd samples/rest-notes-spring-data-rest
$ ./gradlew asciidoctor
```
Once the build is complete, open one of the following:
- build/asciidoc/html5/getting-started-guide.html
- build/asciidoc/html5/api-guide.html
### Building a sample with Maven
To see the sample project's documentation, move into its directory and use Maven to build
it. For example:
```
$ cd samples/rest-notes-spring-hateoas
$ mvn package
```
Once the build is complete, open one of the following:
- target/generated-docs/getting-started-guide.html
- target/generated-docs/api-guide.html
## How it works
There are three main pieces involved in using this project to document your RESTful
service.
### Build configuration
Both Maven and Gradle are supported.
#### Gradle configuration
You can look at either samples' `build.gradle` file to see the required configuration.
The key parts are described below.
Configure the Asciidoctor plugin:
```groovy
plugins {
id "org.asciidoctor.convert" version "1.5.2"
}
```
Add a dependency on `spring-restdocs` in the `testCompile` configuration:
```groovy
dependencies {
testCompile 'org.springframework.restdocs:spring-restdocs:0.1.0.BUILD-SNAPSHOT'
}
```
Configure a property to control the location of the generated snippets:
```groovy
ext {
generatedDocumentation = file('build/generated-snippets')
}
```
Configure the `test` task with a system property to control the location to which the
snippets are generated:
```groovy
test {
systemProperty 'org.springframework.restdocs.outputDir', generatedDocumentation
outputs.dir generatedDocumentation
}
```
Configure the `asciidoctor` task. The `generated` attribute is used to provide easy
access to the generated snippets:
```groovy
asciidoctor {
attributes 'generated': generatedDocumentation
inputs.dir generatedDocumentation
dependsOn test
}
```
You may want to include the generated documentation in your project's jar file, for
example to have it [served as static content by Spring Boot][12]. You can do so by
configuring the `jar` task to depend on the `asciidoctor` task and to copy the
generated documentation into the jar's `static` directory:
```groovy
jar {
dependsOn asciidoctor
from ("${asciidoctor.outputDir}/html5") {
into 'static/docs'
}
}
```
#### Maven configuration
You can look at either samples' `pom.xml` file to see the required configuration. The key
parts are described below:
Add a dependency on `spring-restdocs` in the `test` scope:
```xml
<dependency>
<groupId>org.springframework.restdocs</groupId>
<artifactId>spring-restdocs</artifactId>
<version>0.1.0.BUILD-SNAPSHOT</version>
<scope>test</scope>
</dependency>
```
Configure the SureFire plugin with a system property to control the location to which
the snippets are generated:
```xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<includes>
<include>**/*Documentation.java</include>
</includes>
<systemPropertyVariables>
<org.springframework.restdocs.outputDir>${project.build.directory}/generated-snippets</org.springframework.restdocs.outputDir>
</systemPropertyVariables>
</configuration>
</plugin>
```
Configure the Asciidoctor plugin. The `generated` attribute is used to provide easy
access to the generated snippets:
```xml
<plugin>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctor-maven-plugin</artifactId>
<version>1.5.2</version>
<executions>
<execution>
<id>generate-docs</id>
<phase>package</phase>
<goals>
<goal>process-asciidoc</goal>
</goals>
<configuration>
<backend>html</backend>
<doctype>book</doctype>
<attributes>
<generated>${project.build.directory}/generated-snippets</generated>
</attributes>
</configuration>
</execution>
</executions>
</plugin>
```
You may want to include the generated documentation in your project's jar file, for
example to have it [served as static content by Spring Boot][12]. You can do so by
changing the configuration of the Asciidoctor plugin so that it runs in the
`prepare-package` phase and then configuring Maven's resources plugin to copy the
generated documentation into a location where it'll be included in the project's jar:
```xml
<plugin>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctor-maven-plugin</artifactId>
<version>1.5.2</version>
<executions>
<execution>
<id>generate-docs</id>
<phase>prepare-package</phase>
<!---->
</execution>
</executions>
</plugin>
<plugin>
<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>
<outputDirectory>${project.build.outputDirectory}/static/docs</outputDirectory>
<resources>
<resource>
<directory>${project.build.directory}/generated-docs</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
```
### Programatically generated snippets
Spring's MVC Test framework is used to make requests to the service that you are
documenting. A custom `ResultHandler` is used to produce individual documentation
snippets for its request and its response as well as a snippet that contains both its
request and its response.
The first step is to create a `MockMvc` instance using `MockMvcBuilders`, configuring
it by applying a `RestDocumentationConfigurer` that can be obtained from the static
`RestDocumentation.documentationConfiguration` method:
```java
@Before
public void setUp() {
this.mockMvc = MockMvcBuilders
.webAppContextSetup(this.context)
.apply(documentationConfiguration())
.build();
}
```
This will apply the default REST documentation configuration:
| Setting | Default value
| ---------------- | -------------
| Scheme | http
| Host | localhost
| Port | 8080
| Context path | Empty string
| Snippet encoding | UTF-8
One or more of these settings can be overridden:
```java
@Before
public void setUp() {
this.mockMvc = MockMvcBuilders
.webAppContextSetup(this.context)
.apply(documentationConfiguration()
.uris()
.withScheme("https")
.withHost("api.example.com")
.withPort(443)
.withContextPath("/v3")
.and().snippets()
.withEncoding("ISO-8859-1"))
.build();
}
```
To document a MockMvc call, you use MockMvc's `andDo` method, passing it a
`RestDocumentationResultHandler` that can be easily obtained from
the static `RestDocumentation.document` method:
```java
public void getIndex() {
this.mockMvc.perform(get("/").accept(MediaType.APPLICATION_JSON))
.andDo(document("index"));
}
```
The code above will perform a `GET` request against the index (`/`) of the service with
an accept header indicating that a JSON response is required. It will write the cURL
command for the request and the resulting response to files in a directory named
`index` in the project's `build/generated-snippets/` directory. Three files will
be written:
- `index/curl-request.adoc`
- `index/http-request.adoc`
- `index/http-response.adoc`
#### Parameterized output directories
The `document` method supports parameterized output directories. The following parameters
are supported:
| Parameter | Description
| ------------- | -----------
| {methodName} | The name of the test method, formatted using camelcase
| {method-name} | The name of the test method, formatted with dash separators
| {method_name} | The name of the test method, formatted with underscore separators
| {step} | The count of calls to `MockMvc.perform` in the current test
For example, `document("{method-name}")` in a test method named `creatingANote` will
write snippets into a directory named `creating-a-note`.
The `{step}` parameter is particularly useful in combination with Spring MVC Test's
`alwaysDo` functionality. It allows documentation to be configured once in a setup method:
```java
@Before
public void setUp() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
.apply(new RestDocumentationConfigurer())
.alwaysDo(document("{method-name}/{step}/"))
.build();
}
```
With this configuration in place, every call to `MockMvc.perform` will produce
documentation snippets without any further configuration. Take a look at the
`GettingStartedDocumentation` classes in each of the sample applications to see this
functionality in action.
#### Pretty-printed snippets
To improve the readability of the generated snippets you may want to configure your
application to produce JSON that has been pretty-printed. If you are a Spring Boot
user you can do so by setting the `spring.jackson.serialization.indent_output` property
to `true`.
### Hand-written documentation
Producing high-quality, easily readable documentation is difficult and the process is
only made harder by trying to write the documentation in an ill-suited format such as
Java annotations. This project addresses this by allowing you to write the bulk of
your documentation's text using [Asciidoctor][1]. The default location for source files
depends on whether you're using Maven or Gradle. By default, Asciidoctor's Maven plugin
looks in `src/main/asciidoc`, whereas the Asciidoctor Gradle plugin looks in
`src/docs/asciidoc`
To include the programmatically generated snippets in your documentation, you use
Asciidoc's [`include` macro][6]. The Maven and Gradle configuration described above
configures an attribute, `generated`, that you can use to reference the directory to
which the snippets are written. For example, to include both the request and response
snippets described above:
```
include::{generated}/index/curl-request.adoc[]
include::{generated}/index/http-response.adoc[]
```
## Generating snippets in your IDE
As described above, a system property is used to configure the location to which the
generated snippets are written. When running documentation tests in your IDE this system
property will not have been set. If the property is not set the snippets will be written
to standard out.
If you'd prefer that your IDE writes the snippets to disk you can use a file
in `src/test/resources` named `documentation.properties` to configure the property.
For example:
```properties
org.springframework.restdocs.outputDir: target/generated-snippets
```
[slides][7] and a [video recording][8] are available.
## Learning more
To learn more, take a look at the accompanying sample projects:
To learn more about Spring REST Docs, please consult the [reference documentation][9].
- [rest-notes-spring-data-rest][7]
- [rest-notes-spring-hateoas][8]
## Building from source
Spring REST Docs requires Java 7 or later and is built using [Gradle][10]:
```
./gradlew build
```
## Contributing
[Pull requests][11] are welcome. Please see the [contributor guidelines][12] for details.
## Licence
Spring REST Docs is open source software released under the [Apache 2.0 license][13].
[1]: https://build.spring.io/plugins/servlet/buildStatusImage/SRD-PUB (Build status)
[2]: https://build.spring.io/browse/SRD-PUB
[3]: http://asciidoctor.org
[4]: http://docs.spring.io/spring-framework/docs/4.1.x/spring-framework-reference/htmlsingle/#spring-mvc-test-framework
[5]: https://developer.github.com/v3/
[6]: http://swagger.io
[7]: https://speakerdeck.com/ankinson/documenting-restful-apis-webinar
[8]: https://www.youtube.com/watch?v=knH5ihPNiUs&feature=youtu.be
[9]: http://docs.spring.io/spring-restdocs/docs/
[10]: http://gradle.org
[11]: https://help.github.com/articles/using-pull-requests/
[12]: https://github.com/spring-projects/spring-restdocs/blob/master/CONTRIBUTING.md
[13]: http://www.apache.org/licenses/LICENSE-2.0.html
[1]: http://asciidoctor.org
[2]: http://docs.spring.io/spring-framework/docs/4.1.1.RELEASE/spring-framework-reference/html/testing.html#spring-mvc-test-framework
[3]: https://developer.github.com/v3/
[4]: http://swagger.io
[5]: http://plugins.gradle.org/plugin/org.asciidoctor.gradle.asciidoctor
[6]: http://www.methods.co.nz/asciidoc/userguide.html#_system_macros
[7]: samples/rest-notes-spring-data-rest
[8]: samples/rest-notes-spring-hateoas
[9]: https://speakerdeck.com/ankinson/documenting-restful-apis-webinar
[10]: https://build.spring.io/plugins/servlet/buildStatusImage/SRD-PUB (Build status)
[11]: https://build.spring.io/browse/SRD-PUB
[12]: http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-spring-mvc-static-content
[13]: https://www.youtube.com/watch?v=knH5ihPNiUs&feature=youtu.be

View File

@@ -16,5 +16,6 @@ asciidoctor {
sources {
include 'index.adoc'
}
attributes 'revnumber': project.version
attributes 'revnumber': project.version,
'branch-or-tag': project.version.endsWith('SNAPSHOT') ? 'master': "v${project.version}"
}

View File

@@ -29,7 +29,7 @@ change one or more of the defaults to suit your needs:
[source,java,indent=0]
----
include::{examples-dir}com/example/CustomUriConfiguration.java[tags=custom-uri-configuration]
include::{examples-dir}/com/example/CustomUriConfiguration.java[tags=custom-uri-configuration]
----
@@ -43,7 +43,7 @@ use `RestDocumentationConfigurer` to configure it:
[source,java,indent=0]
----
include::{examples-dir}com/example/CustomEncoding.java[tags=custom-encoding]
include::{examples-dir}/com/example/CustomEncoding.java[tags=custom-encoding]
----

View File

@@ -0,0 +1,36 @@
[[contributing]]
== Contributing
Spring REST Docs is intended to make is easy for you to produce high-quality documentation
for your RESTful services. However, we can't achieve that goal without your contributions.
[[contributing-questions]]
=== Questions
You can ask questions about Spring REST Docs on http://stackoverflow.com[StackOverflow]
using the `spring-restdocs` tag. Similarly, we encourage you to help your fellow
Spring REST Docs users by answering questions.
[[contributing-bugs]]
=== Bugs
If you believe you have found a bug, please take a moment to search the
{github}/issues?is%3Aissue[existing issues]. If no one else has reported the problem,
please {github}/issues/new[open a new issue] that describes the problem in detail and,
ideally, includes a test that reproduces it.
[[contributing-enhancements]]
=== Enhancements
If you'd like an enhancement to be made to Spring REST Docs, pull requests are most
welcome. The source code is on {github}[GitHub]. You may want to search the
{github}/issues?is%3Aissue[existing issues] and {github}/pulls?q=is%3Apr[pull requests] to
see if the enhancement is already being worked on. You may also want to
{github}/issues/new[open a new issue] to discuss a possible enhancement before work on it
begins.

View File

@@ -9,9 +9,12 @@ This section describes how to get started with Spring REST docs.
=== Sample applications
If you want to jump straight in, there are two sample applications available.
{hateoas-sample}[One sample uses Spring HATEOAS] and {data-rest-sample}[the other uses
Spring Data REST]. Both samples use Spring REST Docs to produce a detailed API guide
and a getting started walkthrough. You can use either Gradle or Maven to build them.
{samples}/rest-notes-spring-hateoas[One sample] uses
http://projects.spring.io/spring-hateoas/[Spring HATEOAS] and
{samples}/rest-notes-spring-data-rest[the other] uses
http://projects.spring.io/spring-data-rest/[Spring Data REST]. Both samples use
Spring REST Docs to produce a detailed API guide and a getting started walkthrough. You
can use either Gradle or Maven to build them.
In each sample the source for the documentation can be found in `src/main/asciidoc`.
`api-guide.adoc` produces an API guide for the service. `getting-started-guide.adoc`
@@ -73,6 +76,26 @@ snippets that it generates.
then use this attribute when including the generated snippets in your documentation.
[[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. You can do so by configuring the `jar` task to depend on
the `asciidoctor` task and to copy the generated documentation into the jar's static
directory:
[source,groovy,indent=0]
----
jar {
dependsOn asciidoctor
from ("${asciidoctor.outputDir}/html5") {
into 'static/docs'
}
}
----
[[getting-started-build-configuration-maven]]
==== Maven build configuration
@@ -118,7 +141,7 @@ use as a reference. The key parts of the configuration are described below.
<executions>
<execution>
<id>generate-docs</id>
<phase>package</phase>
<phase>package</phase> <5>
<goals>
<goal>process-asciidoc</goal>
</goals>
@@ -144,13 +167,66 @@ snippets that it generates. The plugin is also configured to include files whose
with `Documentation.java`:
<4> Configure the Asciidoctor plugin and define an attribute named `snippets`. You can
then use this attribute when including the generated snippets in your documentation.
<5> [[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.
[[getting-started-build-configuration-maven-packaging]]
==== 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.
First, configure the Asciidoctor plugin so that it runs in the `prepare-package` phase, as
<<getting-started-build-configuration-maven-plugin-phase, described above>>. Now configure
Maven's resources plugin to copy the generated documentation into a location where it'll
be included in the project's jar:
[source,xml,indent=0]
----
<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>
<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 and the resource plugin must run after the Asciidoctor plugin.
[[getting-started-documentation-snippets]]
=== Generating documentation snippets
Spring REST Docs uses {spring-mvc-test-docs}[Spring's MVC Test] to make requests to the
service that you are documenting. It then produces documentation snippets for the
result's request and response.
Spring REST Docs uses {spring-framework-docs}/#spring-mvc-test-framework[Spring's MVC Test
framework] to make requests to the service that you are documenting. It then produces
documentation snippets for the result's request and response.
@@ -162,7 +238,7 @@ that creates a `MockMvc` instance:
[source,java,indent=0]
----
include::{examples-dir}com/example/ExampleApplicationTests.java[tags=mock-mvc-setup]
include::{examples-dir}/com/example/ExampleApplicationTests.java[tags=mock-mvc-setup]
----
The `MockMvc` instance is configured using a `RestDocumentationConfigurer`. An instance
@@ -173,7 +249,7 @@ sensible defaults and also provides an API for customizing the configuration. Re
[[getting-started-documentation-snippets-setup]]
[[getting-started-documentation-snippets-invoking-the-service]]
==== Invoking the RESTful service
Now that a `MockMvc` instance has been created, it can be used to invoke the RESTful
@@ -181,7 +257,7 @@ service and document the request and response.
[source,java,indent=0]
----
include::{examples-dir}com/example/InvokeService.java[tags=invoke-service]
include::{examples-dir}/com/example/InvokeService.java[tags=invoke-service]
----
<1> Invoke the root (`/`) of the service an indicate that an `application/json` response
is required

View File

@@ -1,15 +1,17 @@
= Spring REST Docs
Andy Wilkinson
:doctype: book
:icons: font
:source-highlighter: highlightjs
:toc: left
:toclevels: 3
:source-highlighter: highlightjs
:spring-mvc-test-docs: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/testing.html#spring-mvc-test-framework
:samples: https://github.com/spring-projects/spring-restdocs/tree/master/samples
:hateoas-sample: https://github.com/spring-projects/spring-restdocs/tree/master/samples/rest-notes-spring-hateoas
:data-rest-sample: https://github.com/spring-projects/spring-restdocs/tree/master/samples/rest-notes-spring-data-rest
:examples-dir: ../../test/java/
:icons: font
:sectlinks:
:examples-dir: ../../test/java
:github: https://github.com/spring-projects/spring-restdocs
:samples: {github}/tree/{branch-or-tag}/samples
:spring-boot-docs: http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle
:spring-framework-docs: http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle
[[abstract]]
@@ -21,4 +23,5 @@ include::getting-started.adoc[]
include::documenting-your-api.adoc[]
include::customizing-responses.adoc[]
include::configuration.adoc[]
include::working-with-asciidoctor.adoc[]
include::working-with-asciidoctor.adoc[]
include::contributing.adoc[]

View File

@@ -10,9 +10,9 @@ http://asciidoctor.org[Asciidoctor]. Asciidoctor processes plain text and produc
HTML styled and layed out to suit your needs.
Spring REST Docs makes use of snippets produced by tests written with
{spring-mvc-test-docs}[Spring MVC Test]. This test-driven approach helps to guarantee the
accuracy of your service's documentation. If a snippet is incorrect the test that
produces it will fail.
{spring-framework-docs}#spring-mvc-test-framework[Spring MVC Test]. This test-driven
approach helps to guarantee the accuracy of your service's documentation. If a snippet is
incorrect the test that produces it will fail.
Documenting a RESTful service is largely about describing its resources. Two key parts
of each resource's description are the details of the HTTP requests that it consumes

View File

@@ -41,9 +41,9 @@ included.
[[working-with-asciidoctor-customizing-tables-formatting-columns]]
==== Formatting columns
Asciidoctor has rich support for http://asciidoctor.org/docs/user-manual/#cols-format
[formatting a table's columns]. For example, the widths of a table's columns can be
specified using the `cols` attribute:
Asciidoctor has rich support for
http://asciidoctor.org/docs/user-manual/#cols-format[formatting a table's columns]. For
example, the widths of a table's columns can be specified using the `cols` attribute:
[source,adoc,indent=0]
----