catsridingCATSRIDING|OCEANWAVES
Dev

Spring REST Docs 적용하기

jynn@catsriding.com
Nov 13, 2023
Published byJynn
999
Spring REST Docs 적용하기

Documentation REST API with Spring REST Docs

Spring Framework를 기반으로 API 서버를 구축하게 되면 문서화를 위해 주로 활용되는 라이브러리는 Spring REST Docs스웨거(Swagger)가 있습니다. 이 두 도구는 기능과 사용 목적에서 차이가 있어, 프로젝트의 요구사항에 따라 하나를 선택하거나 둘을 병행하여 사용하기도 합니다.

Spring REST Docs는 테스트 코드 기반으로 작동하는 특성을 갖고 있습니다. 즉, 테스트가 성공할 경우 자동으로 API 스펙을 설명하는 코드 조각들이 생성됩니다. 이러한 접근 방식은 테스트를 통해 검증된 API만을 문서화함으로써, 보다 안정적인 API 구현을 가능하게 합니다. 또한, 이 방법은 문서의 정확성을 보장하고, 문서를 쉽게 최신 상태로 유지할 수 있도록 돕습니다. 이 과정을 통해 개발된 API는 신뢰성이 높고, 문서화 과정에서 발생할 수 있는 오류를 최소화할 수 있습니다.

Prerequisites

Spring REST Docs를 활용한 API 문서화 과정을 진행하기 위해, 먼저 Spring Boot 프로젝트를 설정하고 간단한 REST API를 구성합니다. 이 프로젝트는 다음 기술 스택을 기반으로 하고 있습니다.

build.gradle
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
  • Java 17
  • Spring Boot 3.3.0
  • Gradle 8
  • Dependencies:
    • Spring Web
    • Lombok

다음은 클라이언트의 요청을 받아 처리 후 응답을 반환하는 간단한 POST API입니다:

HelloController.java
@PostMapping("/hello")  
public ResponseEntity<?> hello(@RequestBody HelloRequest request) {  
    HelloResponse response = HelloResponse.create(request);  
    return ResponseEntity.ok(response);  
}

이 코드는 HelloRequest 클래스에서 정의된 요청 데이터를 기반으로 HelloResponse 객체를 생성하고, 그것을 클라이언트에 반환합니다. HelloRequest 클래스는 다음과 같이 정의됩니다:

HelloRequest.java
public class HelloRequest {

    private String username;

}

응답 데이터 구조는 HelloResponse 클래스에서 정의됩니다:

HelloResponse.java
public class HelloResponse {

    private int id;  
    private String message;

}

API 기능을 검증하기 위해 MockMvc를 사용하는 테스트 코드를 작성합니다:

HelloControllerTest.java
@Test  
@DisplayName("docs")  
void docs() throws Exception {

    // Given
    HelloRequest request = new HelloRequest("request");  
    ObjectMapper objectMapper = new ObjectMapper();  
  
    // When
    ResultActions actions = mockMvc.perform(  
            MockMvcRequestBuilders.post("/hello")  
                    .contentType(APPLICATION_JSON)  
                    .content(objectMapper.writeValueAsString(request)));  
  
    // Then
    actions.andExpect(status().isOk());  
}

이 테스트 코드는 /hello 엔드포인트로 POST 요청을 시뮬레이션하고, 결과로 'OK' 상태 코드가 반환되는지 확인합니다. 이 과정을 통해 구현된 API의 기능이 올바르게 동작하는지 검증할 수 있습니다.

이제 이 API를 기반으로 Spring REST Docs를 통한 문서화 작업을 살펴보겠습니다.

Configuring Spring REST Docs

Spring REST Docs를 사용하기 위해 필요한 의존성을 프로젝트에 추가하고 환경을 구성하는 단계는 비교적 복잡할 수 있습니다. Swagger와 비교했을 때, Swagger는 의존성을 추가하는 것만으로 바로 사용할 수 있지만, Spring REST Docs는 추가적인 설정이 필요합니다. 그러나 이 설정을 한 번 완료하고 나면, 이후에 변경할 일은 거의 없어지므로 초기 설정의 복잡성을 감수할 가치가 있습니다.

