Kotlin/Kotlin | Spring 학습기록

[Kotlin] Kotlin DSL + Spring REST Docs + MockMvc 적용기 (1)

kth990303 2022. 7. 17. 12:23
반응형

현재(22.07.17.) 는 아직 Spring REST Docs에서 kotlin DSL 공식지원을 하지 않고 있는 상황이다. 

 

https://github.com/spring-projects/spring-restdocs/issues/677

 

Document how to use Spring REST Docs with the MockMVC Kotlin DSL · Issue #677 · spring-projects/spring-restdocs

Was trying to implement RestDocs MockMvc in our Kotlin project However noticed that when using the MockMvc Kotlin DSL snippets were not generated e.g. fun shouldReturnDefaultMessageKotlinDSL() { mo...

github.com

 

그럼 kotllin DSL과 함께 REST Docs 적용은 불가능한 것인가?

대신, MockMvcResultHandlersDsl 에서 제공하는 handle을 사용하면 kotlin DSL과 함께 mockMvc를 사용할 수 있다. 이렇게 하면 mockMvc에 REST Docs api 자동문서화 기능을 추가하여 kotlin DSL + REST Docs 사용이 가능해지는 것을 확인하였다.

 

이 방법은 우아한 방법은 아니라고 WilkinSona씨가 언급했다.

Yeah, that's not great. Unfortunately, the Kotlin DSL hardcodes the use of MockMvcRequestBuilders so that may be the best that can be done at the moment. -WilkinSona-

Unfortunately, the Kotlin DSL hardcodes the use of MockMvcRequestBuilders so that may be the best that can be done at the moment.

 

왜 우아하지 않다고 하는지 솔직히 잘은 모르겠지만, 아마 반복되는 코드 때문이 아닐까 예상한다. 

하지만, 아직까지 kotlin DSL + REST Docs 공식 지원을 안해주기 때문에 어쩔 수 없지 않나 싶다.

 

REST Docs를 사용하는 이유

REST Docs를 이용하면 성공하는 테스트에 한해, 자동으로 api 문서가 생성된다는 장점이 존재한다. 그리고 그 api 문서의 디자인도 우리가 설정해줄 수 있다.

 

환경세팅, .adoc 문서 생성 (디자인 설정 및 어떠한 내용을 보여줄지 세팅), 테스트 코드에 REST Docs 기능 추가.

위 세 작업만 해주면 별도의 문서를 생성할 필요 없이 REST Docs 기능이 자동으로 api 문서를 예쁘게 보여준다.

 

개인적으로는 Swagger보다 가독성이 좋다고 생각하며, 프로덕션 코드에 불필요한 어노테이션을 붙이지 않아도 된다는 점이 매력적이었다.

 

환경설정

Gradle 7 버전에서의 REST Docs를 사용하기 위해 아래와 같이 설정해주자. 이 부분은 Java 프로젝트의 환경설정과도 유사하기 때문에, 기존 자바 프로젝트에 REST Docs를 적용해봤다면 익숙할 것이다.

 

build.gradle.kts

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
    id("org.asciidoctor.jvm.convert") version "3.3.2"  // 1
}

val asciidoctorExt by configurations.creating  // 2

dependencies {
    asciidoctorExt("org.springframework.restdocs:spring-restdocs-asciidoctor")  // 2
    testImplementation("org.springframework.restdocs:spring-restdocs-mockmvc")
}

val snippetsDir by extra {
    file("build/generated-snippets")
}

tasks {
    asciidoctor {
        dependsOn(test)
        configurations("asciidoctorExt")
        baseDirFollowsSourceFile()  // 3
        inputs.dir(snippetsDir)
    }
    register<Copy>("copyDocument") {  // 4
        dependsOn(asciidoctor)
        from(file("build/docs/asciidoc/index.html"))
        into(file("src/main/resources/static/docs"))
    }
    bootJar {
        dependsOn("copyDocument")  // 5
    }
}

1. org.assciidoctor.convert 은 Gradle 7 버전부터 deprecated 되었다. 이는 gradle 7부터 플러그인을 jvm을 사용하기 때문이다. 따라서 org.asciidoctor.jvm.convert를 사용하는 것이며, 이는 아래 Spring REST Docs 공식 문서를 참고하였다.

https://docs.spring.io/spring-restdocs/docs/current/reference/html5/

 

Spring REST Docs

Document RESTful services by combining hand-written documentation with auto-generated snippets produced with Spring MVC Test, WebTestClient, or REST Assured.

docs.spring.io

 

2. asciidoctor가 이제 asciidoctorExt (Extension)을 사용하게 됐다. REST Docs api 자동문서화 기능을 적용하면 각 테스트 클래스마다 .adoc 파일들이 생긴다. 이 adoc 파일들을 html로 변환해주는 역할을 한다. 따라서 이를 Configuration으로 지정해주고, dependencies에 추가해주자.

 

3. 특정 파일에서 다른 .adoc 파일을 include하는 경우에, 이들을 동일 경로로 설정하게 해주는 역할. gradle 7부터는 이걸 추가하지 않으면 각각의 개별 경로로 .adoc 파일들을 인식하기 때문에, base 경로에선 .adoc 파일들을 인식하지 못해 api 자동 문서화된 index.html 파일이 생성되지 않게 된다. 이는 우아한테크코스 백엔드 크루, 오리의 학습 로그에서 확인하였다.

