skip to content

Spring REST Docs

REST Docs captures request and response snippets from passing tests and assembles them into API documentation, so the docs cannot drift from the code. Interviewers contrast it with OpenAPI generation and ask which failure mode you prefer.

part ofSpring Frameworkoverview, primer and where to startread it →
on this pageshow

questions

5

What is Spring REST Docs, and how do you enable it and produce a documentation snippet from a MockMvc test?

level: juniorimportance: must knowfreq 55%

answer

  1. @AutoConfigureRestDocs on the slice test
  2. andDo(document("identifier"))
  3. build/generated-snippets
  4. snippets only on passing test
  5. Asciidoctor include:: renders final HTML

basics

~10 s

Spring 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 s

Spring 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 lines
java
import 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

for a junior

Know the three moves: @AutoConfigureRestDocs, andDo(document("id")), and that snippets live under build/generated-snippets.

for a middle

Explain the test-driven-docs philosophy and that the Asciidoctor plugin renders included snippets into HTML.

for a senior

Contrast with annotation/runtime approaches, know the manual RestDocumentationExtension wiring, and the default snippet set.

for a principal

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

context

open as a page

How do you document request and response fields with Spring REST Docs, and what happens if you leave a field undocumented?

level: middleimportance: must knowfreq 50%

basics

~10 s

Use PayloadDocumentation.responseFields(fieldWithPath("name").description("...")) inside document(). REST Docs is strict: if a field in the payload isn't documented (or a documented field is missing), the test fails, so docs stay complete.

open as a page

What are operation preprocessors in Spring REST Docs, and how do you use them to clean up captured snippets?

level: seniorimportance: should knowfreq 38%

basics

~10 s

Preprocessors transform the captured request/response before snippets are written — e.g. Preprocessors.prettyPrint() to format JSON, removeHeaders(...) to drop noise, maskLinks() to hide URIs. You attach them with document(id, preprocessRequest(...), preprocessResponse(...), snippets...).

open as a page

How does Spring REST Docs work with WebTestClient for a reactive/WebFlux application, and how does it differ from the MockMvc integration?

level: seniorimportance: should knowfreq 28%

basics

~10 s

Use the spring-restdocs-webtestclient module. Configure WebTestClient with WebTestClientRestDocumentation.documentationConfiguration, then call .consumeWith(WebTestClientRestDocumentation.document("id", ...)) on the response. Same snippets and descriptors as MockMvc, just a different entry-point class.

open as a page

At scale, how do you keep Spring REST Docs maintainable — reducing per-test boilerplate, keeping constraints/docs in sync, and what tradeoffs does the test-driven-docs approach carry?

level: principalimportance: should knowfreq 22%

basics

~20 s

Centralize preprocessors and URI config as defaults, extract reusable snippet/descriptor helpers, drive validation docs from Bean Validation via ConstraintDescriptions, and use snippet templates for consistency. The tradeoff: docs require and depend on maintained tests, and drift breaks the build (intentionally).

open as a page