Dependencies

Spring REST Docs를 프로젝트에서 사용하려면 먼저 build.gradle 파일에 의존성을 추가하고 환경을 구성해야 합니다.

build.gradle
plugins {  
    id 'org.asciidoctor.jvm.convert' version '3.3.2' // ¹
}

configurations {  
    asciidoctorExt  // ²
}

ext {  
    set('snippetsDir', file("build/generated-snippets"))  // ³
}

dependencies {  // ⁴
    asciidoctorExt 'org.springframework.restdocs:spring-restdocs-asciidoctor'
    testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc'
}

tasks.named('test') {  
    outputs.dir snippetsDir  // ⁵
    useJUnitPlatform()
}

tasks.named('asciidoctor') {  // ⁶
    inputs.dir snippetsDir
    configurations 'asciidoctorExt'
    sources {
        include("**/index.adoc")
    }
    baseDirFollowsSourceFile()
    dependsOn test
}

asciidoctor.doFirst {  // ⁷
    delete file('src/main/resources/static/docs')
}

bootJar {  // ⁸
    dependsOn asciidoctor
    copy {
        from("${asciidoctor.outputDir}")
        into 'src/main/resources/static/docs'
    }
}
  • ¹ Asciidoctor 플러그인을 추가합니다.
  • ² Asciidoctor 확장 의존성에 대한 구성을 추가합니다.
  • ³ Spring REST Docs에서 생성한 코드 조각들의 경로를 전역적으로 사용할 수 있도록 변수로 추가합니다.
  • ⁴ Spring REST Docs 및 Asciidoctor 확장 의존성을 추가합니다.
  • ⁵ 테스트를 수행하면 자동으로 생성되는 Spring REST Docs의 *.adoc 코드 조각들이 저장되는 위치를 지정합니다.
  • ⁶ Asciidoctor Gradle Task를 추가합니다.
    • sources{}: index.adoc 파일에 대해서만 html 파일을 생성합니다.
    • configurations 'asciidoctorExt': 확장 플러그인을 활용하기 위한 설정을 구성합니다.
    • baseDirFollowsSourceFile(): Asciidoc 문서를 html 파일로 변환할 때 include:: 연산에 포함된 *.adoc 파일들을 읽어 들일 수 있도록 해당 파일들의 경로를 자동으로 지정해줍니다.
    • dependsOn test: 테스트가 수행된 이후에 Task가 실행됩니다.
  • ⁷ Asiidoctor Gradle Task가 수행되기 전에 먼저 기존에 생성된 문서를 모두 정리합니다.
  • ⁸ 프로젝트를 패키징 할 때, build 디렉토리에 생성된 문서를 지정한 디렉토리로 자동으로 복사합니다. 외부에서 URL을 통해 해당 문서에 접근해야 하는 경우에 활용할 수 있으며 필수는 아닙니다.

프로젝트를 빌드 할 때 문서를 외부에 접근 가능하도록  resources/static 디렉토리로 이동해야 한다면 Gradle Task를 추가적으로 구성합니다.

build.gradle
tasks.register('copyDocument', Copy) {  // ¹
    dependsOn asciidoctor
    from file("build/docs/asciidoc")
    into file("src/main/resources/static/docs")
}

build {  // ²
    dependsOn copyDocument
}
  • ¹ build 디렉토리 하위에 생성된 문서를 지정한 장소로 복사하는 Gradle Task를 추가합니다.
  • ² 프로젝트를 빌드할 때, 위에서 등록한 copyDocument Gradle Task를 실행합니다.

Integrating Test Environment

