안녕하세요 '누'입니다.
회사에서 백엔드 엔지니어로 일하면서 가장 귀찮고 번거로운 작업은 당연히 API문서를 적는 것이었다.
API 스펙이 변할 때마다 노션 문서를 뒤져서 json 복붙해주고, 관련 설명글을 추가하고 하는 작업이 정말 매우 많이 귀찮았다.
물론 AI한테 MCP 서버를 연결 시켜 주면 그것도 자동화 해주지만 토큰을 발급해서 저장해 줘도 종종 인식하지 못하거나 MCP 서버 자체가 먹통이 되면 아예 동작하지도 않았다.

그래서 그냥 자동으로 컨트롤러를 스캔해서 노션에 문서로 만들어주는 라이브러리를 만들면 편하지 않을까? 하는 생각에 라이브러리를 만들게 되었다.
라이브러리를 만들어 본 적 없는 나는 시작부터 난관에 봉착했다
이거 어떻게 시작해야 하냐...?
스프링 부트 프로젝트와 다르게 단독으로 동작하는게 아니라 라이브러리이기에 다른 어플리케이션에 붙어서 동작하는 구조였다. 기존에 공부해온 구조와 동작 방식이 달랐기에 여기저기 검색도 하고 AI의 도움을 받아서 개발을 시작했다.
가능한 단순하게, 기존 코드를 변경하지 않도록 하기 위해 yml을 통해 토큰과 페이지ID를 받으면 그냥 자동으로 스캔하게 하는 구조를 택했다.
서버가 빌드되면 자동으로 스캔을 하고 노션에 연결하여서 순차적으로 집어넣는 방식이다.

그러나 그렇게 했을 때 request, response 값들을 똑바로 스캔하지 못하거나 BaseResponse 같은 클래스로 감싸는 형태가 되었을 때 이를 잘 인식하지 못하는 문제들이 발생했다.
위와 같은 문제를 해결하기 위해 @NotionDoc라는 어너테이션을 추가하고 거기에 사용자가 더 자세한 데이터들을 직접 주입할 수 있도록 하는 기능을 추가했다.
@NotionDoc(
name = "회원 조회",
description = "ID로 회원을 조회합니다",
auth = {"USER", "ADMIN"},
responses = {
@Response(status = 200, description = "정상 조회", body = MemberResponse.class),
@Response(status = 404, description = "회원 없음", body = ErrorResponse.class),
@Response(status = 403, description = "권한 없음")
}
)
물론 이건 부가 기능이기에 기본적으로도 어느정도 스캔은 가능하게 했으나 성공했거나 실패할 경우. 그리고 실패했다면 그 원인이 무엇인지를 모르기에 만약 이 라이브러리를 사용하게 된다면 @NotionDoc 어너테이션을 적극 활용하는 것을 추천한다.
만들고 나서 보니 뭔가 노션 버전 스웨거 같아서 이상했지만 자동화에는 성공했으니 만족한다.
사용하는 환경에 따라 아래처럼 라이브러리를 불러오면 된다.
Gradle
dependencies {
implementation 'io.github.lgwk42:notion-docs:1.1.0'
}
Maven
<dependency>
<groupId>io.github.lgwk42</groupId>
<artifactId>notion-docs</artifactId>
<version>1.1.0</version>
</dependency>
그 다음에는 YML에서 관련 설정을 해주면 된다.
notion-docs:
api-token: "ntn_your_integration_token" # 노션 API 토큰
parent-page-id: "your-notion-page-id" # 페이지ID
만약 더 자세한 설정이 필요하다면 아래처럼 추가 설정칸을 채워주면 된다.
notion-docs:
enabled: true # 라이브러리 활성화 여부 (기본값: true)
api-token: "ntn_..." # [필수] Notion Integration 토큰
parent-page-id: "abc123..." # [필수] 데이터베이스가 생성될 부모 페이지 ID
database-title: "API Documentation" # 데이터베이스 제목 (기본값: "API Documentation")
sync-on-startup: true # 애플리케이션 시작 시 동기화 (기본값: true)
archive-removed-endpoints: false # 삭제된 엔드포인트의 DB 행을 보관 처리 (기본값: false)
include-packages: # 이 패키지만 스캔 (비어있으면 전체 스캔)
- "com.example.api"
exclude-packages: # 스캔에서 제외할 패키지
- "com.example.internal"
default-domain: "" # @NotionDoc이 없을 때 기본 도메인
default-auth: [] # @NotionDoc이 없을 때 기본 접근 권한
notion-api-version: "2022-06-28" # Notion API 버전
connect-timeout: 5s # HTTP 연결 타임아웃
자세한 사용법과 코드 등은 아래 깃허브 레포지토리에서 확인이 가능하다.
https://github.com/lgwk42/notion-docs
(스타 하나는 저에게 큰 행복을 줍니다)
피드백과 코드 리뷰는 언제든 환영입니다. 달아주시면 정말 감사합니다!