1. API 문서 자동화의 이유
프로젝트를 진행하면서, 이전까지는 Notion
을 이용해 API docs 를 작성하고 관리하였다.
하지만 당연하게도 기능개발을 하면서 몇몇 이유로 API docs를 수정해야 하는 일이 생겼다.
그때마다 노션에 들어가서 API docs를 변경하는 것은 여간 번거로운 일이 아니었다.
심지어 어떤 때는 기능개발에 정신이 팔려 API docs의 업데이트를 새까맣게 까먹고 있다가,
프론트에서 변경 전 API 주소로 요청을 하는 경우도 있었다.
해야된다는 것은 문제가 터지기 전부터 인지하고 있었으나, 기능 개발이 우선
이란 마음에 차일피일 미루다,
더 이상은 미룰 수 없다! 라는 마음으로 API 문서 자동화를 진행하기로 했다.
2. RestDocs vs Swagger 그리고 OAS
이 부분은 팀원 모두가 한마음으로 RestDocs
를 외쳤다.
나를 포함해 기존에 Swagger
를 사용해본 경험이 있는 크루들이 프로덕션 코드에 문서화를 위한 코드가 포함되는것을 아주아주 마음에 안들어했다.
또한 RestDocs
의 경우 테스트 코드가 성공해야 문서 작성이 가능하므로,
문서의 신뢰성이 높아진다.
물론 테스트 코드 작성 시에 내부 구현을 싹다 Mocking
해버린다면이거 믿어도 되는건가...
싶은 문서가 생겨나긴 하지만,
우리 팀은 이번 프로젝트에서 Mocking
을 사용한 테스트를 최대한 배제 하기로 하였기에
신뢰도 높은 문서가 생성될 것이라 생각했다.
하지만 Swagger
를 선택하지 않음으로 인한 놓치게 되는 아쉬운 부분도 분명이 존재했다.RestDocs
로 api 문서화를 하게되면, adoc
을 통해 html
파일을 만들어주는데..
이렇게 만들어진 문서는 아름답지 못하다..
한 마디로 UI가 구리다.
또한 Swagger
로 만들어진 문서에선 API Test 기능이 지원 되지만, RestDocs
는 그렇지 않다.
장점 | 단점 | |
---|---|---|
RestDocs | 테스트코드 기반 -> 신뢰성 높음 | 구린 UI |
프로덕션 코드 영향 X | 문서에서 API Test 미지원 | |
Swagger | UI가 예쁘다! | 프로덕션 코드가 지저분해진다. |
문서에서 API Test 지원 |
나를 포함해서 욕심쟁이들로 이뤄진 우리팀은 두마리 토끼를 잡기 위해RestDocs
를 통해 만들어진 adoc
파일을 OAS
파일로 API spec을 시각화 해주기로 했다.
Swagger는 OAS 파일을 해석하여 API Spec을 시각화 한다.
우리 팀은 Swagger 보다 더 이쁜 문서 양식을 발견하여,
결론적으로는 Swagger를 통해 시각화 하지는 않았지만,
이 양식 역시 OAS 파일을 해석하여 API spec을 시각화 한다.
2-1. restdocs-api-spec
문제는 RestDocs
가 만들어 준 adoc
파일을 어떻게 OAS
파일로 변환하냐는 것인데,
매우 고맙게도 OAS파일을 만들어 주는 오픈소스(restdocs-api-spec) 가 있다.
물론 직접 java를 이용해 파일을 변환해줄 수도 있겠지만...
그렇게 된다면 배보다 배꼽이 더 큰 상황이 되버리니 잘 만들어둔 오픈 소스를 사용하자!
3. 적용
3-1. RestDocs
정하는게 어렵지 사용은 어렵지 않다.
RestDocs는 공식문서가 굉장히 잘돼있다.
plugins {
id "org.asciidoctor.jvm.convert" version "3.3.2"
}
configurations {
asciidoctorExt
}
dependencies {
asciidoctorExt 'org.springframework.restdocs:spring-restdocs-asciidoctor:{project-version}'
testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc:{project-version}'
}
ext {
snippetsDir = file('build/generated-snippets')
}
test {
outputs.dir snippetsDir
}
asciidoctor {
inputs.dir snippetsDir
configurations 'asciidoctorExt'
dependsOn test
}
이게 공식문서에 나와있는 의존성추가 부분인데 여기서 우리가 필요한 것만 골라쓰면 된다.asciidoctor
는 adoc 파일 텍스트 프로세서의 일종인데, asciidoc을 HTML 등으로 변환해주는 역할을 한다.
우리는 adoc을 yml로 변환해줄거기 때문에 필요없어서 이부분은 지우고,
mockMvc가 아닌 restAssured를 통해 테스틀 진행하기 때문에 mockMvc도 restAssured로 변경해주었다.
dependencies {
testImplementation 'org.springframework.restdocs:spring-restdocs-restassured'
}
ext {
snippetsDir = file('build/generated-snippets')
}
test {
outputs.dir snippetsDir
}
요렇게만 추가를 해줬다.
RestDocs 적용법은 공식문서가 원체 잘나와있기에 패스.
3-2. yml 변환
위에서 언급 했듯, 오픈소스를 이용할거다.
이것도 나름 공식문서가 필요한 만큼은 잘되어있다.
plugins {
id 'com.epages.restdocs-api-spec' version '0.18.2'
}
dependencies {
testImplementation 'com.epages:restdocs-api-spec-mockmvc:0.18.2'
}
openapi3 {
server = 'https://localhost:8080'
title = 'My API'
description = 'My API description'
tagDescriptionsPropertiesFile = 'src/docs/tag-descriptions.yaml'
version = '0.1.0'
format = 'yaml'
}
이것도 공식문서에서 가져온건데,
의존성을 추가해주면 된다. 간단한다.
근데 마찬가지로 우린 mockMvc가 아닌 resuAssured를 사용할 것이므로testImplementation 'com.epages:restdocs-api-spec-mockmvc:0.18.2'
얘를 지우고,testImplementation 'com.epages:restdocs-api-spec-restassured:0.18.2'
얘를 넣어줬는데,
이러면 안된다.
restAssured를 사용하려면 저 두개가 모두 있어야 된다.
저거때문에 외않되
를 연발 하다가, 똑같은 내용을 적용한 다른팀 크루에서 물어봐서 알게되었다.
두개가 다 있어야한다!
이 부분에 대해 공식문서에서 딱히 언급이 없어서 조금 헤멨던 것 같다.
사용하는 법 역시 간단하다.
RestDocs 공식문서를 보고 열심히 test코드를 수정했다면,
RestAssured.given(this.spec)
.filter(document("{method-name}",
"The API description",
requestParameters(
parameterWithName("param").description("the param")
),
responseFields(
fieldWithPath("doc.timestamp").description("Creation timestamp")
)
))
.when()
.queryParam("param", "foo")
.get("/restAssuredExample")
.then()
.statusCode(200);
이런식으로 돼있을 텐데,filter()
의 파라미터에 들어가는 값을 바꿔주면 된다.
현재 restDocs의 document가 아닌 com.epages.restdocs.apispec.RestAssuredRestDocumentationWrapper
얘의 document로 변경하면 된다.
설정은 끝났고 build.gradle 에 있는 저..저 재생? 버튼 누르면
테스트가 돌아가면서,
이런 식으로 문서가 생성된다!
끝
'우테코 > 요즘카페' 카테고리의 다른 글
공간 인덱스로 조회속도 32배 개선하기(요즘 카페 지도 기능 개발) (2) | 2023.09.17 |
---|---|
이미지 리사이즈 성능 개선하기 (1) | 2023.09.14 |
Java + Spring 이미지 리사이즈 (0) | 2023.09.04 |
RestAssured & @Transactional 방금 저장한 데이터를 못찾아요 (0) | 2023.08.22 |
[요즘카페 트러블슈팅] orElse + JPA 콜라보로 DB가 날라감;; (0) | 2023.08.06 |
댓글