REST API는 Postel의 법칙에 따라 후방 호환성을 유지하는 것이 중요하며, 이는 시스템의 견고성을 보장합니다. 🛡️
필수 필드 변경, 데이터 타입 변경, 속성 이름 변경, 날짜 형식 변경, 유효성 검사 추가, Enum 값 변경 등은 클라이언트에게 치명적인 Breaking Change를 유발합니다. 💥
Breaking Change를 피하기 위해 API를 과도하게 복잡하게 만들거나(예: 전화번호를 여러 구성 요소로 분리), map<string, anything>과 같은 모호한 메타데이터/확장 필드를 사용하는 것은 API 품질을 저하시키고 "의미론적 기술 부채"를 증가시킵니다. 🤢
API 버전 관리(예: V2)는 종종 코드에 if version equals와 같은 조건문으로 오염시키고, DTO 및 매퍼의 복사-붙여넣기로 코드 품질을 저하시키므로, 이상적으로는 두 개 이상의 병렬 버전을 지원하지 않는 것이 좋습니다. 🧬
클라이언트를 식별하고 어떤 필드를 사용하는지 파악하기 위해 Oauth 토큰 서비스 계정 외에 Trace ID, Zipkin과 같은 관찰 가능성 도구와 Pact.io 같은 컨슈머 주도 계약 도구를 활용하는 것이 효과적입니다. 🔍
클라이언트에게 V1에서 V2로 업그레이드를 강제할 때는 협박이나 거짓말 대신 마이그레이션 가이드라인, 자동화된 도구(OpenRewrite), 또는 직접적인 협업을 통해 지원하는 것이 바람직합니다. 🤝
미래의 Breaking Change를 피하기 위해 초기부터 API를 과도하게 설계하거나(예: 이메일을 배열로, 전화번호에 타입 필드 추가) map<string, anything>과 같은 스키마 없는 구조를 사용하는 것은 프로젝트 실패의 원인이 될 수 있습니다. 🏗️
REST 창시자 Roy Fielding은 URI에 /v1을 포함하는 것을 비판했으며, 불가피한 Breaking Change 시에는 기존 서비스를 삭제하고 새로운 마이크로서비스(V2)를 설계하는 "삭제를 위한 설계" 원칙을 고려할 수 있습니다. 💀
Breaking Change를 조기에 감지하기 위해 제공자 측에서는 OpenAPI 계약을 Git 버전과 비교하는 승인 테스트를, 클라이언트-서버 간에는 Spring Cloud Contract나 Pact를 통한 컨슈머 주도 계약을, 동종 코드베이스에서는 클라이언트 JAR과 Dependabot/Renovate 같은 봇을 활용한 자동 업그레이드를 적용할 수 있습니다. 🚨
수백만 개의 레코드를 Get by ID로만 노출하는 것은 N+1 문제로 이어져 네트워크, CPU, 메모리에 심각한 성능 저하를 초래합니다. 🐢
성능 문제를 해결하기 위해 여러 ID를 한 번에 처리하는 배치 API를 제공하되, URL 길이 제한을 고려하여 POST 메서드를 사용하고, 응답 페이로드 크기를 관리하며, 클라이언트가 배치 API를 올바르게 사용하도록 유도해야 합니다. 또한, 배치 API는 프로덕션에서 성능 문제가 감지될 때까지는 성급하게 최적화하지 않는 것이 좋습니다. 📦