https://prolog.techcourse.co.kr/studylogs/2499

 

우아한테크코스 학습로그 저장소

우아한테크코스 크루들이 배운 내용을 기록하는 학습로그 저장소입니다.

prolog.techcourse.co.kr

 

4. ./gradlew 명령어로 생성된 .build 디렉토리의 .adoc 파일들을 src 디렉토리로 옮겨준다. 

 

5. ./gradlew copyDocument 명령어를 터미널에 입력하면 4에서 지정한 copyDocument 작업을 실행하게 해준다.

 

adoc 형식 지정 및 .adoc 생성 위치

위와 같이 작업해주었다면, 아래 디렉토리에서 adoc 형식 지정을 해주면 된다.

테스트 코드 성공 시, snippets 생성 위치 (좌) / .adoc 파일 생성 위치 (후)

이제, 기존 테스트 코드들이 성공하면 자동으로 .build 폴더에 snippets 들이 생성된다. (실패하면 생기지 않는다. REST Docs 특성이다.) 그리고, copyDocument를 build.gradle.kts에 설정해놓았으므로 src/docs/asciidoc 폴더를 만들어놓고 .adoc 파일 형식들을 작성해놓는다면, 여기에 snippets들이 옮겨져서 아래와 같이 예쁘게 문서로 보이게 될 것이다.

우아한테크코스의 지하철 미션 REST Docs 문서

 

index.adoc 세팅

우리가 REST Docs api 문서로 보여주고 싶은 것들은 아래와 같다.

  • Http Request 형식
  • Http Response 형식
  • Table of Contents 를 이용한 api 검색 간편화 (자동링크)

위 기능들을 제공해주는 방법은 .adoc 세팅을 통해 제공할 수 있다. 또한, 위 기능들을 얼마나 예쁘게 보여줄지 디자인적으로 설정하는 것도 adoc 형식 문법을 이용하면 가능하다. 아래 사진처럼 src 폴더에 docs/asciidoc 폴더를 만들어서 index.adoc을 생성해주자.

// 형식 지정
:doctype: book
:source-highlighter: highlightjs
:toc: left
:toclevels: 1
:sectlinks:

// index.html 문서에 보여줄 api 목록
== Service-Apply
include::user.adoc[]
include::application-form.adoc[]
include::assignment.adoc[]

문서를 더 가독성있게 디자인하고 싶다면 위처럼 형식을 지정해줄 수 있다.

 

1. doctype

어떤 형식으로 api 문서 타이틀을 보여줄지 설정해줄 수 있다. default는 article 이지만, 대부분 book 형식으로 많이 사용한다. 

doctype에 대한 자세한 설명은 아래 문서를 참고하자.

https://docs.asciidoctor.org/asciidoc/latest/document/doctype/

 

AsciiDoc - Document Type

A documentation page for AsciiDoc.

docs.asciidoctor.org

 

2. toc, toclevel

toc은 Table Of Content 위치 (left, right 등)를 설정해준다. 보통 left로 해놓는 것이 가독성 면에서 좋은 듯하다.

toclevel은 indent를 설정해주는 것이다.

위 사진들은 각각 left, right로 설정해놓은, toclevel 0 일때의 예시이다.

참고하여 본인이 보기에 더 가독성 좋은 toc을 선택해주도록 하자.

위 문서는 :toc:left , :toclevel: 1인 경우이다. toclevel 0일 때는 지하철역, 지하철 노선만 뜰 것이다.

toclevel 1이기 때문에 indent 1인 경우까지 테이블에 보여주는 것을 확인할 수 있다.

 

3. :sectlink:

각 api마다 간편하게 이동할 수 있도록 링크를 달아주는 기능이다. Table of Contents 에서 `지하철 노선 등록`을 클릭하면, 해당 api로 바로 이동시켜 빠르고 편리하게 볼 수 있게 해준다. 웬만해선 달아주자.

 

4. ==

html의 h2 태그와 동일하다. =은 h1으로 적용 가능. 

 

5. include::user.adoc[]

user 관련 .adoc 을 index.adoc에 지정해준 것이다. 이렇게 해주면 user 관련 api 문서를 index.adoc에 볼 수 있다.

보통 여러 도메인 관련 api를 한 문서에 보고 싶을 때 include를 사용한다. 이 작업을 해주고 싶을 때에는 위에서 언급했듯이 build.gradle.kts에 아래 코드를 꼭 넣어주어야 index.html 문서가 생성될 때 문제가 발생하지 않는다.

baseDirFollowsSourceFile()

 

더 많은 형식 문법은 아래 우아한형제들 기술 블로그를 참고하자.

https://techblog.woowahan.com/2597/

 

Spring Rest Docs 적용 | 우아한형제들 기술블로그

{{item.name}} 안녕하세요? 우아한형제들에서 정산시스템을 개발하고 있는 이호진입니다. 지금부터 정산시스템 API 문서를 wiki 에서 Spring Rest Docs 로 전환한 이야기를 해보려고 합니다. 1. 전환하는

techblog.woowahan.com

 

마치며

다음 포스팅에선 간단한 예시 코드 틀과 함께 확장함수를 이용한 중복 줄이기를 작성해볼 예정이다.

https://kth990303.tistory.com/348 여기로 이동하면 볼 수 있다.

반응형