이제 Spring REST Docs를 위한 테스트 환경을 설정합니다. 이 과정에서는 테스트 실행 후 생성되는 코드 조각에 공통적으로 적용할 설정을 관리하는 RestDocsSupport 클래스를 추가합니다.

RestDocsSupport.java
@TestConfiguration  
public class RestDocsSupport {  
  
    @Bean  
    public RestDocumentationResultHandler restDocs() {  
        return MockMvcRestDocumentation.document("{class-name}/{method-name}",  
                preprocessRequest(prettyPrint()),  
                preprocessResponse(prettyPrint()));  
    }  
}
  • {class-name}/{method-name}: 코드 조각이 저장될 디렉토리의 패턴을 지정합니다. 이렇게 정형화하면 추후 Asciidoc에서 문서를 불러올때 IntelliJ IDEA 자동완성 기능과 함께 편리하게 가져올 수 있습니다.
  • prettyPrint(): 생성된 코드 조각의 JSON 포맷을 보기 좋은 형태로 정렬합니다. JSON 코드가 한 줄로 출력되는 것을 방지하기 위해 반드시 적용하는 것이 좋습니다.

다음으로, MockMvc 인스턴스에 Spring REST Docs를 통합합니다.

IntegrationTestSupport.java
@SpringBootTest  
@ActiveProfiles("test")  
@Import(RestDocsSupport.class)  
@ExtendWith(RestDocumentationExtension.class)  
public class IntegrationTestSupport {  
  
    @Autowired  
    protected RestDocumentationResultHandler restDocs;  
    protected MockMvc mockMvc;  
  
    @BeforeEach  
    public void setup(WebApplicationContext context, RestDocumentationContextProvider restDocumentation) {  
        this.mockMvc = MockMvcBuilders.webAppContextSetup(context)  
                .apply(documentationConfiguration(restDocumentation))  
                .alwaysDo(print())  
                .alwaysDo(restDocs)  
                .build();  
    }  
}
  • @Import: Spring Framework의 @Import 어노테이션은 지정된 구성 클래스 또는 구성 요소를 애플리케이션 컨텍스트에 가져옵니다. 여기서는 RestDocsSupport 클래스를 가져와서 통합 테스트에 필요한 설정을 적용합니다.
  • @ExtendWith: JUnit 5의 @ExtendWith 어노테이션은 테스트 실행 시 지정된 확장 클래스를 추가합니다.
  • RestDocumentationExtension: 이 클래스는 Spring REST Docs의 확장 기능을 제공하여, 테스트 중에 RESTful API 문서화를 지원합니다. 테스트 시작 시 RestDocumentationContextProvider를 초기화하여 각 테스트 메서드가 실행될 때마다 문서화 설정을 자동으로 적용합니다. 이를 통해 매번 수동으로 설정을 적용할 필요 없이 일관된 문서화를 보장합니다. 또한, JUnit 5와의 통합을 통해 테스트 클래스 내에서 REST Docs 관련 설정을 자동으로 관리하고, 문서화 작업을 보다 쉽게 수행할 수 있도록 지원합니다. 이 클래스를 통해 문서화 설정을 포함한 다양한 REST Docs 기능을 테스트 코드 내에서 쉽게 활용할 수 있습니다.
  • RestDocumentationResultHandler: Spring REST Docs의 결과 처리기로, 테스트 결과를 기반으로 문서화를 수행합니다. 각 테스트의 결과를 캡처하고 이를 사용하여 RESTful API의 문서화된 스니펫을 생성합니다. 이는 API 문서의 일관성과 정확성을 유지하는 데 중요합니다.
  • MockMvc: Spring MVC 테스트 프레임워크의 핵심 구성 요소로, 웹 애플리케이션의 엔드포인트를 테스트할 수 있게 해줍니다. 이를 통해 실제 서버를 구동하지 않고도 컨트롤러의 동작을 검증할 수 있습니다.
  • webAppContextSetup(): Spring 애플리케이션 컨텍스트를 기반으로 MockMvc 인스턴스를 생성하고 구성합니다. 이를 통해 실제 애플리케이션의 동작과 유사한 환경에서 통합 테스트를 수행할 수 있습니다. 이 메서드는 REST Docs 설정뿐만 아니라, 보안 설정, 데이터베이스 연결, 뷰 리졸버 등 웹 애플리케이션의 전체적인 설정을 포함하여 통합 테스트 환경을 완벽하게 재현합니다.
  • alwaysDo(): MockMvc 설정의 일부로, 모든 요청에 대해 특정 동작을 항상 수행하도록 지정합니다. 여기서는 모든 요청에 대해 커스터마이징된 RestDocumentationResultHandler를 적용하여 문서화 작업을 자동화합니다.

