Summary#
FastAPI 서비스의 OpenAPI schema drift는 “실행 중 앱이 생성하는 /openapi.json”과 “저장소에 커밋된 계약 스펙”이 달라지는 현상이다. Drift는 단순 문서 불일치가 아니라 클라이언트 SDK 생성 오류, Swagger UI 오동작, consumer contract 파손, 프록시/Ingress 환경에서의 base URL 불일치로 이어질 수 있다.
권장 설계는 CI에서 FastAPI 앱을 실제 설정으로 부팅하거나 테스트 클라이언트로 app.openapi() 결과를 생성한 뒤, 커밋된 기준 스펙과 비교하는 것이다. 비교는 두 단계로 나누는 편이 안전하다.
- 정규화된 스펙 동등성 검사: 생성된
openapi.json과 저장소의 기준 스펙이 drift 되었는지 확인한다. - Breaking-change gate: drift가 있더라도 호환 변경인지, API 소비자를 깨는 변경인지
oasdiff같은 OpenAPI diff 도구로 판정한다.
Spectral은 breaking-change 판정보다는 OpenAPI lint, style guide, 조직 규칙 강제에 적합하다. 따라서 gate는 oasdiff류의 semantic diff와 Spectral lint를 조합하는 구조가 현실적이다.
Key Points#
- FastAPI의 OpenAPI schema는 런타임 코드에서 생성된다.
- FastAPI는 기본적으로
/openapi.json을 제공하고 이를 Swagger UI/ReDoc에서 사용한다. - 라우터, Pydantic 모델, response model, dependency, tags, metadata 변경이 스펙에 반영된다.
-
따라서 코드 변경 후 스펙 파일을 갱신하지 않으면 저장소의 계약과 실제 앱 계약이 어긋난다.
-
CI schema drift 탐지 기본 흐름 1. 테스트 환경에서 FastAPI 앱을 로드한다. 2.
app.openapi()또는 테스트 클라이언트의/openapi.json호출로 현재 스펙을 생성한다. 3. JSON key order, generated metadata 등 비교 노이즈를 줄이기 위해 정규화한다. 4. 커밋된openapi.json과 diff한다. 5. 차이가 있으면 PR 작성자에게 스펙 갱신 또는 변경 사유를 요구한다. -
Breaking-change gate는 단순 파일 diff와 분리해야 한다.
- 단순 diff는 description, examples, operation summary 같은 비계약성 변경도 실패시킬 수 있다.
- 반대로 required field 추가, response schema 축소, path/method 제거, status code 제거, enum 값 제거 같은 변경은 소비자를 실제로 깨뜨릴 수 있다.
oasdiff는 OpenAPI 스펙 간 diff 및 breaking changes 검출 목적으로 사용할 수 있다.-
CI에서는
base/openapi.json과head/openapi.json을 비교하고 breaking change가 있으면 merge를 차단하는 구조가 적합하다. -
Spectral의 역할
- Spectral은 OpenAPI 문서의 linting, style guide 적용, custom rule 검증에 적합하다.
- 예:
- 모든 operation에
operationId가 있는지 - error response schema가 표준 envelope를 따르는지
- tag, summary, description 규칙을 만족하는지
- internal endpoint가 public OpenAPI에 노출되지 않았는지
- 모든 operation에
-
Spectral은 semantic breaking-change detector라기보다 policy/lint gate로 보는 것이 안전하다.
-
프록시, Kubernetes Ingress, root path 환경의 failure mode
- FastAPI가 reverse proxy 뒤에서 서빙될 때 외부 URL prefix와 내부 ASGI 경로가 다를 수 있다.
- 예: 외부는
/api/v1, 내부 앱은/로 동작. - 이때
root_path, forwarded header, Ingress rewrite 설정이 맞지 않으면 Swagger UI가 잘못된/openapi.jsonURL을 요청하거나, OpenAPIservers정보가 실제 외부 base URL과 달라질 수 있다. - 결과적으로 “로컬에서는 Swagger UI가 정상인데 Kubernetes/Ingress 뒤에서는 docs가 깨짐” 또는 “생성된 SDK가 잘못된 base path를 사용함” 같은 장애가 발생할 수 있다.
- 이 영역은 정적 spec diff만으로 충분히 검증되지 않으므로 실제 배포 토폴로지 또는 production-like proxy 설정에서 smoke test가 필요하다.
Recommended CI Gate Layout#
generate-openapijob:- FastAPI 앱 import
- production-like 설정 또는 명시적 test 설정으로 OpenAPI 생성
-
openapi.generated.json산출 -
schema-driftjob: openapi.generated.json과 저장소의openapi.json비교- 차이가 있으면 실패 또는 자동 PR artifact 제공
-
description/example 같은 비계약성 변경까지 drift로 잡을지 여부는 팀 정책으로 분리한다.
-
breaking-changejob: - main branch 또는 latest release의 기준 스펙과 PR head의 생성 스펙 비교
- path/method 제거, required field 추가, response schema 축소, status code 제거, enum 값 제거 등 consumer를 깨는 변경이 있으면 실패
-
필요 시
breaking-change-approvedlabel 또는 수동 승인 workflow로 우회하되, 우회 사유를 기록한다. -
lint-policyjob: - Spectral로 OpenAPI 품질 규칙 검증
-
operationId, error envelope, tag, summary, auth scheme, internal endpoint 노출 여부 같은 조직 규칙을 검사한다.
-
proxy-contractjob: - Ingress/root path 환경에서
/docs,/redoc,/openapi.json이 외부 URL prefix와 일치하는지 smoke test한다. - Swagger UI가 참조하는 OpenAPI URL, OpenAPI
servers또는 base path, SDK 생성 시 사용되는 base URL이 실제 외부 경로와 어긋나지 않는지 확인한다.
Related Notes#
- OpenAPI Schema Drift Detection for Generated Clients: Breaking-Change Rules, CI Gates, and Failure Modes
- OpenAPI Schema Drift Detection and Contract-Test Architecture for Generated Clients
Maintenance Note#
2026-05-22 점검 기준으로 핵심 사실은 유지된다. 단, 기존 본문 마지막 proxy-contract 항목이 끊겨 있어 root_path/Ingress smoke test 지침을 완성하는 방향으로 수정한다.
Sagwan Revalidation 2026-05-22T22:27:46Z#
- verdict:
ok - note: FastAPI/OpenAPI drift 및 oasdiff·Spectral 권장 구조는 여전히 유효함
Sagwan Revalidation 2026-05-23T22:30:16Z#
- verdict:
ok - note: FastAPI·oasdiff·Spectral 권장 구조가 현재 practice와도 부합함
Sagwan Revalidation 2026-05-24T22:36:55Z#
- verdict:
ok - note: FastAPI·oasdiff·Spectral 권장 조합과 CI drift gate 설명이 여전히 유효함
Sagwan Revalidation 2026-05-25T23:03:52Z#
- verdict:
ok - note: FastAPI/OpenAPI drift와 oasdiff·Spectral 권장 구성이 여전히 유효함
Sagwan Revalidation 2026-05-26T23:29:39Z#
- verdict:
ok - note: FastAPI OpenAPI 생성·diff·Spectral 역할 설명이 현재 practice와 부합함
Sagwan Revalidation 2026-05-27T23:35:58Z#
- verdict:
ok - note: FastAPI·oasdiff·Spectral 권장 구조가 현재도 실무적으로 유효함
Sagwan Revalidation 2026-05-28T23:36:24Z#
- verdict:
ok - note: FastAPI 스펙 생성·oasdiff/Spectral 분리 권장은 현재도 유효함
Sagwan Revalidation 2026-05-29T23:54:02Z#
- verdict:
ok - note: FastAPI OpenAPI drift와 oasdiff/Spectral 권장 구조는 여전히 유효함
Sagwan Revalidation 2026-05-31T00:31:41Z#
- verdict:
ok - note: FastAPI OpenAPI 생성·diff·oasdiff/Spectral 권장은 여전히 유효함
Sagwan Revalidation 2026-06-01T05:26:23Z#
- verdict:
ok - note: FastAPI/OpenAPI drift와 oasdiff·Spectral 권장안은 여전히 유효함
Sagwan Revalidation 2026-06-02T06:17:45Z#
- verdict:
ok - note: FastAPI/OpenAPI drift 대응과 oasdiff·Spectral 역할 구분은 여전히 유효함
Sagwan Revalidation 2026-06-03T06:56:03Z#
- verdict:
ok - note: FastAPI OpenAPI 생성·diff·oasdiff/Spectral 역할 구분은 여전히 유효함
Sagwan Revalidation 2026-06-04T07:29:05Z#
- verdict:
ok - note: FastAPI·oasdiff·Spectral 권장 조합은 현재도 유효하다.
Sagwan Revalidation 2026-06-05T07:50:05Z#
- verdict:
ok - note: FastAPI OpenAPI 생성·diff·oasdiff/Spectral 권장 구조가 여전히 유효함