-
[Spring] Rest-Docs 연결Backend/Spring 2023. 1. 13. 00:26
Spring-Rest-Docs
- 테스트 코드를 기반으로 Restful API 문서 작성을 돕는 도구
- Asciidoctor를 사용하여 HTML 등 다양한 포맷으로 문서를 자동 출력할 수 있다.
- API Spec과 문서화를 위한 테스트 코드가 일치하지 않으면, 테스트 빌드를 실패하게 되어 테스트 코드로 검증된 문서임을 보장할 수 있다.
Swagger
- @ApiOperation 등 코드에는 영향을 주지 않지만, Swagger를 위해서 지속적으로 추가 코드를 작성해야 한다.
- 명세를 위한 코드들이 너무 많아 가독성이 떨어질 수 있다.
- 구조가 변경되었을 때, 명세도 같이 변경하지 않으면 초기 명세와 달라질 가능성이 존재한다.
프로젝트를 진행하면서, API 문서 자동화를 위해 Swagger와 Spring-Rest-Docs 중 고민하다 위와 같은 이유로 Spring-Rest-Docs를 선택하였다.
실습
환경: SpringBoot 2.7.5
1. build.gradle 세팅
plugins { id 'org.asciidoctor.jvm.convert' version '3.3.2' } configurations { asciidoctorExtensions } ext { set('snippetsDir', file("build/generated-snippets")) } dependencies { asciidoctorExtensions 'org.springframework.restdocs:spring-restdocs-asciidoctor' testImplementation 'org.springframework.restdocs:spring-restdocs-webtestclient' } test { outputs.dir snippetsDir } asciidoctor { inputs.dir snippetsDir sources { include '**/api-docs.adoc' } configurations 'asciidoctorExtensions' dependsOn test baseDirFollowsSourceFile() } task copyDocument(type: Copy) { dependsOn asciidoctor from file("build/docs/asciidoc") into file("src/main/resources/static/docs") } bootJar { dependsOn copyDocument }
- 기존 build.gradle에 위와 같은 코드를 추가한다.
- 테스트 코드 실행 및 성공 시, snippetsDir로 설정한 경로에 아래와 같은 .adoc파일이 생성된다.
- curl-request.adoc
- http-request.adoc
- http-response.adoc
- httpie-request.adoc
- request-body.adoc
- response-body.adoc
- 프로젝트 build 시, asciidoctor 과정이 실행되어 src/docs/asciidoc 경로의 api-docs.adoc을 기반으로 html 파일을 /build/docs/asciidoc 경로에 생성한다.
- copyDocument 과정에서 생성된 html을 src/main/resources/static/docs로 복사한다.
2. 테스트 코드 작성
@ExtendWith(RestDocumentationExtension.class) class ControllerTest { @BeforeEach void setUp(ApplicationContext applicationContext, RestDocumentationContextProvider restDocumentation) { this.webTestClient = WebTestClient.bindToApplicationContext(applicationContext).configureClient() .filter(documentationConfiguration(restDocumentation)) .build(); } @Test @DisplayName("테스트") void 테스트() throws Exception { // given User testUser = TestProvider.createTestUser(); LinkedMultiValueMap<String, String> formData = new LinkedMultiValueMap<>(); formData.put("email", List.of(testUser.getEmail())); formData.put("password", List.of(testUser.getPassword())); formData.put("name", List.of(testUser.getName())); formData.put("nickname", List.of(testUser.getNickname())); formData.put("age", List.of(testUser.getAge().toString())); formData.put("gender", List.of(testUser.getGender())); // when & then webTestClient.post() .uri("/api/v1/auth/sign-up") .body(BodyInserters.fromFormData(formData)) .exchange() .expectStatus().isCreated() .expectBody() .jsonPath("code").isEqualTo(201) .consumeWith(document("snippets 생성 경로", requestParameters( parameterWithName("email").description("이메일").attributes(field("example", testUser.getEmail()), field("length", "0-20")), parameterWithName("password").description("비밀번호").attributes(field("example", testUser.getPassword()), field("length", "10-15")), parameterWithName("name").description("이름").attributes(field("example", testUser.getName())), parameterWithName("nickname").description("닉네임").attributes(field("example", testUser.getNickname())), parameterWithName("age").description("나이").attributes(field("example", String.valueOf(testUser.getAge()))), parameterWithName("gender").description("성별").attributes(field("example", testUser.getGender())) ))) .consumeWith(System.out::println); } }
- @ExtendWith(RestDocumentationExtension.class)를 테스트 클래스에 적용한다.
- setUp 메서드를 사용하여, WebTestClient에 Rest-Docs를 사용할 수 있도록 적용한다.
- document()를 사용해서 설정한 내용을 바탕으로 .adoc 파일을 snippets 생성 경로에 생성한다.
- build/generated-snippets/{지정한 경로}에 위와 같은 .adoc 파일이 생성된 것을 확인할 수 있다.
3. api-docs.adoc 파일 작성
operation::{파일 경로}[snippets='http-request,request-parameters,response-body']
- build/generated-snippets 아래의 파일 경로를 적용한 뒤, 위에서 생성된 .adoc 파일 중 사용하고 싶은 파일을 snippets=''에 작성한다.
- AsciiDoc 플러그인을 사용하면, 다음과 같은 파일 결과를 미리 볼 수 있다.
4. project build
- 터미널에 ./gradlew clean build 명령어를 입력한 뒤, resources/static/docs/api-docs.html 파일을 확인하면 다음과 같은 결과를 확인할 수 있다.
'Backend > Spring' 카테고리의 다른 글
[Spring] checkstyle 적용하기 (0) 2023.05.03 DDD(Domain Driven Design)란? (1) 2023.04.03 [Spring] 알림 기능에 SSE 적용하기 (0) 2022.11.25 [Spring] Logback 설정 (0) 2022.11.16 [Slf4j] Slf4j란? (0) 2022.09.19