이러한 설정을 통해 테스트 중에 자동으로 문서화가 진행되며, Spring REST Docs의 설정을 완료하게 됩니다. 테스트 코드가 많아지고 실행 속도가 중요해질 경우, webAppContextSetup() 대신 standaloneSetup()을 사용하여 더 빠르고 독립적인 테스트 환경을 구성할 수 있습니다. 이 방법은 별도의 Spring 서버 없이 MockMvc 인스턴스를 단독으로 실행할 수 있게 해주어, 테스트 실행 속도를 개선합니다.

Documenting REST API

필요한 설정이 완료되었으므로 이제 Spring REST Docs를 사용하여 REST API 문서화 작업을 진행하겠습니다. 이 도구는 코드의 변화에 따라 문서가 자동으로 업데이트되어, 항상 최신의 API 정보를 제공합니다. 이 과정은 문서와 코드 사이의 일관성을 유지하며, 정확하고 신뢰할 수 있는 API 문서화를 가능하게 합니다.

Snippet Operations

Spring REST Docs는 API 스펙을 자세히 문서화할 수 있는 다양한 스니펫 오퍼레이션을 제공합니다. 이 오퍼레이션들은 API 테스트 케이스를 작성하는 동안 문서화도 동시에 수행되도록 설계되어 있습니다. 여기서는 몇 가지 주요 스니펫 오퍼레이션을 살펴보겠습니다:

REST Docs는 API 문서화를 자동화하는 도구로, 다양한 스니펫 유형을 통해 API의 각 부분을 상세하게 문서화할 수 있습니다. 아래는 각 스니펫의 핵심 설명과 함께 조금 더 구체적인 정보를 추가한 것입니다:

Request Components

요청 컴포넌트는 클라이언트가 서버에 요청을 보낼 때 사용되는 다양한 요소를 문서화하는데 사용됩니다. 각 컴포넌트는 요청의 특정 부분을 설명하여 API 사용자가 요청의 구조와 기대값을 이해할 수 있도록 합니다.

requestHeaders

클라이언트가 서버에 요청을 보낼 때 포함해야 하는 HTTP 헤더들을 문서화합니다. 예를 들어, Authorization 헤더는 클라이언트의 인증 정보를 전달하고, Content-Type 헤더는 요청 본문의 데이터 타입을 지정합니다.

requestHeaders(
    headerWithName("Authorization").description("Bearer token for authentication"),
    headerWithName("Content-Type").description("The MIME type of the body of the request")
)
pathParameters

URL 경로 내의 변수 파라미터를 문서화합니다. 이는 특정 리소스를 식별하는 데 사용됩니다. 예를 들어, /users/{userId}에서 userId는 특정 사용자를 식별하는 데 사용됩니다.

pathParameters(
    parameterWithName("userId").description("The ID of the user")
)
queryParameters

URL의 쿼리 스트링 파라미터를 문서화합니다. 이는 페이징, 필터링, 정렬 등에 사용됩니다. 예를 들어, ?page=1&size=20에서 pagesize는 결과의 페이지와 페이지 크기를 나타냅니다. Spring Boot 2.x 대의 requestParameters를 대체합니다.

