Documentando APIs com Spring REST Docs: Configuração
Depois de concluirmos este webinar, nós:
- Saberemos configurar um projeto (em Gradle 9 ou Maven) que gera a documentação da nossa API automaticamente durante o build.
- Compreenderemos o que é o Spring REST Docs.
- Saberemos configurar o Spring REST Docs quando estivermos usando o Spring Boot 4 e o JUnit 6 (tanto em testes unitários standalone quanto em testes de integração).
- Compreenderemos como podemos documentar nossa API REST com Spring REST Docs e Asciidoctor.
Este webinar assume que:
- Você sabe especificar o contexto de aplicação carregado pelo Spring TestContext Framework.
- Você está familiarizado com o JUnit 6.
- Você sabe criar um projeto que executa testes unitários, de integração e End-to-End com JUnit 6.
Uma Rápida Introdução ao Spring REST Docs
O Spring REST Docs é uma biblioteca que nos permite documentar uma API REST escrevendo testes automatizados para ela. O Spring REST Docs utiliza Asciidoctor por padrão (embora também seja possível usar Markdown).
Quando queremos documentar uma API REST com o Spring REST Docs, temos que seguir estes dois passos:
- Gerar os snippets que documentam o comportamento da nossa API REST: Para ser mais específico, esses snippets descrevem tanto as requisições HTTP consumidas pelos nossos recursos de API quanto as respostas HTTP retornadas por eles. Podemos gerar esses snippets utilizando o Spring MVC Test framework (
MockMvc), oWebTestClientdo Spring WebFlux ou o REST Assured. - Escrever o documento Asciidoctor (
index.adoc) que especifica a estrutura da documentação da nossa API: Quando queremos documentar nossos recursos de API, incluímos (include::...) os snippets gerados automaticamente pelo Spring REST Docs.
Agora que conhecemos o funcionamento do Spring REST Docs, vamos descobrir como declarar as dependências e plugins necessários no nosso build.
Obtendo as Dependências e Configurando o Asciidoctor no Build
Como queremos integrar o Spring REST Docs com o Spring MVC Test framework (MockMvc), temos que declarar a dependência spring-restdocs-mockmvc no escopo de teste e configurar o plugin do Asciidoctor.
Opção A: Configuração no Gradle 9 (build.gradle.kts)
No Gradle 9 com Kotlin DSL, aplicamos o plugin org.asciidoctor.jvm.convert, declaramos a configuração asciidoctorExt para o spring-restdocs-asciidoctor e configuramos o diretório de saída dos snippets:
|
|
Opção B: Configuração Equivalente no Maven (pom.xml)
Em projetos Maven, declaramos a dependência spring-restdocs-mockmvc:
|
|
E configuramos o asciidoctor-maven-plugin para ser executado na fase prepare-package gerando um documento HTML com doctype igual a book e a dependência spring-restdocs-asciidoctor:
|
|
Antes de vermos como usar o Spring REST Docs com o MockMvc, vamos dar uma rápida olhada no sistema sob teste.
Introdução ao Sistema sob Teste
Durante este webinar, escreveremos testes unitários e de integração para um método controlador simples que processa requisições GET enviadas ao caminho /api/hello. Este método simplesmente retorna a string "Hello World!" no corpo da resposta.
O código-fonte da classe HelloWorldController em Kotlin é o seguinte:
|
|
Vamos avançar e descobrir como podemos usar o Spring REST Docs quando estamos escrevendo testes unitários para este controlador.
Gerando Snippets em Testes Unitários (Standalone Setup)
Quando estamos escrevendo testes unitários para um controlador Spring MVC, configuramos o sistema sob teste usando o modo standalone (MockMvcBuilders.standaloneSetup(...)). Para integrar o Spring REST Docs com o MockMvc no modo standalone e JUnit 6, seguimos estes passos:
- Integrar o Spring REST Docs com o JUnit 6 anotando a classe de teste com
@ExtendWith(RestDocumentationExtension::class). - Adicionar uma propriedade
mockMvcà nossa classe de teste. - Criar um método
@BeforeEachque é executado antes de cada método de teste. Como estamos usando aRestDocumentationExtension, nosso método de setup recebe um parâmetro do tipoRestDocumentationContextProvider. - Implementar o método
@BeforeEachcriando um novo objetoMockMvce aplicandodocumentationConfiguration(restDocumentation). - Criar uma classe interna
@Nested(SayHello) e adicionar um método de teste que envia a requisiçãoGET /api/helloe invoca.andDo(document("say-hello"))da classeMockMvcRestDocumentation, passando o identificador único do recurso documentado ("say-hello").
Após termos escrito o método de teste que documenta o comportamento do nosso recurso de API, o código-fonte da nossa classe de teste fica assim:
|
|
Há dois pontos importantes que quero destacar:
- Por padrão, o Spring REST Docs gera os snippets Asciidoc no diretório
build/generated-snippets/<identificador-do-recurso>(no Gradle) outarget/generated-snippets/<identificador-do-recurso>(no Maven). O identificador do recurso é a string única passada ao métododocument("say-hello").- Nossa classe de teste naturalmente possui outros testes unitários (que verificam status HTTP 200 e corpo
"Hello World!"). Contudo, é uma excelente prática escrever um método de teste dedicado exclusivamente a gerar os snippets do Spring REST Docs, garantindo que cada método de teste tenha uma única responsabilidade.
Agora sabemos gerar os snippets Asciidoctor ao escrever testes unitários. Vamos avançar e descobrir como podemos gerar esses snippets ao escrever testes de integração.
Gerando Snippets em Testes de Integração (@AutoConfigureRestDocs)
Quando estamos escrevendo testes de integração para um controlador Spring MVC no Spring Boot 4, queremos configurar o sistema sob teste usando o WebApplicationContext real. Podemos integrar o Spring REST Docs com o MockMvc de forma totalmente declarativa seguindo estes passos:
- Configurar a classe de aplicação Spring Boot com
@SpringBootTest(classes = [ExampleApplication::class]). - Garantir que o Spring Boot crie e configure um objeto
MockMvcanotando a classe com@AutoConfigureMockMvc. - Garantir que o Spring REST Docs seja autoconfigurado pelo Spring Boot anotando a classe com
@AutoConfigureRestDocs. - Injetar o bean
MockMvcna nossa classe de teste e invocar.andDo(document("say-hello")).
Após termos escrito o teste de integração que documenta nosso recurso de API, o código-fonte da classe SayHelloTest fica assim:
|
|
Agora sabemos gerar os snippets tanto em testes unitários quanto em testes de integração. A seguir, descobriremos como escrever o documento Asciidoctor da nossa API.
Escrevendo a Documentação da Nossa API com Asciidoctor
Quando escrevemos a documentação da API usando o Spring REST Docs, criamos um documento Asciidoctor (src/docs/asciidoc/index.adoc no Gradle ou src/main/asciidoc/index.adoc no Maven) e incluímos os snippets gerados dentro desse documento.
Primeiro, criamos a estrutura básica do documento com uma seção chamada Resources:
|
|
Segundo, documentamos nosso recurso de API seguindo estes passos:
- Adicionar uma subseção chamada
Say Helloà seçãoResources. - Descrever a requisição HTTP que é usada para obter uma mensagem do nosso recurso de API (incluindo o snippet
curl-request.adoc). - Descrever o conteúdo da resposta HTTP retornada (incluindo o snippet
http-response.adoc).
Após termos documentado nosso recurso de API, o conteúdo do nosso arquivo Asciidoctor fica assim:
|
|
Nota: O atributo
{snippets}é configurado automaticamente pelospring-restdocs-asciidoctore aponta para o diretório raiz onde os snippets foram gerados (build/generated-snippetsoutarget/generated-snippets).
Gerando a Documentação HTML da Nossa API
Podemos gerar a documentação final da nossa API executando:
|
|
Quando executamos esse comando, o plugin do Asciidoctor processa o index.adoc junto com os snippets gerados pelos testes e cria a documentação HTML pronta em build/docs/asciidoc (no Gradle) ou target/generated-docs (no Maven).
Vamos resumir o que aprendemos neste webinar.
Resumo
Este webinar nos ensinou sete coisas:
- O Spring REST Docs gera snippets que documentam com precisão o comportamento real do recurso de API testado.
- Podemos gerar esses snippets usando o Spring MVC Test framework (
MockMvc),WebTestClientou REST Assured. - Antes de usar o Spring REST Docs com
MockMvc, devemos declarar a dependênciaspring-restdocs-mockmvcno escopo de teste. - Geramos a documentação HTML final usando o plugin do Asciidoctor (com a extensão
spring-restdocs-asciidoctor). - Ao documentar nossa API REST em testes unitários standalone, usamos
@ExtendWith(RestDocumentationExtension::class)edocumentationConfiguration(restDocumentation). - Ao documentar nossa API REST em testes de integração Spring Boot, basta anotar a classe de teste com
@AutoConfigureMockMvce@AutoConfigureRestDocs. - Geramos os snippets de um recurso invocando
.andDo(document("<identificador-do-recurso>"))da classeMockMvcRestDocumentation.