본문 바로가기
Backend boot camp/Session3

[Spring MVC] API문서화

by orioncsy 2022. 11. 11.

API 문서화

API 문서화가 필요한 이유

API 문서화

  • REST API 백엔드 애플리케이션 요청을 전송하기 위해 알아야 하는 요청 정보를 문서로 정리한 것
  • 클라이언트 측에서 API를 사용하려면 정보가 필요하기 때문에 작성
  • API 정보를 수기 작성 혹은 빌드를 통해 API 문서 자동 생성

API 문서 생성의 자동화가 필요한 이유

  • 수기 작성은 매우 비효율적
  • 보다 정확한 정보 전달을 위해 API 문서 생성 자동화 필요

Swagger vs Spring Rest Docs

Swagger API 문서화

  • Java 애플리케이션에서 전통적인 API 문서 자동화 오픈 소스
  • 애플리케이션 기능을 구현하기 위해 API 문서 생성을 위한 애너테이션이 추가된다.
  • controller와 request Body, response body 같은 DTO 클래스에도 애너테이션 추가
    • @ApiOperation(value=””, tags={Member Controller}) - 컨트롤러에 추가
    • @ApiOperation(value=””, notes=””) - 각 핸들러 매서드에 추가
    • ApiResponses(value={@ApiResponse(code=201, message=””), @ApiResponse(code=404, “”)}) - 각 핸들러 메서드에 response에 대한 처리
    • @ApiModel(””) - Dto 에 추가
    • @ApiModelProperty(notes=””, example=””, requried = true) - Dto 멤버 필드에 추가
  • Postman처럼 execute 버튼을 눌러 요청을 전송 가능

Spring Rest Docs API 문서화

  • Swagger와의 차이는 구현 코드에 애너테이션을 추가하지 않는다.
  • Controller 테스트 클래스에 API 문서 정보 추가
  • 슬라이스 테스트가 passed일 경우 API 문서 생성

Spring Rest Docs

API 문서 생성 흐름

  • 슬라이스 테스트 코드 작성
    • Controller에 대한 슬라이스 테스트 코드 작성
  • API 스펙 정보 코드 작성
  • test 실행
    • 슬라이스 테스트 코드 실행
    • Gradle의 빌드 task 중 하나인 test task를 실행시켜 API 문서 snippet을 일괄 생성
    • passed 이면 다음 작업, failed 면 테스트 케이스 수정
  • API 문서 스피닛 생성
    • 테스트 결과 passed 이면 API 스펙정보 코드 기반으로 API 문서 스피닛이. adoc 확장자를 가진 파일로 생성
  • API 문서 생성
    • 생성된 API 문서 스피닛을 모아서 하나의 API 문서 생성
  • API 문서 → HTML 변환
    • 파일 자체를 공유하거나 URL을 통해 접속 가능

Spring Rest Docs 설정

  • build.gradle 설정
    • .adoc 파일 확장자를 가지는 AsciiDoc 문서를 생성해주는 Asciidoctor를 사용하기 위해 플러그인 추가
    plugins {
    	id "org.asciidoctor.jvm.convert" version "3.3.2"
    }
    
    • ext 변수의 set() 메서드로 API 문서 스피닛 생성 경로 지정
    ext {
    	set('snippetsDir', file("build/generated-snippets"))
    }
    
    • AsciiDoctor에서 사용되는 의존 그룹 지정
    configurations {
    	asciidoctorExtensions
    }
    
    • dependencies에 라이브러리 추가
    dependencies {
    	testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc' 
    	asciidoctorExtensions 'org.springframework.restdocs:spring-restdocs-asciidoctor'
    }
    
    • :test task 실행 시 API 문서 생성 스피닛 디렉터리 경로 설정
    tasks.named('test') {
    	outputs.dir snippetsDir
    	useJUnitPlatform()
    }
    
    • :asciidoctor task 실행 시 Asciidoctor 기능을 사용하기 위해 asciidoctorExtensions 설정
    tasks.named('asciidoctor') {
    	configurations "asciidoctorExtensions"
    	inputs.dir snippetsDir
    	dependsOn test
    }
    
    • :build task 실행 전 실행되는 task
    • :copyDocument task 수행되면 index.html 파일이 src/main/resources/static/docs에 copy 되고 API 문서를 파일 형태로 외부에 제공하는 용도로 사용 가능
      • :askiidoctor task 실행 후 task 실행되도록 의존성 설정
      • “build/docs/asciidoc/” 경로에 생성되는 index.html copy
      • “src/main/resources/statis/docs” 경로에 index.html 추가
    task copyDocument(type: Copy) {
    	dependsOn asciidoctor
    	from file("${asciidoctor.outputDir}")
    	into file("src/main/resources/static/docs")
    }
    
    • :build task가 실행되기 전 :copyDocument task가 먼저 수행되도록 한다.
    build {
    	dependsOn copyDocument
    }
    
    • :bootJar task 설정
    bootJar {
    	dependsOn copyDocument
    	from ("${asciidoctor.outputDir}") {
    		into 'static/docs'
    	}
    }
    