queryParameters(
    parameterWithName("page").description("The page number to retrieve"),
    parameterWithName("size").description("The number of records per page")
)
requestFields

HTTP 요청 본문에 포함된 JSON 또는 XML 등의 데이터 필드를 문서화합니다. 이는 데이터 생성 및 업데이트 시 필요한 정보 전달을 위해 사용됩니다. 예를 들어, {"name": "John", "age": 30}에서 nameage 필드는 사용자의 이름과 나이를 나타냅니다.

requestFields(
    fieldWithPath("name").description("The name of the user"),
    fieldWithPath("age").description("The age of the user")
)
requestParts

multipart/form-data 형식의 요청에서 각 파트를 문서화합니다. 이는 여러 유형의 데이터를 포함하는 요청 처리에 사용됩니다. 예를 들어, 파일 업로드와 폼 데이터를 함께 전송할 때 사용됩니다.

requestParts(
    partWithName("file").description("The file to be uploaded"),
    partWithName("metadata").description("JSON metadata about the file")
)
requestPartFields

multipart/form-data 요청의 JSON 파트 내 필드를 문서화합니다. 이는 복잡한 멀티파트 요청에서 데이터를 설명하는 데 사용됩니다. 예를 들어, {"metadata": {"field": "value"}} JSON 파트 내의 필드들을 설명합니다.

requestPartFields(
    fieldWithPath("metadata.field").description("A field within the metadata JSON object")
)
Response Components

응답 컴포넌트는 서버가 클라이언트에게 응답할 때 사용되는 다양한 요소를 문서화하는데 사용됩니다. 각 컴포넌트는 응답의 특정 부분을 설명하여 API 사용자가 응답의 구조와 의미를 이해할 수 있도록 합니다.

responseHeaders

서버 응답의 HTTP 헤더들을 문서화합니다. 이는 응답 데이터 타입, 세션 정보 등을 전달합니다. 예를 들어, Content-Type 헤더는 응답 본문의 데이터 타입을 지정합니다.

responseHeaders(
    headerWithName("Content-Type").description("The MIME type of the body of the response"),
    headerWithName("Set-Cookie").description("Cookie information to be stored by the client")
)
responseFields

HTTP 응답 본문에 포함된 JSON 또는 XML 등의 데이터 필드를 문서화합니다. 이는 응답 데이터의 구조와 의미를 설명하는 데 사용됩니다. 예를 들어, {"id": 1, "name": "John"}에서 idname 필드는 사용자 ID와 이름을 나타냅니다.

responseFields(
    fieldWithPath("id").description("The ID of the user"),
    fieldWithPath("name").description("The name of the user")
)
Specific Item Components

특정 항목 컴포넌트는 요청 또는 응답의 특정 요소를 문서화하는 데 사용됩니다. 이는 특정 헤더, 파트, 필드 또는 파라미터의 상세 설명을 추가하여 그 기능과 중요성을 강조합니다.

headerWithName

특정 헤더의 이름과 상세 설명을 추가합니다. 이는 특정 헤더의 기능과 중요성을 강조합니다. 예를 들어, Authorization 헤더는 클라이언트의 인증 정보를 전달합니다.

headerWithName("Authorization").description("Bearer token for authentication")
partWithName

특정 파트의 이름과 상세 설명을 추가합니다. 이는 멀티파트 요청에서 특정 파트를 설명하는 데 사용됩니다. 예를 들어, 파일 업로드에서 파일 파트를 설명합니다.

partWithName("file").description("The file to be uploaded")
fieldWithPath

JSON 또는 XML 페이로드 내 특정 필드의 경로와 상세 설명을 추가합니다. 이는 데이터 구조 내 특정 필드를 설명하는 데 사용됩니다. 예를 들어, 사용자 정보 내의 이름 필드를 설명합니다.

fieldWithPath("name").description("The name of the user")
parameterWithName

