구현하기
구현 순서는 아래와 같다.
- restdocs-api-spec을 이용한 OAS 파일을 생성하는 빌드 환경 구축
- Swagger-UI standalone, Static Routing 세팅
- 생성된 OAS 파일을 Swagger 디렉터리로 복사(copyOasToSwagger)
- SampleController 및 MockMvc REST Docs Test 코드 작성
- 결과 확인
사용 기술
- Spring Boot 3.3.0 / gradle-kotlin
- Java 17
- restdocs-api-spec
1. restdocs-api-spec을 이용한 OAS 파일을 생성하는 빌드 환경 구축
1-1. 의존성 추가
아래처럼 의존성을 추가해준다.
// build.gradle.kts
plugins {
... 생략
id("com.epages.restdocs-api-spec") version "0.15.3"
}
repositories {
mavenCentral()
}
dependencies {
... 생략
// Rest Docs
testImplementation("org.springframework.restdocs:spring-restdocs-mockmvc")
testImplementation("org.springframework.restdocs:spring-restdocs-asciidoctor")
testImplementation("com.epages:restdocs-api-spec-mockmvc:0.17.1")
... 생략
}
openapi3 {
this.setServer("https://localhost:8080") // list로 넣을 수 있어 각종 환경의 URL을 넣을 수 있음!
title = "My API"
description = "My API description"
version = "0.1.0"
format = "yaml" // or json
}
1-2. task 확인
의존성을 추가하고 gradle의 tasks를 보면 아래 사진처럼 openapi3 과 같은 task가 추가돼있다.
여기서 openapi3 task를 실행해보면 아래 사진처럼 build/api-spec 경로에 openapi3.yaml 파일이 생성된다.
openapi3.yaml 파일을 보면 아래와 같다.
2. Swagger-UI standalone, 리소스 핸들러 설정
2-1. Swagger-ui 정적 파일 설치
위 사진은 Swagger-ui 정적 파일 설치 사이트 하단의 설명이다.
위 페이지에서 latest release 를 다운 받는 링크로 이동하여 압축 파일을 받아준다.
2-2. 스프링부트의 정적 파일 경로에 추가
압축을 해제하면 아래 사진처럼 나오는데, 여기서 /dist 의 내용물만 필요하다.
/dist 내용물을 아래 사진처럼 스프링부트의 /resources/static/swagger-ui 로 옮겨준다.
2-3. 파일명 변경 및 불필요한 파일 제거
index.html 은 swagger-ui.html 로 파일명을 변경하였다.
또한 불필요한 파일들은 삭제해주었다.
- oauth2-redirect.html
- swagger-ui.js
- swagger-ui-es-bundle-core.js
- swagger-ui-es-bundle.js
2-4. swagger-initializer.js 파일의 url 수정
swagger-initializer.js의 코드를 보면 아래 사진과 같다.
1-2 에서는 openapi3 task 를 돌리면 OAS 파일이 생성됐지만, 최종적으로는
Spring Rest Docs와 연동하여 빌드 시 테스트 코드를 돌릴 때 OAS 파일을 만들게 될것이다.
swagger-initializer.js에서 OAS 파일을 읽어 API 시각화를 하기 때문에 이를 우리가 만들 OAS 파일을 참조하도록 수정한다.
여기서 url 부분을 수정하여 우리가 만들 OAS 파일을 참조하도록 한다.
Swagger-initializer.js
2-5. 리소스 핸들러 설정
브라우저에서 스프링부트 애플리케이션 서버의 /static/swagger-ui 경로에 있는 정적 파일에 접근하기 위해서는
리소스 핸들러 설정을 바꿔줘야 한다.
(사실 이 부분은 2-4 에서 url 을 /static/swagger-ui/openapi3.yaml 으로 했을때는 필요했는데
본인은 url을 /swagger-ui/openapi3.yaml로 설정해서 굳이 필요 없을것 같기는 하다.)
@Configuration
public class AppConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
}
}
3. 생성된 OAS 파일을 Swagger 디렉터리로 복사(copyOasToSwagger)
1-2에서 openapi3 task를 실행하면 build/api-spec 경로에 openapi3.yaml 파일이 생성되는걸 확인했다.
이걸 2에서 생성한 /static/swagger-ui 경로에 넣고 swagger-ui.html로 읽을 것이다.
build.gradle.kts에 아래 코드를 추가하여 이를 위한 task를 추가한다.
// build.gradle.kts
tasks.withType<Test> {
useJUnitPlatform()
// 기존에 있는 test 쪽에 이 코드를 추가
finalizedBy("copyOasToSwagger") // test 후 copyOasToSwagger task 진행
}
val buildDir = layout.buildDirectory.get().asFile
tasks.register<Copy>("copyOasToSwagger") {
dependsOn("openapi3") // openapi3 Task가 먼저 실행되도록 설정
delete("src/main/resources/static/swagger-ui/openapi3.yaml") // 기존 OAS 파일 삭제
from("$buildDir/api-spec/openapi3.yaml") // 복제할 OAS 파일 지정
into("src/main/resources/static/swagger-ui/") // 타겟 디렉터리로 파일 복제
}
tasks {
bootJar {
// openapi3.yaml 파일을 /static/swagger-ui 경로로 복사에 성공한 후 bootJar 진행
dependsOn("copyOasToSwagger")
from("build/api-spec") {
into ("BOOT-INF/classes/static/swagger-ui")
}
}
}
위 코드를 추가하고 빌드나 테스트를 돌려서 로그를 살펴보면 아래처럼 task 를 진행함을 확인할 수 있다.
test -> openapi3 -> copyOasToSwagger -> bootJar -> build 의 순서로 task 를 진행한다.
4. Sample Controller 코드 및 Rest Docs 테스트 작성
간단하게 테스트용으로 컨트롤러를 작성하였다.
TestController
@RestController
@RequestMapping("/hi")
public class TestController {
@GetMapping("/hi1")
public String test() {
return "hi1";
}
@GetMapping("/hi2")
public String test2() {
return "hi2";
}
}
TestControllerTest
Spring Rest Docs는 MockMvc 와 결합해서 동작한다.
컨트롤러 테스트 코드를 작성할 때 아래 두 가지를 목적에 맞게 사용해야 한다.
- Rest Docs 사용- MockMvcRestDocumentation.document
- Swagger 사용 - MockMvcRestDocumentationWrapper.document
본인은 Rest Docs는 사용하지 않고 Swagger 용도로만 사용하였다.
어떤 메서드를 사용하는지 참고하기 쉽도록 패키지까지 올려두었다.
package com.example.dream;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.restdocs.RestDocumentationExtension;
import org.springframework.test.web.servlet.MockMvc;
import static com.epages.restdocs.apispec.MockMvcRestDocumentationWrapper.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@SpringBootTest
@AutoConfigureMockMvc
@AutoConfigureRestDocs
@ExtendWith(RestDocumentationExtension.class)
class TestControllerTest {
@Autowired
private MockMvc mockMvc;
@DisplayName("")
@Test
void test() throws Exception {
mockMvc.perform(get("/hi/hi1")
.accept(MediaType.APPLICATION_JSON)
)
.andDo(print())
.andExpect(status().isOk())
.andDo(document("나는짱1"));
}
@DisplayName("")
@Test
void test2() throws Exception {
mockMvc.perform(get("/hi/hi2")
.accept(MediaType.APPLICATION_JSON)
)
.andDo(print())
.andExpect(status().isOk())
.andDo(document("나는짱2"));
}
}
5. 결과 확인
아래 사진처럼 Production 코드를 침투하지 않고도 Swagger 의 API Test가 가능하다.
또한 Spring Rest Docs 의 테스트 코드를 통한 유지 보수성 또한 확보 되었다.
위 결과는 빌드하고 java -jar 명령어로 실행해본 결과이다.
배포 환경에서는 서버 URL 설정을 변경해줘야할 수 있다.
그때는 build.gradle.kts 의 openapi3 쪽의 서버 URL을 변경해주자.
혹은 주석 달려있는것 처럼 List 형태로 넣어서 여러개의 URL을 사용해도 될듯 하다.
yml 파일로 동적으로 이용할 수 있는 방법도 있을듯 하니 추후 사용할 때 가볍게 정리할것 같다.
참고자료
OpenAPI Specification을 이용한 더욱 효과적인 API 문서화 | 카카오페이 기술 블로그
사실상의 표준으로 발돋움 중인 OpenAPI Specification을 이용한 API 문서화 방법(Swagger와 Spring REST Docs의 장점을 합치는 방법)을 공유드립니다.
tech.kakaopay.com
내가 만든 API를 널리 알리기 - Spring REST Docs 가이드편
'추석맞이 선물하기 재개발'에 차출되어 API 문서화를 위해 도입한 Spring REST Docs 를 소개합니다.
helloworld.kurly.com
[리팩토링] Swagger UI + Spring RestDocs 적용기
Swagger UI 와 Spring RestDocs 의 장 단점의 비교Swagger UI 의 장점직관적인 UI스웨거는 API 에 대한 요청과 응답 등을 시각적으로 표현하여 사용자가 쉽게 이해할 수 있습니다실시간 테스트API 엔드포인트
oth3410.tistory.com
'API 만들어 보기 > API 문서 자동화' 카테고리의 다른 글
API 문서 자동화 1: Spring Rest Docs vs Swagger 장단점 비교 (0) | 2024.06.11 |
---|---|
스웨거 사용해보기 4: API 인증 필요 여부 개별 관리 (0) | 2024.05.15 |
스웨거 사용해보기 3: SwaggerConfig에 서버 설정 (0) | 2024.05.03 |
스웨거 사용해보기 2: API 인증 필요 여부 표기 (0) | 2024.05.02 |
스웨거 사용해보기 1: 기본 설정 (0) | 2024.05.01 |