들어가며

안녕하세요. 트렌비 스토어팀에서 백엔드 개발을 맡고 있는 오언입니다.

최근 마이크로 서비스 환경에서 API 문서를 효율적으로 관리할 수 있는 공용 API 문서 서버를 구축하였고 이에 대한 내용을 공유하고자 합니다.

1. API 문서를 효율적으로 관리할 수 없을까?

API를 제공하거나 사용하는 개발자들에게 있어서 API 명세를 정리하고 공유하는 것은 주요한 업무 중 하나입니다.

백엔드 개발자가 생성한 API를 프론트엔드 개발자에게 전달해줄 때, 다른 도메인 팀과 API 명세를 주고받을 때 등 개발자 간의 효율적인 소통은 잘 정리된 API 문서를 통해서 이루어지게 됩니다.

트렌비에서는 API 문서를 관리하는 데 있어서 정해진 규칙이 존재하지 않았습니다. 서비스에 따라 Swagger나 Spring Rest Docs와 같은 API 문서화 도구를 통해 문서를 관리하고 있거나 노션에 API 명세를 정리를 해두는 등 각양각색의 방법이 혼재되어 있었습니다. 이로 인해 API 문서를 공유하는데 혼란이 있었고 비효율적인 커뮤니케이션이 추가로 발생하였습니다.

API 문서를 효율적으로 관리하는 방법을 고민하던 중에 2020년에 NHN에서 진행되었던 한 컨퍼런스 영상에서 이에 대한 좋은 아이디어를 얻을 수 있었습니다. NHN에서도 마찬가지로 MSA 환경에서 API 문서 관리 방법에 대해 고민하였고, 이에 대한 해결책으로 Swagger와 Spring RestDocs로 만들어진 API 문서 형식을 하나의 OpenAPI 형식으로 통일하여 한 곳에서 관리하도록 처리했다는 것을 확인할 수 있었습니다.

이 아이디어를 기반으로 하여 트렌비에서도 API 문서가 통합되고 자동으로 관리될 수 있는 공용 API 문서 서버를 구성하였습니다.

2. API 문서 형식 통일하기

API 문서를 효율적으로 관리하기 위해서는 우선 다양한 형식의 문서를 통일된 형식으로 맞출 필요가 있었습니다.

트렌비의 많은 서비스는 Swagger나 Spring RestDocs로 문서 관리를 하고 있었기 때문에 NHN 컨퍼런스에서 소개한 방법으로 많은 서비스들을 하나의 OpenAPI 형식으로 통합할 수 있었습니다.

또한 기존에 Swagger가 적용되어 있는 프로젝트에서는 OpenAPI 문서 형식이 기본 포맷이므로 별도의 작업이 필요 없고, Spring Rest Docs 코드에서도 오픈소스를 이용하면 적은 비용으로 OpenAPI 문서를 생성할 수가 있어 쉽게 마이그레이션이 가능하다는 장점이 있었습니다.

Spring Rest Docs에서 OpenAPI 문서 생성하기

Spring RestDocs에서는 AsciiDoc이나 Markdown 문법을 지원하고 이를 통해 쉽게 HTML 기반의 문서 파일을 만들어낼 수 있습니다. 기본적으로 OpenAPI 형식의 문서 파일을 만들어 낼 수는 없지만 restdocs-api-spec 오픈 소스로 손쉽게 OpenAPI 형식의 문서 파일을 생성할 수 있습니다.

이 오픈 소스를 활용하면 Spring Rest Docs 기반의 테스트 코드와 거의 동일하게 작성할 수 있고, 기존에 작성되어 있는 Spring Rest Docs 기반의 테스트 코드에서도 import 문을 변경하는 최소한의 코드 수정으로 손쉽게 OpenAPI 스펙으로 마이그레이션이 가능합니다.

import static com.epages.restdocs.apispec.MockMvcRestDocumentationWrapper.document
// import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document

resultActions
  .andDo(
    document(operationName,
      requestFields(fieldDescriptors().getFieldDescriptors()),
      responseFields(
        fieldWithPath("comment").description("the comment"),
        fieldWithPath("flag").description("the flag"),
        fieldWithPath("count").description("the count"),
        fieldWithPath("id").description("id"),
        fieldWithPath("_links").ignored()
      ),
      links(linkWithRel("self").description("some"))
  )
);

이후 다음과 같은 Gradle 플러그인 명령어를 실행하면 Spring Rest Docs 기반의 테스트 코드로부터 OpenAPI 문서를 생성할 수 있습니다.

./gradlew openapi3 --no-build-cache


3. 통합된 API 문서를 자동으로 관리하기

트렌비와 같은 MSA 환경에서는 도메인별로 서버가 분산되어 있기 때문에 API 문서도 서버별로 분산되어 있습니다. API 문서를 공유하기 위해서는 각 도메인에 있는 문서를 하나하나 URL로 전달해야 한다는 불편함이 있고 개별 문서를 찾아보거나 관리하는 것도 쉽지 않습니다.