API 문서 스니핏 사용을 위한 템플릿 생성

  • API 문서 스피닛이 생성되었을 때 최종 API문서를 만들어주는 템플릿 문서(idex.adoc)를 생성
  • src/docs/asciidoc/ 경로에 디렉터리 생성
  • 비어 있는 index.adoc 생성

Controller 테스트 케이스에 Spring Rest Docs 적용

API 문서 생성 슬라이스 테스트 케이스 작성

API 문서 생성 테스트 케이스 기본 구조

  • 테스트 클래스를 선언하고 @SpringBootTest 대신 @WebMvcTest 적용
    • @WebMvcTest()는 controller 테스트 전용 애너테이션이다.
    • 괄호 안에 테스트 대상 controller 작성
  • @MockBean(JpaMetamodelMappingContext.class)를 클래스에 추가한다.
    • JPA에서 사용하는 bean들을 Mock 객체로 주입하는 설정
    • @SpringBootApplication이 존재하는 최상위 패키지 경로의 application 클래스를 찾아서 실행
    • 해당 클래스에 @EnableJpaAuditing이 붙어있는 것을 확인 가능
    • @WebMvcTest()를 사용하면 JPA 관련 bean이 필요하기 때문에 @MockBean(JpaMetamodelMappingContext.class) 작성 필수
  • 테스트 클래스에 @AutoConfigureRestDocs를 추가해 자동 구성
  • MockMvc 객체를 주입받는다.
  • controller 클래스가 의존하는 객체를 @MockBean으로 주입받는다.
  • HTTP request에 필요한 데이터 추가
  • given() 메서드로 stubbing을 작동
  • ResultActions와. andExpect로 테스트 진행
  • 테스트 수행 후 API 문서 자동 생성을 위해. andDo(document())를 통해 API 스펙 정보 입력
  • 테스트 과정과 모두 동일하고 마지막 document()에 API 스펙 정보를 추가
    • “post-member”
      • API 문서 스피닛의 식별자 역할
    • getRequestPreProcessor()
      • 스피닛 생성하기 전 resquest에 해당하는 문서 영역을 전 처리하는 역할
      • interface ApiDocumentUtils를 선언해 static으로 OperationRequestPreprocessor를 반환형으로 하는 메서드를 만들고 return preprocessRequest(prettyPrint())로 선언
    • getResponsePreProcessor()
      • interface ApiDocumentUtils를 선언해 static으로 OperationResponsePreprocessor를 반환형으로 하는 메서드를 만들고 return preprocessResponse(prettyPrint())로 선언
    • requestFields()
      • List.of()
        • fieldWithPath(). type(JsonFieldType.STRING). description(””) 형태로 작성
    • responseFields
      • List.of()
        • fieldWithPath().type(JsonFieldType.STRING).description(””) 형태로 작성
  • 마지막으로 test를 실행하고 passed 처리되면
  • build 디렉터리 - generated-snippets 디렉터리 - post-member 디렉터리 - adoc 확장자의 스니핏 문서가 생성

Post-member 이외의 API 작성 요령

  • document()에
    • path variable 정보 추가
    • pathParameters(parameterWithName(””). description(””))로 추가
    • field가 path variable 정보로 전달받는 내용인 경우에는. ignored()를 사용하여 제외 가능
    • field가 선택적으로 수정할 수 있다면. optional() 추가

@SpringBootTest vs @WebMvcTest

  • @SpringBootTest
    • @AutoConfigureMockMvc와 함께 테스트 가능
    • 전체 Bean을 ApplicationContext에 등록
    • 실행 속도 느림
    • DB까지 이어지는 통합 테스트에 사용
  • @WebMvcTest
    • controller에 필요한 bean만 ApplicationContext에 등록
    • 실행 속도 상대적 빠름
    • mock 객체를 사용하여 의존성을 일일이 제거해야 한다.
    • Controller를 위한 슬라이스 테스트에 사용

Snippet을 이용한 API 문서화

