Spring Rest Docs는 Spring MVC를 사용하는 REST API를 문서화하는데 도움을 주는 프로젝트 이다.
Spring Rest Docs는 Spring MVC의 테스트를 실행하면서 생성된 응답을 기반으로 문서를 생성합니다.
Spring Rest Docs는 Asciidoctor를 사용하여 문서를 생성합니다.
스프링 프로젝트 팀에서는 Swagger 보다 Asciidoctor를 사용하는 것을 권장하고 있다.
이전에는 Swagger를 많이 사용했다고 한다. 물론 Swagger 의 장점은 많다.
그러나 Swagger는 Spring MVC의 테스트를 실행하지 않고 문서를 생성하기 때문에 실제로 API가 동작하는지 확인할 수 없다.
Swagger는 API의 스펙을 정의하는 것이 목적이지만 Spring Rest Docs는 API의 스펙을 정의하고 테스트하는 것이 목적이다.
또한 Swagger 는 비지니스 로직 코드와 문서를 분리하기 어렵다. @ApiOperation 등 여러 어노테이션을 사용 하기 때문에
코드가 더러워지는 문제가 있다.
plugins {
...
id "org.asciidoctor.jvm.convert" version "3.3.2" // (1)
// .adoc 파일 생성을 위한 플러그인
...
}
...
// (2)
ext {
set('snippetsDir', file("build/generated-snippets"))
// snippetsDir : 테스트 실행시 생성되는 응답을 저장할 디렉토리 지정
}
// (3)
configurations {
asciidoctorExtensions
// asciidoctorExtensions : Asciidoctor의 확장 기능을 사용하기 위한 설정
}
dependencies {
// (4) rest docs 의존성 추가
testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc'
// (5) asciidoctor 의존성 추가 configration에서 지정한 의존 설정을 사용
asciidoctorExtensions 'org.springframework.restdocs:spring-restdocs-asciidoctor'
...
}
// (6) test 할 때 snippetsDir에 생성된 응답을 asciidoctor로 변환하여 .adoc 파일 생성
tasks.named('test') {
outputs.dir snippetsDir
useJUnitPlatform()
}
// (7) asciidoctor를 사용하기 위해서 asciidoctor task에 asciidoctorExtensions 설정
tasks.named('asciidoctor') {
configurations "asciidoctorExtensions"
inputs.dir snippetsDir
dependsOn test
}
// (8) asciidoctor task 실행시 생성된 html 파일을 src/main/resources/static/docs 디렉토리에 카피
task copyDocument(type: Copy) {
dependsOn asciidoctor // (8-1)
from file("${asciidoctor.outputDir}") // (8-2)
into file("src/main/resources/static/docs") // (8-3)
}
build {
dependsOn copyDocument // (9) 빌드되기전 copyDocument task 실행
}
// (10)
bootJar {
dependsOn copyDocument // (10-1) bootJar 실행되기전 copyDocument task 실행
from ("${asciidoctor.outputDir}") { // (10-2) bootJar에 asciidoctor task에서 생성된 html 파일 추가
into 'static/docs' // (10-3) bootJar에 추가될 경로
}
}
위 Gradle 설정을 통해 테스트 실행시 생성되는 응답을 snippetsDir에 저장하고, snippetsDir에 저장된 응답을 asciidoctor를 통해 .adoc 파일로 변환한다.
그리고 asciidoctor task 실행시 생성된 html 파일을 src/main/resources/static/docs 디렉토리에 카피한다.
그리고 이러한 분리된 .adoc 파일을 하나의 html 파일로 합치기 위해
main/src/docs/asciidoc/index.adoc 파일을 생성한다.
= Spring REST Docs
include::http-request.adoc[]
include::http-response.adoc[]
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
@AutoConfigureRestDocs(outputDir = "build/generated-snippets")
public class MemberControllerTest {
@Autowired
private MockMvc mockMvc;
@Test
public void getMember() throws Exception {
this.mockMvc.perform(get("/api/members/{id}", 1L))
.andExpect(status().isOk())
.andDo(document("get-member",
pathParameters(
parameterWithName("id").description("회원 ID")
),
responseFields(
fieldWithPath("id").description("회원 ID"),
fieldWithPath("name").description("회원 이름"),
fieldWithPath("email").description("회원 이메일"),
fieldWithPath("password").description("회원 비밀번호"),
fieldWithPath("createdDate").description("회원 가입일"),
fieldWithPath("modifiedDate").description("회원 정보 수정일")
)
));
}
}
테스트 All pass 시 build/generated-snippets 디렉토리에 응답이 저장된다.
gradle build 실행시 build/generated-snippets 디렉토리에 저장된 응답을 asciidoctor를 통해 .adoc 파일로 변환한다.