API 문서를 한 곳에서 조회하고 관리한다면 이러한 불편함이 줄어들지 않을까요?

앞서 API 문서 형식을 OpenAPI 형식으로 통일했기 때문에 Swagger UI와 함께 사용한다면 통합된 API 문서를 관리 할 수 있습니다.

Swagger UI

Swagger UI를 이용하면 OpenAPI 문서를 UI로 시각화할 수 있고 API 요청을 직접 테스트해볼 수 있습니다.

Swagger UI는 복수 개의 OpenAPI 문서 조회가 가능하므로 모든 OpenAPI 문서를 하나의 Swagger UI 서버에서 조회하게 할 수 있습니다.

Swagger UI 화면에서 셀렉트 박스를 클릭하면 각 도메인별로 API 문서 조회가 가능한 것을 보실 수 있을 것입니다.

하지만 API 문서를 한 곳에서 관리하기 위해서는 한 저장소로 업로드하는 과정이 필요하고 API 문서가 업데이트될 때마다 재업로드하는 과정이 필요하기 때문에 이를 수작업으로 하는 데는 많은 번거로움이 요구됩니다.

그렇기 때문에 API에 변경이 생겼을 때 업데이트된 API 문서를 자동으로 반영해줄 수 있는 CI/CD를 구성하였습니다.

CI/CD를 통해 자동으로 API 문서 관리하기

트렌비에서는 마이크로 서비스를 빌드, 배포할 때 Github Action을 주로 활용하고 있기에 Github Action으로 API 문서 관리를 위한 CI/CD 파이프라인을 구성하였습니다.

CI/CD 파이프라인에 의해 서비스를 개발 환경에 배포할 때마다 API 문서 파일을 생성하고 AWS S3 버킷에 업로드 하는 로직을 추가하여 자동으로 문서가 업데이트될 수 있도록 처리하였습니다.

저희의 경우 개발 환경에만 API 문서 서버를 구축하였는데, Swagger UI에서 쉽게 API 테스트를 할 수 있다 보니 운영 환경에서 API를 테스트할 수 있게 하면 실제 상용 데이터가 변경되는 이슈가 발생할 수 있기 때문이었습니다. 또, 개발 중인 API의 문서를 주로 공유한다는 점에서 개발 환경에서만 구축하는 것으로 충분하다고 판단했습니다.

Github Action 배포 파이프라인

jobs:
build-deploy:
steps:
- name: Upload OpenApi Specification to S3
run: |
  # OpenAPI 형식의 yaml 파일 생성
  ./gradlew openapi3 --no-build-cache

  # Amazone S3에 OpenAPI 문서 파일 업로드
  aws s3 cp openapi3.yaml s3://{bucket}/(문서파일 이름}.yam
env:
  AWS_ACCESS_KEY_ID: $
  AWS_SECRET_ACCESS_KEY: $
  AWS_REGION: ap-northeast-2


전체적인 구성도 사용자가 개발 환경에 서비스 배포 요청을 하면 Github Action의 workflow 파이프라인이 수행되어 어플리케이션의 이미지가 빌드되고 배포되는 동시에 최신 API 문서도 S3로 업로드됩니다.

API 문서 서버에서는 S3에 있는 API 문서 파일을 조회해서 UI 화면에 렌더링해서 최신의 API 문서를 시각화하여 보여주게 됩니다.

4. 후기

Spring RestDocs의 장점인 테스트 코드로 검증된 API 문서와 Swagger의 장점인 UI 화면에서 손쉽게 API 테스트가 가능하다는 이 두 가지 장점을 모두 취해 보다 편리하고 검증된 API 문서 서버를 구축할 수 있었습니다.

또, 통합된 API 문서 서버를 구축하고 여러 도메인 팀의 개발자들이 API 문서 표준화에 힘써준 덕분에 트렌비의 분산된 많은 도메인 API를 한 곳에서 확인할 수 있게 되었습니다. API 명세를 공유하기 위해 하나의 API 문서 서버 주소를 사용하게 되면서 제공하는 입장이나 사용하는 입장에서 불필요한 의사소통을 줄일 수 있게 되었으며, 손쉽게 사이트에서 API 테스트를 할 수 있어서 개발 편의성이 증가하였습니다.

트렌비와 비슷한 MSA 환경에서 API 문서를 효율적으로 관리하는 것을 고민하고 있다면 위와 같은 방법을 고려해보는 것도 좋을 것 같습니다.

참고자료

[NHN FORWARD 2020] MSA 환경에서 API 문서 관리하기: 생성부터 배포까지
https://github.com/aws-actions/configure-aws-credentials
https://github.com/swagger-api/swagger-ui/blob/master/docs/usage/installation.md