API 문서 탬플릿 생성을 위한 디렉터리 및 템플릿 문서 생성

  • API 문서 스피닛은 문서의 일부 조각으로 최종 API 문서를 만들기 위해서 템플릿 문서 필요
  • src/docs/asciidoc을 생성하고 하위에 index.adoc 파일을 생성
    • gradle 프로젝트에서 템플릿 문서의 디폴트 경로가 src/docs/asciidoc이다.

템플릿 내용 추가

  • = 제목
    • API 문서 제목
  • API 문서 목차
  • Hong gil dong gildong.hgd@gmail.com
    • 생성자 정보
  • v1.0.0 2022.11.11
    • 버전 및 API 문서 생성 날짜
  • API 문서 스니핏을 사용하는 부분
***
==MemberController
===회원 등록
.스니핏 문서파일명
include::{snippets}/스니핏 문서가 위치한 디렉터리/스니핏 문서파일명.adoc[]

템플릿 문서를 HTML 파일로 변환

  • gradle 탭에서 :bootJar 혹은 :build task를 더블 클릭
  • 정상적으로 종료되면 src/main/resources/static/docs 디렉터리에 index.adoc 파일을 이용해 변환된 index.html 파일 생성
  • 애플리케이션 실행하고 http://localhost:8080/docs/index.html로 접속하여 확인

Asciidoc 문법

Asciidoc

  • Spring Rest Docs를 통해 생성되는 텍스트 기반 문서 포맷
  • 다양한 형식으로 변환 가능
  • 기술 문서를 작성하기 위해 설계된 마크업 언어

목차 구성

= 커피 주문 애플리케이션
:sectnums:
:toc: left
:toclevels: 4 
:toc-title: Table of Contents
:source-highlighter: prettify
  • =의 개수가 늘어날수록 크기가 작아진다.
  • 각 세션에 넘버링을 위해 :sectnums:를 추가
  • :toc:는 목차를 문서의 어디에 위치할 것인지 정한다.
  • :toclevels:는 목차에 표시할 제목의 level을 정한다. 4로 지정하면 ====까지 제목이 목차에 표시
  • :toc-title:은 목차의 제목을 지정 가능
  • :source-highlighter: 문서에 표시되는 소스 코드 하일라이터 지정

이외의 문법

  • 박스 문단
    • *** 단락을 구분 짓은 수평선 추가
    • 문단의 제목을 적고 한 줄 띄우고 한 칸 들여 쓰기 문단을 작성하고 아래 ***로 닫으면 박스 문단을 사용 가능
  • *** 제목 박스 문단의 예시이다. ***
  • 경고 문구 추가
    • 경고 문구가 작성된다.
  • *** 제목 박스 문단 예시이다. CAUTION: 경고 문구 추가의 예시이다. ***
  • URL Scheme 자동인식
    • http, https, ftp, irc, mailto, hgd@gmail.com은 자동으로 인식하여 링크 설정
  • 이미지 추가
    • image::URL 입력

Asciidoctor

  • AsciiDoc 포맷의 문서를 파싱 해서 HTML 5, 매뉴얼 페이지, PDF, EPUB 3 등 문서 생성 툴
  • Spring Rest Docs에서는 Asciidoc 포맷의 문서를 HTML 파일로 변환하기 위해 내부적으로 Asciidoctor 사용

문서 스니핏을 템플릿 문서에 포함시키기

***
==MemberController
===회원 등록
.스니핏 문서파일명
include::{snippets}/스니핏 문서가 위치한 디렉터리/스니핏 문서파일명.adoc[]
  • . 스니핏 문서 파일명에서.(dot)은 스피닛 섹션 제목을 표현하기 위해 사용
  • include는 Asciidoc에서 사용하는 매크로 중 하나로 스니핏 템플릿 문서를 포함할 때 사용
  • ::는 매크로 사용 표기법, {snippets}는 스니핏이 생성되는 디폴트 경로 의미
  • build.gradle 파일에 ext {set(’snippetsDir’, file(”build/generated-snippets”))}에 있는 file 안에 잇는 경로가 스니핏 생성되는 디폴트 경로이다.

'Backend boot camp > Session3' 카테고리의 다른 글

[Spring MVC] 빌드/실행/배포  (0) 2022.11.11
[Spring MVC] Testing  (0) 2022.11.11
[Spring MVC] 트랜잭션  (0) 2022.11.07
[Spring MVC] JPA 데이터 액세스 계층  (0) 2022.11.07
[Spring MVC] JDBC DB Access Layer  (0) 2022.10.29