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 {
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 {
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”
- 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이다.
템플릿 내용 추가
***
==MemberController
===회원 등록
.스니핏 문서파일명
include::{snippets}/스니핏 문서가 위치한 디렉터리/스니핏 문서파일명.adoc[]
템플릿 문서를 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은 자동으로 인식하여 링크 설정
- 이미지 추가
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 안에 잇는 경로가 스니핏 생성되는 디폴트 경로이다.