API 카탈로그OpenAPI sync 정책

OpenAPI Sync 정책

SPEC #006 §2-4 + architecture/api-contract 정합.

Overview

backend 의 OpenAPI v3 spec (/v3/api-docs) 가 단일 소스. 프론트는 orval 로 TypeScript 클라이언트 + zod schema 자동 생성. 수기 type 정의 금지.

Backend side

linkmusic-msa-space-was/build.gradle.kts:

implementation("org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0")
  • /v3/api-docs — JSON
  • /swagger-ui.html — UI

SecurityConfig:

.requestMatchers("/v3/api-docs/**", "/swagger-ui/**", "/swagger-ui.html")
.permitAll()

Frontend side

packages/api-client/orval.config.ts:

  • mode: tags-split
  • httpClient: fetch
  • mutator: ./src/mutator.ts
  • client: tanstack-query
  • zod: true

/sync-api 명령

pnpm --filter @linkmusic/api-client sync

내부 (packages/api-client/scripts/sync.sh, bash 스크립트):

  1. backend /v3/api-docs JSON fetch (BACKEND_OPENAPI_URL env, default http://localhost:8080/v3/api-docs)
  2. packages/api-client/openapi.json 갱신 + servers 키 제거 (외부 도구가 prod URL 직접 호출 방지)
  3. orval --config orval.config.ts 실행 → src/generated/endpoints/<tag>/* + src/generated/schemas/*
  4. 후처리: endpoints/ 사전순 스캔 → src/generated/index.ts root barrel 재작성 (orval tags-split 가 emit 안 함, idempotent)
  5. consumer 측에서 pnpm -r typecheck 로 깨진 호출부 확인

Drift 검증

생성된 결과는 commit. CI 또는 워크플로우에서:

pnpm sync-api && git diff --exit-code packages/api-client/src/generated

diff 가 있으면 fail — backend / frontend 불일치 표시.

(현재 워크플로우 미구현 — 작성자 의무 + 주기 /factcheck-docs 로 점검)

OpenAPI 변경 → frontend 워크플로우

backend 에서 endpoint / DTO / enum 변경:

  1. backend 변경 + PR develop
  2. develop deploy (또는 로컬 dev 서버)
  3. 프론트 작업 시작 — pnpm sync-api 로 generated 갱신
  4. typecheck 통과까지 호출부 수정
  5. 변경 의미 있는 endpoint 면 docs (api/endpoints.md · features/<해당화면>) 갱신
  6. commit (generated/ 포함)

Validation 일관성

backend OpenAPIminLength · maxLength · pattern 은 zod schema 로 자동 변환:

  • email: 형식 검증
  • password: ≥8
  • businessNumber: regex ^[0-9]{3}-[0-9]{2}-[0-9]{5}$
  • billingAnchorDay: 1~31

프론트 수기 zod 정의 시 backend OpenAPI 와 일치 ([[feedback-8]]).

함정 — null vs undefined

  • backend 가 nullable 로 보낼지 omit 으로 보낼지는 backend 결정
  • 예: name: string | null (수기) vs name?: string (OpenAPI omit) → runtime 분기 다름
  • 수기 alias 금지 — generated 만 사용

Constraints

  • generated 디렉토리는 commit 대상 (drift 검증 위해)
  • 수기 type 정의 금지 ([[feedback-15]])
  • backend 가 단일 소스 — frontend 에서 schema 추가 정의 X

Roadmap

  • CI drift 자동 검증
  • OpenAPI tag 명 컨벤션 (auth · admin-hq · admin-stores · …) 통일
  • OpenAPI changelog 자동 (diff)
  • OpenAPI → docs 페이지 자동 생성 (이 endpoints 페이지)

References

  • SPEC #006 §2-4
  • linkmusic-frontend-space/packages/api-client/orval.config.ts
  • linkmusic-frontend-space/packages/api-client/scripts/sync.sh
  • 워크스페이스 skill /sync-api