특정 쿼리 파라미터의 이름과 상세 설명을 추가합니다. 이는 URL 쿼리 파라미터를 설명하는 데 사용됩니다. 예를 들어, 페이지 번호를 나타내는 page 파라미터를 설명합니다.

parameterWithName("page").description("The page number to retrieve")

이러한 스니펫 오퍼레이션을 활용하면, API 문서가 사용자가 API를 효과적으로 활용할 수 있도록 필요한 모든 정보를 상세히 제공합니다. 또한, 개발자는 API의 변경 사항을 문서에 신속하게 업데이트할 수 있어, 문서의 정확성과 최신성을 유지할 수 있습니다.

Generating Code Snippets

기존 테스트 클래스를 확장하여 IntegrationTestSupport 클래스를 적용하고, Spring REST Docs의 다양한 오퍼레이션을 추가함으로써 API 문서화 작업을 진행합니다. 이 접근 방식은 테스트 주도 개발(TDD)의 이점을 문서 생성 과정에도 적용하며, 코드와 문서 간의 일치를 보장합니다.

HelloControllerTest.java
class HelloControllerTest extends IntegrationTestSupport {

    @Test
    @DisplayName("docs")
    void docs() throws Exception {
  
        //  Given
        (...)
  
        //  When
        ResultActions actions = mockMvc.perform(
                RestDocumentationRequestBuilders.post("/hello")
                        .contentType(APPLICATION_JSON)
                        .content(objectMapper.writeValueAsString(request)));
  
        //  Then
        actions
                .andExpect(status().isOk())
                .andDo(
                        restDocs.document(
                                requestHeaders(headerWithName(CONTENT_TYPE).description(APPLICATION_JSON)),
                                requestFields(fieldWithPath("username").description("유저명")),
                                responseHeaders(headerWithName(CONTENT_TYPE).description(APPLICATION_JSON)),
                                responseFields(
                                        fieldWithPath("id").description("ID"),
                                        fieldWithPath("message").description("메시지"))));
    }
}
  • RestDocumentationRequestBuilders: 기존의 MockMvcRequestBuilders를 대체하여 Spring REST Docs에 특화된 요청 빌더를 사용합니다.
  • andDo(restDocs.document()): 실행한 API 요청의 상세 스펙을 문서화하는 코드 조각을 생성합니다. 만약 테스트 중 정의된 API 스펙이 요청과 일치하지 않는 경우, 테스트는 실패하게 됩니다.

테스트 코드 실행 후 성공적으로 통과한다면, build.gradle에서 지정한 build/generated-snippets 디렉토리에 아래와 같이 여러 *.adoc 코드 조각 파일들이 자동으로 생성됩니다.

$ exa -alhFT
./
├──  .git/
├──  .gitignore
├──  .gradle/
├──  .idea/
├──  build/
│  └──  generated-snippets/
│     └──  hello-controller-test/
│        └──  docs/
│           ├──  curl-request.adoc
│           ├──  http-request.adoc
│           ├──  http-response.adoc
│           ├──  httpie-request.adoc
│           ├──  request-body.adoc
│           ├──  request-fields.adoc
│           ├──  request-headers.adoc
│           ├──  response-body.adoc
│           ├──  response-fields.adoc
│           └──  response-headers.adoc
├──  build.gradle
├──  gradle/
├──  gradlew*
├──  gradlew.bat
├──  settings.gradle
└──  src/
   ├──  main/
   └──  test/

RestDocsSupport에서 설정했던 {class-name}/{method-name} 패턴으로 디렉토리가 추가되었습니다. 참고로, 아래 코드 조각들은 오퍼레이션을 추가하지 않더라도 기본적으로 생성됩니다:

  • curl-request.adoc
  • http-request.adoc
  • http-response.adoc
  • httpie-request.adoc
  • request-body.adoc
  • response-body.adoc

Working with AsciiDoc

