마이크로서비스 아키텍처에서 각 마이크로서비스 별로 API 문서화는 어떻게 해야할까요? 각 마이크로서비스마다 Swagger나 REST Docs로 문서화를 진행할경우 각 마이크로서비스마다 문서를 별도로 관리해주어야 한다는 문제점이 있습니다.
하나로 통합해서 API문서를 관리해주어야 API를 받아쓰는 프론트 입장에서 편리하겠죠. 하나하나 포트를 다르게 하거나 도메인을 다르게 접근해서 각각 문서를 봐야한다면 굉장히 불편하겠죠.
이번시간에는 spring REST Docs로 각 마이크로서비스에서 문서화를 한 후 이를 Swagger UI를 이용해 API 문서를 통합해보겠습니다.
먼저 spring REST Docs로 문서화하기 게시글을 참고하여 각 마이크로서비스에서 문서화를 해주세요.
이번 게시글은 이전 게시글을 통해 spring REST Docs로 문서화를 진행하는데 성공했다고 가정하고 진행하겠습니다.
spring REST Docs로 문서화를 하였는데 어떻게 Swagger UI로 통합관리가 가능할까요?
누군가 친절하게도 오픈소스를 만들어주었다고 합니다.
우리는 이 오픈소스를 활용하여 spring REST Docs에서 openapi spec을 추출하여 Swagger UI 서버로 보내 API 문서를 통합 관리할 것입니다.
이번 시간에는 Gradle 빌드 환경에서 진행해보겠습니다.
https://github.com/ePages-de/restdocs-api-spec
https://github.com/BerkleyTechnologyServices/restdocs-spec
plugins {
id 'com.epages.restdocs-api-spec' version '0.18.2'
}
dependencies {
testImplementation 'com.epages:restdocs-api-spec-mockmvc:0.16.2'
}
openapi3 {
server = 'https://localhost:8080'
title = 'rest docs + swagger UI'
description = 'My API description'
version = '0.0.1'
format = 'json'
outputFileNamePrefix = 'open-api-3-labeling-service'
outputDirectory = 'src/main/resources/static/docs'
}
이전 spring REST Docs 게시글을 통해 rest docs 관련 빌드 스크립트는 구성되어 있다는 가정 하에 위 내용을 추가해주세요.
추출한 문서는 깃에 추적될 필요가 없습니다. .gitignore
에 출력 경로를 무시해주세요.
//.gitignore
src/main/resources/static/docs/
각 테스트코드에서 문서화를 진행하셨을텐데 딱 하나만!!!!! 임포트문 하나만!!! 변경해주면 됩니다.
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
이것을
import static com.epages.restdocs.apispec.MockMvcRestDocumentationWrapper.document;
이거로 수정합니다. 그럼 다 알아서 해줍니다.
./gradlew openapi3
해당 명령어를 통해 openapi spec을 추출해냅니다.
위와같이 생성된 것 확인 가능합니다.
먼저 원격 Swagger EC2 서버를 미리 준비해주세요.
이후 문서들을 보관할 디렉토리를 먼저 생성 후 해당 디렉토리에 각 서비스에서 추출한 내용(json)을 복사/붙여넣기 합니다.
mkdir docs
cd docs
vi open-api-3-labeling-service.json // 각 마이크로서비스별로 파일을 만들어 붙여넣기
docker pull swaggerapi/swagger-ui
Swagger UI 이미지를 다운받습니다.
sudo docker run -d -p 80:8080 \
--name swagger \
-e URLS_PRIMARY_NAME=Auth \
-e URLS="[{ url: 'docs/open-api-3-auth-service.json', name: 'Auth' }, { url: 'docs/open-api-3-labeling-service.json', name: 'Labeling' }]" \
-v /home/ubuntu/docs:/usr/share/nginx/html/docs/ \
swaggerapi/swagger-ui
Swagger UI 컨테이너를 구동합니다.
-v로 볼륨매핑을 통해 추출만 open api spec이 모여있는 방금 생성했던 디렉토리를 지정합니다.
-e 옵션을 통해 문서를 하나하나 지정해주어야 합니다.
URLS_PRIMARY_NAME
는 처음으로 보여질 URL 환경변수입니다.
URLS
에 추출한 문서를 하나하나 매핑해줍니다.
성공하였습니다.
손쉽게 각 마이크로서비스 별 API문서를 열람할 수 있음을 확인했습니다.
API가 추가되었습니다. 문서도 업데이트 해주어야하겠죠? 기능추가가 한두번 일어나는 것도 아니고 마이크로서비스 개수도 많은데 그럴 때마다 위 과정을 수동으로 해주면 큰일납니다.
Jenkins
나 action
등을 통해 위 과정을 자동화 해주어야 합니다.
저는 이 자동화를 SSH Agent 플러그인을 사용한 젠킨스 파이프라인을 이용해 구현하였습니다.
stage('generate api docs by spring rest docs and send to swagger ui') {
steps {
sh '''
./gradlew openapi3
'''
// swagger UI로 보내는 로직
dir('src/main/resources/static/docs') {
sshagent (credentials: ['{swagger서버관련인증ID}']) { // use SSH Agent
sh """
ssh -o StrictHostKeyChecking=no {리눅스계정명}@{swagger서버접속IP} '
sudo docker container ls
'
"""
sh 'scp ./open-api-3-labeling-service.json {리눅스계정명}@{swagger서버접속IP}:/home/ubuntu/docs' //지정 경로로 파일 이동시켜 문서 변경
}
}
}
post {
success {
echo 'success generate api docs'
}
failure {
error 'fail generate api docs' // exit pipeline
}
}
}
각 마이크로서비스에서 CI / CD 배포 자동화를 하며 위와 같은 파이프라인을 추가해주세요.