지난 포스트들의 결과로 Spring Rest Docs 를 적용하였다.
하지만...장점이 있으면 단점도 있는 법 테스트 중심의 API 문서화의 결과로 완성된 API 문서는 기존 계속 사용해왔던 Swagger-UI 처럼 사용자 친화적? 이지 않다.
필자의 개인적인 생각으로는 별로 이쁘지도 않고 API를 호출해 테스트도 할 수 없다.
그래서 위 두 기능을 합칠 순 없을까 하고 구글링을 하던 와중 많은 레퍼런스가 있어 적용해 보려한다.
Spring Rest Docs 로 작성된 문서를 Swagger-UI 가 읽을 수 있도록 해보자
ePages-de/restdocs-api-spec : Spring Rest Docs 의 테스트코드를 활용해 OpenAPI(Swagger 3.0) 의 결과를 만들어주는 오픈소스 라이브러리 입니다.
Spring Rest Docs 의 스펙을 따라가기위해 "MockMvc, WebTestClient, RestAssured" 모두 지원한다고 합니다.
기존의 adocs 문서를 만들기 위한 코드는 삭제 후 진행했습니다.
Spring Rest Docs 와 Swagger-UI 연동을 위한 코드만 집중해 작성했습니다.
plugins {
id 'java'
id 'org.springframework.boot' version '3.0.6'
id 'io.spring.dependency-management' version '1.1.0'
id "org.asciidoctor.jvm.convert" version "3.3.2"
id 'com.epages.restdocs-api-spec' version '0.17.1'
id 'org.hidetake.swagger.generator' version '2.18.2'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
asciidoctorExt
}
repositories {
mavenCentral()
}
dependencies {
...
//restdocs-api-spec 의존성 추가
testImplementation 'com.epages:restdocs-api-spec-mockmvc:0.17.1'
asciidoctorExt 'org.springframework.restdocs:spring-restdocs-asciidoctor'
testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc'
testImplementation 'com.squareup.okhttp3:mockwebserver'
...
}
openapi3 {
server = "http://localhost"
title = "카카오인증 관리자 서버 API 문서"
description = "Spring REST Docs with SwaggerUI."
version = "0.0.1"
outputFileNamePrefix = 'open-api-3.0.1'
format = 'json'
// /static/docs/open-api-3.0.1.json 생성 → jar 파일만 배포할 예정이기에 build 에 출력
outputDirectory = 'build/resources/main/static/docs'
}
// Task 및 설정 추가
// GenerateSwaggerUI 태스크가, openapi3 task 를 의존하도록 설정
tasks.withType(GenerateSwaggerUI).configureEach {
dependsOn 'openapi3'
// 기존 파일 삭제했다가, build 에 출력한 json 정적파일 복사 (안해도 됨 → local 확인용)
delete file('src/main/resources/static/docs/')
copy {
from "build/resources/main/static/docs"
into "src/main/resources/static/docs/"
}
}
// 테스트를 통해 생성된 snippets 출력 위치 정의
tasks.register("ext") {
snippetsDir = file('build/generated-snippets')
}
tasks.named('test') {
useJUnitPlatform()
// test 스니펫 디렉터리를 출력으로 추가하도록 작업을 구성
outputs.dir 'snippetsDir'
}
// 기존에 존재하던 docs 삭제
asciidoctor.doFirst {
delete file('src/main/resources/static/docs')
}
// asciidoctor 작업을 구성
tasks.named("asciidoctor") {
inputs.dir 'snippetsDir'
configurations 'asciidoctorExt'
dependsOn test
}
tasks.named("bootJar") {
dependsOn asciidoctor
from("${asciidoctor.outputDir}") {
into 'static/docs'
}
dependsOn(':openapi3')
}
tasks.register('copyDocument', Copy) {
dependsOn asciidoctor
from file("$buildDir/docs/asciidoc")
into file("src/main/resources/static/docs")
}
tasks.named("build") {
dependsOn copyDocument
}
위 build-gradle
에 설정한 openapi3 설정에 대한 설명을 하고 넘어가겠습니다.
위 설정은 openapi3 로 openapi3 스펙을 만들때 필요한 부가정보들을 설정한 부분이며
openapi3 {
server = "서버주소(API 호출 테스트 시 이 주소 사용)"
title = "API 문서 제목"
description = "API 문서 설명 부분"
version = "API 문서 버전"
outputFileNamePrefix = '결과로 나오게 될 fomat형식 파일의 접두사'
format = 'API 문서 출력 포맷 (default: JSON)'
// /static/docs/open-api-3.0.1.json 생성 → jar 파일만 배포할 예정이기에 build 에 출력
outputDirectory = 'format형식으로 변환 된 파일을 저장 할 디렉토리 경로'
}
세세한 설정들이 몇개 있지만 변경을 최소화 하기 위해 패키지 설정만 바꿔주었다.
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static com.epages.restdocs.apispec.MockMvcRestDocumentationWrapper.document;
import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders;
위와같이 변경 후 clean -> build 작업을 하게되면 위에 설정한 경로에 format형식의 파일이 생성된 걸 확인할 수 있을 것 이다.
의존성을 추가해 적용해보자...!
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.2'
의존성 설정 후 애플리케이션을 실행시켜 "http://localhost:8080/docs/swagger-ui/index.html" 로 접속해 기본 페이지가 렌더링 된다면 성공!
implementation 'org.springdoc:springdoc-openapi-ui:1.7.0'
를 사용해보자하지만 우린 만들어둔 파일이 있다...! 기본 페이지가 아닌 생성한 파일을 읽도록 설정해보자
application.yaml 파일에서 간단한 설정을 할 수 있습니다.
swagger-ui.url : swagger-ui가 읽은 파일 경로
swagger-ui.path : swagger-ui 띄울 url 변경 → 이러면 "http://localhost:8080/docs/swagger" 를 통해 문서를 불러올 수 있습니다.
application.yml
springdoc:
default-consumes-media-type: application/json;charset=UTF-8
default-produces-media-type: application/json;charset=UTF-8
swagger-ui:
url: /docs/open-api-3.0.1.json
path: /docs/swagger
기본적인 설정은 이제 끝났습니다.
위 설정까지 마친 후 url 접속 시 Spring Rest Docs 로 생성한 문서를 Swagger-UI 를 통해 볼 수 있게 됩니다.
설정이 90% 인 것같은 느낌적인 느낌... 그래도 많이 설정하다보면 익숙해 지겠지...?
현업에서 진행하는 프로젝트에 적용시켜 보았지만 아직 뭔가 부족하다 좀 더 공부하자!
https://github.com/ePages-de/restdocs-api-spec
https://thalals.tistory.com/433
https://helloworld.kurly.com/blog/spring-rest-docs-guide/