생성된 코드 조각들을 사용하여 API를 문서를 작성하기 위해서는 AsciiDoc 파일을 추가해야 합니다.  src/docs/asciidoc 디렉토리를 추가하고 안에 index.adoc 파일을 생성합니다.

$ exa -alhFT
./
├──  .git/
├──  .gitignore
├──  .gradle/
├──  .idea/
├──  build/
├──  build.gradle
├──  gradle/
├──  gradlew*
├──  gradlew.bat
├──  settings.gradle
└──  src/
   ├──  docs/
   │  └──  asciidoc/
   │     └──  index.adoc
   ├──  main/
   └──  test/

AsciiDoc 공식 문서도 아주 잘 정돈되어 있고 문법도 마크다운과 매우 유사하여 다른 *.adoc 파일을 불러오는 기능만 이해한다면 어렵지 않게 사용할 수 있을 것입니다.

AsciiDoc은 includeoperation 키워드를 통해 다른 *.adoc 파일을 내장할 수 있습니다. 이 기능을 활용하여 Spring REST Docs 코드 조각들을 불러옵니다.

index.adoc
include::{snippets}/hello-controller-test/docs/http-request.adoc[]
operation::hello-controller-test/docs[snippets='request-headers,request-fields,http-request']
  • include: 하나의 *.adoc 파일을 불러올 때 활용할 수 있습니다.
  • operation: 다수의 *.adoc 파일을 한 번에 불러올 때 활용할 수 있습니다.

IntelliJ IDEA AsciiDoc 플러그인이 설치되어 있다면 랜더링 결과를 바로 확인할 수 있습니다.

documentation-rest-api-with-spring-rest-docs_0.png

AsciiDoc 공식 문서를 확인하면서 API 문서를 완성합니다.

= Spring REST Docs  
:doctype: book  
:icons: font  
:source-highlighter: highlightjs  
:toc: left  
:toclevels: 6  
:sectlinks:  
  
== Hello API  
Spring REST Docs 적용하여 API 문서를 작성하고 있습니다.  
  
=== Request  
operation::hello-controller-test/docs[snippets='request-headers,request-fields,http-request']  
  
=== Response  
operation::hello-controller-test/docs[snippets='response-headers,response-fields,http-response']

documentation-rest-api-with-spring-rest-docs_1.png

지금은 하나의 파일에서 API 문서를 관리하지만 API 개수가 많으면 파일이 너무 커져서 문서 관리가 어려워집니다. 이럴 때는 API마다 각각의 *.adoc 파일로 분리한 다음 index.adoc에서 해당 파일들을 include 하는 방식으로 구조를 변경하는 것이 유리합니다.

Generate API Document

작성한 *.adoc 파일을 html 파일로 변환하는 작업은  build.gradle에 추가한 Task에 의해 gradle bootJar 명령어 실행 시 자동으로 수행됩니다. 패키징에 성공하면 지정한 위치  resources/static/docs*.adoc 파일과 동일한 이름의 html 파일이 생성됩니다.

$ exa -alhFT
./
├──  .git/
├──  .gitignore
├──  .gradle/
├──  .idea/
├──  build/
├──  build.gradle
├──  gradle/
├──  gradlew*
├──  gradlew.bat
├──  settings.gradle
└──  src/
   ├──  docs/
   ├──  main
   │  ├──  java
   │  └──  resources
   │     ├──  application.yml
   │     ├──  data.sql
   │     ├── 󰗀 logback-prod.xml
   │     ├──  schema.sql
   │     └──  static
   │        └──  docs
   │           └──  index.htm
   └──  test/

브라우저로  index.html 파일을 열면 인텔리제이 AsciiDoc 플러그인의 미리 보기와 동일한 화면이 출력됩니다. 이 html 파일을 공유하거나 애플리케이션 배포 후 URL을 통해 API 문서를 공유할 수 있습니다.

documentation-rest-api-with-spring-rest-docs_2.png


  • Spring
  • Documentation