What is Spring REST Docs, and how do you enable it and produce a documentation snippet from a MockMvc test?
answer
- @AutoConfigureRestDocs on the slice test
- andDo(document("identifier"))
- build/generated-snippets
- snippets only on passing test
- Asciidoctor include:: renders final HTML
basics
~10 sSpring REST Docs generates API documentation from passing tests. You add @AutoConfigureRestDocs to a @WebMvcTest, then call MockMvc's perform(...).andDo(document("identifier")) to capture the request and response as reusable snippets.
solid answer
~40 sSpring REST Docs is a test-driven documentation tool: instead of hand-writing docs (or reflecting over annotations), it captures the actual request and response of a passing MockMvc/WebTestClient/REST Assured test and writes Asciidoctor snippets (curl-request.adoc, http-request.adoc, http-response.adoc, etc.) into build/generated-snippets. You enable the auto-configuration with @AutoConfigureRestDocs on a slice test such as @WebMvcTest, which wires a RestDocumentationRequestBuilder and configures MockMvc. In the test you statically import MockMvcRestDocumentation.document and add .andDo(document("users-get")) after the assertions. The "users-get" identifier becomes a folder under generated-snippets. You then include those snippets in a hand-written .adoc file using Asciidoctor include:: directives, and the asciidoctor Gradle/Maven plugin renders the final HTML. Because the snippets only exist if the test passed, the docs stay honest.
code
java · 20 linesimport static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@WebMvcTest(UserController.class)
@AutoConfigureRestDocs
class UserControllerDocsTest {
@Autowired MockMvc mockMvc;
@MockBean UserService userService;
@Test
void getUser() throws Exception {
given(userService.find(1L)).willReturn(new User(1L, "Ada"));
mockMvc.perform(get("/users/{id}", 1))
.andExpect(status().isOk())
.andDo(document("users-get")); // writes build/generated-snippets/users-get/*.adoc
}
}go deeper
Know the three moves: @AutoConfigureRestDocs, andDo(document("id")), and that snippets live under build/generated-snippets.
Explain the test-driven-docs philosophy and that the Asciidoctor plugin renders included snippets into HTML.
Contrast with annotation/runtime approaches, know the manual RestDocumentationExtension wiring, and the default snippet set.
Frame it as a documentation-accuracy strategy and integrate the snippet lifecycle into the CI/build pipeline.
**What it is.** Spring REST Docs is a library from the Spring team that produces accurate REST API documentation by *observing real tests*. The philosophy is "test-driven docs": documentation is generated only from tests that pass, so if the API drifts from the docs, the test fails and the build breaks. This is the opposite of runtime-annotation approaches — REST Docs is out of scope for OpenAPI/live contracts; it emits **Asciidoctor** (or optionally Markdown) text snippets. **Core pieces.** - `@AutoConfigureRestDocs` — a Spring Boot test annotation (from `spring-boot-test-autoconfigure`) that turns on REST Docs auto-configuration for a slice test like `@WebMvcTest` or `@SpringBootTest`. It registers the `RestDocumentationContextProvider`/JUnit 5 `RestDocumentationExtension` for you and configures the `MockMvc` bean so captured output lands under the generated-snippets directory. You can override the output dir: `@AutoConfigureRestDocs(outputDir = "target/snippets")`. - `MockMvcRestDocumentation.document(String identifier, Snippet... snippets)` — a `ResultHandler` you pass to `.andDo(...)`. On a passing test it writes the snippet `.adoc` files. The `identifier` names the sub-directory (supports `{method-name}` templating for uniqueness). - **Default snippets** written for every `document(...)` call: `curl-request.adoc`, `httpie-request.adoc`, `http-request.adoc`, `http-response.adoc`, `request-body.adoc`, `response-body.adoc`. - **Output directory**: by default `build/generated-snippets` (Gradle) or `target/generated-snippets` (Maven). **Minimal flow.** 1. Add the `spring-restdocs-mockmvc` dependency and the Asciidoctor build plugin. 2. Annotate the test class with `@WebMvcTest(UserController.class)` + `@AutoConfigureRestDocs`. 3. In the test: `mockMvc.perform(get("/users/1")).andExpect(status().isOk()).andDo(document("users-get"));` 4. Write `src/docs/asciidoc/api.adoc` that pulls snippets in with `include::{snippets}/users-get/curl-request.adoc[]`. 5. Run the build — Asciidoctor renders `api.html`. **Manual (non-Boot) setup.** Without Boot you wire it yourself: a JUnit 5 `@ExtendWith(RestDocumentationExtension.class)` field, then in `@BeforeEach` build MockMvc with `MockMvcBuilders.webAppContextSetup(context).apply(MockMvcRestDocumentation.documentationConfiguration(restDocumentation)).build()`. `@AutoConfigureRestDocs` just does this for you. **Gotchas.** - Snippets are written **only when the test passes** (assertions succeed). A failing assertion means no snippet — that's by design. - `document(...)` must come after your `andExpect(...)` matchers so it documents what you actually asserted. - The generated-snippets directory must be wired to the Asciidoctor plugin (via the `snippets` attribute) or your includes won't resolve. - REST Docs documents HTTP wire format, not Java signatures; you describe request/response *fields*, headers, path/query params — not method parameters. **When to use.** Choose REST Docs when you want documentation that is provably in sync with behavior and you're comfortable maintaining a hand-authored narrative .adoc that stitches snippets together. It complements existing controller tests rather than adding a separate doc build step.
- Where do the generated snippets go and how do they reach the final HTML?By default build/generated-snippets (Gradle) or target/generated-snippets (Maven). A hand-written .adoc file includes them with include::{snippets}/users-get/http-response.adoc[], and the Asciidoctor build plugin renders the .adoc into HTML/PDF.
- Why must document() run only on a passing test?That's the whole point: snippets are produced from real, asserted behavior, so if the API changes and the test fails, no (or wrong) docs are generated and the build breaks — keeping docs and code in sync.
saying these in an interview costs you the question
- Thinking REST Docs scans annotations at runtime like Swagger/OpenAPI instead of capturing test output
- Believing snippets are generated even when the test fails
- Assuming @AutoConfigureRestDocs alone produces HTML without an Asciidoctor build plugin and include directives