RestDoc과 Swagger 함께 사용하기 :: 잡다한 프로그래밍
반응형

1. RestDoc이란

  • 테스트 코드 기반으로 Restful API 문서를 돕는 도구입니다.
  • Asciidoctor를 이용해서 HTML 등등 다양한 포맷으로 문서를 자동으로 출력할 수 있습니다.
  • RestDocs의 가장 큰 장점은 테스트 코드 기반으로 문서를 작성한다는 점입니다.
  • API Spec과 문서화를 위한 테스트 코드가 일치하지 않으면 테스트 빌드를 실패하게 되어 테스트 코드로 검증된 문서를 보장할 수 있습니다.

장점

  • 테스트 코드가 통과해야만 문서가 생성되므로 API 문서의 신뢰도가 높다
  • API 문서 주석이 비즈니스 코드에 묻어나지 않는다.(swagger의 흔한 단점)
  • 커스텀이 자유롭다

 

단점

  • API 테스트 코드가 추가되면 문서 조각(Asciidoc snippet)을 합쳐주는 작업이 필요하다.
  • Swagger 처럼 직접 API 테스트를 해볼 수 없고, 문서 가독성이 떨어진다. (디자인이 구림)
  • 설정 복잡함

테스트 코드 예시

    private MockMvc mockMvc;

    @BeforeEach
    void setUp(WebApplicationContext context, RestDocumentationContextProvider restDocumentation) {
        this.mockMvc = MockMvcBuilders.webAppContextSetup(context)
                .apply(MockMvcRestDocumentation.documentationConfiguration(restDocumentation))
                .build();
    }

    @Test
    void order() throws Exception {
        mockMvc.perform(get("/api/v1/order")
                        .param("test", "testValue")
                )
                .andExpect(status().isOk())
                .andDo(document("order Test",
                        preprocessRequest(prettyPrint()),
                        preprocessResponse(prettyPrint()),
                        resource(ResourceSnippetParameters.builder()
                                .tag("User API")
                                .summary("소셜 로그인 API")
                                .queryParameters(
                                        parameterWithName("test").description("테스트 파라미터"))
                                .responseFields(
                                        fieldWithPath("test").type(STRING).description("테스트 값"))
                                .requestSchema(Schema.schema("FormParameter-socialLogin"))
                                .responseSchema(Schema.schema("UserResponse.Login"))
                                .build())));
    }

 

RestDoc 결과 화면

2. Swagger란

  • Rest API를 편리하게 문서화 해주는 도구입니다.
  • 제 3의 사용자는 문서에서 직접 API 호출 테스트를 진행할 수 있습니다.

장점

  • 실시간으로 문서에서 API를 호출해보고, 응답 결과를 즉시 확인할 수 있음
  • 어노테이션으로 간편하게 API문서를 만들 수 있음 (장점이자 단점)
  • UI/UX 우수함
  • 비교적 설정 간단

 

단점

  • 비즈니스로직에 주석이 많아져서, 복잡해짐

  • 코드와 문서 사이에 불일치가 발생할 수 있음 (어노테이션동작이기 때문에)

3. RestDoc + Swagger

RestDoc의 장점과, Swagger의 장점만 모두 사용해보자

 

동작 개념

  1. RestDoc을 이용했던 것 처럼 테스트 코드를 통해 docs 문서를 생성
  2. docs 문서를 OpenAPI3 스펙으로 변환 (springdoc-openapi 라이브러리를 통해)
  3. 만들어진 OpenAPI3 스펙을 SwaggerUI로 생성
  4. 생성된 SwaggerUI를 static 패키지에 복사 및 정적리소스로 배포

 

적용방법

gradle

buildscript {
    ext {
        restdocsApiSpecVersion = '0.18.2'
    }
}

plugins {
    id 'java'
    id 'org.springframework.boot' version '3.4.4'
    id 'io.spring.dependency-management' version '1.1.7'
    // REST Docs 테스트 결과(문서조각)을 바탕으로 openapi(openapi3.yaml)을 자동 생성하는 플러그인
    id 'com.epages.restdocs-api-spec' version "${restdocsApiSpecVersion}"
}

group = 'com.run'
version = '0.0.1-SNAPSHOT'

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(21)
    }
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-security'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testImplementation 'org.springframework.security:spring-security-test'
    testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
    // rest docs 기본 라이브러리
    testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc'
    // rest docs와 openapi spec 플러그인을 연결해주는 Adapter
    testImplementation "com.epages:restdocs-api-spec-mockmvc:${restdocsApiSpecVersion}"
}

// yaml파일 생성
openapi3 {
    server = 'http://localhost:8080'
    title = "RF API"
    description = "RF API description"
    version = "0.1.0"
    format = "yaml"
}

// openapi.yaml 생성 + 정적 리소스 위치로 복사
tasks.register('copyOasToSwagger', Copy) {
    from layout.buildDirectory.file("api-spec/openapi3.yaml")
    into layout.projectDirectory.dir("src/main/resources/static/swagger-ui") // JAR 내 포함될 정적 리소스 경로
}

// 빌드 전에 swagger 파일 복사
tasks.named('build') {
    dependsOn("openapi3", "copyOasToSwagger")
}

// 수동 실행용 문서 생성 task (test + openapi3 + copy까지)
tasks.register('generateSwaggerDoc') {
    group = "documentation"
    description = "Generate OpenAPI YAML and copy to static folder"
    dependsOn("test", "openapi3", "copyOasToSwagger")
}

tasks.named('test') {
    useJUnitPlatform()
}

 

결과 화면

http://localhost:8080/docs/index.html 에서 확인 가능

 

 

 

 

반응형

+ Recent posts