API 계약 테스트: 빠르게 움직이는 팀에서 깨지는 변경을 방지하는 방법
API 계약 테스트는 웹과 모바일 출시 전에 깨지는 변경을 잡아냅니다. 실용적인 단계, 피해야 할 실수, 빠른 배포 체크리스트를 제공합니다.

왜 API의 깨지는 변경이 릴리스에 자꾸 포함되는가
대부분의 팀은 하나의 API를 여러 클라이언트가 사용하게 됩니다: 웹 앱, iOS 앱, Android 앱, 때로는 내부 도구까지. 모든 팀이 같은 엔드포인트를 쓴다고 합의해도 각 클라이언트는 API를 약간씩 다르게 사용합니다. 어떤 화면은 필드가 항상 존재한다고 기대하는 반면, 다른 화면은 필터가 적용될 때만 그 필드를 사용합니다.
진짜 문제는 이 조각들이 서로 다른 일정으로 배포될 때 발생합니다. 백엔드는 하루에도 여러 번 라이브로 바뀔 수 있고, 웹은 빠르게 배포되지만 모바일 릴리스는 리뷰와 단계적 롤아웃 때문에 느립니다. 그 간격이 놀라운 고장을 만듭니다: API는 최신 클라이언트에 맞춰 변경되었지만, 어제 빌드된 모바일 앱이 아직 사용 중이라 이제 처리할 수 없는 응답을 받습니다.
이럴 때 증상은 거의 항상 분명합니다:
- 필드가 이름이 바뀌거나 옮겨져 화면이 갑자기 비어 보임
- 예상하지 못한 null이나 누락된 객체로 인한 크래시
- 재현하기 어려운 "무언가 고장났음" 지원 티켓
- 백엔드 배포 직후 오류 로그 급증
- 근본 원인 대신 방어 코드를 추가하는 핫픽스 릴리스
수동 테스트와 QA는 이런 문제들을 놓치는 경우가 많습니다. 위험한 경우는 행복 경로(happy path)가 아니기 때문입니다. 테스터는 "주문 생성"이 작동하는지 확인할 수 있지만, 오래된 앱 버전, 부분적으로 채워진 프로필, 드문 사용자 역할, 또는 리스트가 비어 있는 응답 같은 경우를 시도하지 않을 수 있습니다. 캐싱, 기능 플래그, 점진적 롤아웃을 더하면 테스트 계획이 커버할 수 있는 조합보다 더 많은 상황이 생깁니다.
일반적인 예: 백엔드가 로컬라이제이션을 지원하려고 status: "approved"를 status: { code: "approved" }로 바꿉니다. 웹 앱은 같은 날 업데이트되어 정상적으로 보입니다. 하지만 현재 배포된 iOS 버전은 여전히 문자열을 기대하고 있어 응답을 파싱하지 못하고 사용자는 로그인 후 빈 페이지를 보게 됩니다.
이 때문에 API 계약 테스트가 필요합니다: QA를 대체하려는 것이 아니라, "내 최신 클라이언트에서는 동작한다"는 변경이 프로덕션에 도달하기 전에 잡아내는 것입니다.
계약 테스트가 무엇이고, 무엇이 아닌가
계약 테스트는 API 소비자(웹 앱, 모바일 앱 또는 다른 서비스)와 API 제공자(백엔드)가 서로 소통하는 방식을 합의하는 방법입니다. 그 합의가 계약입니다. 계약 테스트는 단 하나의 간단한 것을 확인합니다: 제공자가 소비자가 기대하는 방식으로 계속 동작하는가?
실무에서 API 계약 테스트는 단위 테스트와 엔드투엔드 테스트의 중간에 위치합니다. 단위 테스트는 빠르고 로컬에서 실행되지만, 팀 간 경계에서의 불일치를 놓칠 수 있습니다. 엔드투엔드 테스트는 여러 시스템을 가로지르는 실제 흐름을 검사하지만 느리고 유지보수가 어렵고, 테스트 데이터나 UI 타이밍 같은 관련 없는 문제로 실패하는 경우가 많습니다.
계약은 거대한 문서가 아닙니다. 소비자가 보낼 요청과 받아야 하는 응답을 집중해서 설명한 것입니다. 좋은 계약에는 보통 다음이 포함됩니다:
- 엔드포인트와 메서드(예: POST /orders)
- 필수 및 선택 필드(타입과 기본 규칙 포함)
- 상태 코드와 에러 응답 형태(예: 400 vs 404의 차이)
- 헤더와 인증 기대치(토큰 존재, 콘텐츠 타입)
- 중요한 기본값과 호환성 규칙(필드가 없을 때의 동작)
계약 테스트가 조기에 잡아내는 깨지는 변경의 간단한 예: 백엔드가 total_price를 totalPrice로 이름을 바꿉니다. 단위 테스트는 여전히 통과할 수 있고, 엔드투엔드 테스트는 해당 화면을 커버하지 않거나 나중에 혼란스러운 방식으로 실패할 수 있습니다. 계약 테스트는 즉시 실패하고 정확한 불일치를 가리킵니다.
계약 테스트가 하지 않는 일도 분명히 해야 합니다. 성능 테스트, 보안 테스트, 전체 사용자 여정 테스트를 대체하지 않습니다. 모든 로직 버그를 잡지도 못합니다. 대신 빠르게 움직이는 팀에서 가장 흔한 릴리스 위험을 줄여줍니다: 클라이언트를 조용히 망가뜨리는 작은 API 변경.
백엔드가 자주 생성되거나 변경되는 환경(예: AppMaster 같은 플랫폼에서 API를 재생성할 때)에서는 계약 테스트가 실용적인 안전망이 됩니다. 각 변경 후 클라이언트의 기대가 여전히 유지되는지 검증해 주기 때문입니다.
웹 및 모바일 팀을 위한 계약 접근 방식 선택
웹과 모바일이 자주 배포되는 환경에서 어려운 점은 단순히 "API를 테스트하는 것"이 아니라 각 클라이언트에 대해 무엇이 절대 변경되면 안 되는지를 합의하는 것입니다. 그 부분에서 계약 테스트가 도움이 되지만, 계약의 소유권을 어떻게 할지 선택해야 합니다.
옵션 1: 소비자 주도 계약(CDC)
소비자 주도 계약에서는 각 클라이언트(웹 앱, iOS, Android, 파트너 통합)가 자신이 필요한 것을 정의합니다. 제공자는 그 기대를 만족할 수 있음을 증명합니다.
이 접근은 클라이언트가 독립적으로 움직일 때 잘 작동합니다. 계약이 백엔드 팀의 추측이 아니라 실제 사용을 반영하기 때문입니다. 또한 다중 클라이언트 현실에 적합합니다: iOS는 웹이 사용하지 않는 필드에 의존할 수 있고, 웹은 모바일이 무시하는 정렬이나 페이지네이션 규칙을 중요하게 여길 수 있습니다.
간단한 예: 모바일 앱은 price_cents가 정수일 것을 기대합니다. 웹은 포맷된 가격만 표시하므로 백엔드가 이를 문자열로 바꿔도 전혀 눈치채지 못할 수 있습니다. 모바일에서 만든 CDC는 릴리스 전에 그 변경을 잡아낼 것입니다.
옵션 2: 제공자 중심 스키마
제공자 중심 스키마에서는 백엔드 팀이 하나의 계약(종종 스키마나 명세)을 게시하고 이를 강제합니다. 소비자는 그 단일 진실의 출처를 기준으로 테스트합니다.
이 방법은 API가 공개되어 있거나 컨트롤할 수 없는 여러 소비자와 공유될 때, 또는 팀 간에 엄격한 일관성이 필요할 때 적합합니다. 또한 시작하기가 단순합니다: 하나의 계약, 변경을 검토할 한 곳, 하나의 승인 경로.
선택에 대한 간단한 가이드:
- 클라이언트가 자주 배포되고 API의 다른 부분을 사용하는 경우 CDC를 선택하세요.
- 모든 사람을 위한 안정적인 "공식" 계약이 필요하면 제공자 중심 스키마를 선택하세요.
- 가능하다면 하이브리드를 사용하세요: 기본은 제공자 스키마로 두고, 위험이 큰 엔드포인트 몇 개는 CDC로 보호합니다.
AppMaster 같은 플랫폼으로 빌드한다면 같은 아이디어가 적용됩니다: 웹과 네이티브 모바일 앱을 별도의 소비자로 취급하세요. 같은 백엔드를 공유하더라도, 실제로는 같은 필드와 규칙을 정확히 의존하지 않는 경우가 많습니다.
실제로 계약에 무엇을 넣을까 (진짜 고장을 잡게 하려면)
API 계약은 웹과 모바일 클라이언트가 실제로 의존하는 것을 반영할 때만 도움이 됩니다. 아무도 사용하지 않는 예쁜 명세서는 프로덕션에서 고장을 유발하는 변경을 잡아내지 못합니다.
추측이 아니라 실제 사용에서 시작하세요. 가장 흔한 클라이언트 호출(앱 코드, API 게이트웨이 로그, 또는 팀으로부터의 짧은 목록)을 가져와서 그것들을 계약 사례로 바꾸세요: 정확한 경로, 메서드, 헤더, 쿼리 파라미터, 그리고 전형적인 요청 바디 형태. 이렇게 하면 계약이 작고 관련성이 높으며 논쟁하기 어렵습니다.
성공 응답과 실패 응답 모두를 포함하세요. 팀들은 종종 행복 경로만 계약 테스트하고 에러에 의존하는 경우를 잊습니다: 상태 코드, 에러 형태, 심지어 안정적인 에러 코드/메시지까지. 모바일 앱이 특정 "이미 사용 중인 이메일" 메시지를 보여준다면 계약은 409 응답 형태를 고정시켜 갑자기 400으로 바뀌지 않도록 해야 합니다.
가장 자주 깨지는 부분에 특히 주의하세요:
- 선택 필드 vs 필수 필드: 필드를 제거하는 것보다 선택 필드를 필수로 만드는 것이 더 위험합니다.
- null: 일부 클라이언트는
null을 "없음"과 다르게 처리합니다. 허용 범위를 결정하고 일관되게 유지하세요. - 열거형(enum): 새로운 값을 추가하면 닫힌 목록을 가정한 오래된 클라이언트를 깨뜨릴 수 있습니다.
- 페이지네이션: 파라미터와 응답 필드(
cursor또는nextPageToken등)에 대해 합의하고 안정적으로 유지하세요. - 날짜 및 숫자 형식: 명확히 하세요(ISO 문자열, 정수 센트 등).
계약을 표현하는 방법
팀이 읽기 쉽고 툴링으로 검증할 수 있는 형식을 선택하세요. 일반적인 옵션은 JSON Schema, 예제 기반 계약, 또는 OpenAPI 명세에서 생성된 타입 모델입니다. 실제로는 예제와 스키마 검사가 잘 어울립니다: 예제는 실제 페이로드를 보여주고, 스키마 규칙은 "필드 이름 변경"이나 "타입 변경" 같은 실수를 잡아냅니다.
간단한 규칙: 변경 때문에 클라이언트 업데이트가 필요해진다면, 그 변경은 계약 테스트에서 실패해야 합니다. 이런 사고방식은 계약을 이론적 완벽함이 아니라 실제 깨짐에 집중하게 합니다.
단계별: 계약 테스트를 CI 파이프라인에 추가하기
API 계약 테스트의 목표는 단순합니다: 누군가 API를 변경하면, 해당 변경이 배포되기 전에 어떤 웹이나 모바일 클라이언트를 깨뜨릴지 CI가 알려주게 하는 것입니다.
1) 먼저 클라이언트가 실제로 의존하는 것을 캡처하세요
단일 엔드포인트를 선택하고 실제 사용에서 중요한 기대사항을 적어두세요: 필수 필드, 필드 타입, 허용 값, 상태 코드, 일반적인 에러 응답. 한 번에 전체 API를 설명하려 하지 마세요. 모바일 앱의 경우 오래된 앱 버전의 기대사항도 포함하세요. 사용자는 즉시 업데이트하지 않습니다.
이 작업을 실용적으로 하는 방법은 현재 클라이언트들이 보내는 실제 요청 몇 개(로그나 테스트 픽스처에서)를 가져와 반복 가능한 예제로 바꾸는 것입니다.
2) 계약을 팀이 유지할 위치에 두세요
계약은 잊혀진 폴더에 있으면 실패합니다. 변경하는 코드 가까이에 두세요:
- 한 팀이 양쪽을 소유하면 API 저장소에 계약을 보관하세요.
- 웹, 모바일, API가 서로 다른 팀에 속하면 팀들이 소유하는 공유 저장소를 사용하세요(한 사람이 소유하지 않게).
- 계약 업데이트를 코드처럼 취급하세요: 리뷰, 버전 관리, 논의가 필요합니다.
3) CI의 양쪽에서 검사 추가하기
두 가지 신호를 원합니다:
- 제공자 검증(Provider verification): 모든 API 빌드에서 "API가 알려진 모든 계약을 여전히 만족하는가?"
- 소비자 검사(Consumer checks): 모든 클라이언트 빌드에서 "이 클라이언트가 최신 공개 계약과 여전히 호환되는가?"
이렇게 하면 양쪽 방향에서 문제를 잡습니다. API가 응답 필드를 변경하면 API 파이프라인이 실패합니다. 클라이언트가 새 필드를 기대하기 시작하면 클라이언트 파이프라인이 실패합니다.
4) 실패 규칙을 정하고 강제하세요
무엇이 병합이나 릴리스를 막는지 명확히 하세요. 일반 규칙은: 계약을 깨는 모든 변경은 CI에서 실패하고 메인 브랜치로의 병합을 막는 것입니다. 예외가 필요하면 서면 결정(예: 조정된 릴리스 날짜)을 요구하세요.
구체적 예: 백엔드 변경으로 totalPrice를 total_amount로 바꾸면 제공자 검증이 즉시 실패합니다. 그래서 백엔드 팀은 전환 기간 동안 새 필드를 추가하면서 옛 필드도 유지해 두고, 웹과 모바일은 안전하게 계속 배포합니다.
팀 속도를 늦추지 않는 버전 관리와 하위 호환성
빠른 팀이 API를 가장 자주 깨뜨리는 이유는 기존 클라이언트가 이미 의존하던 것을 변경하기 때문입니다. "깨지는 변경"은 이전에 작동하던 요청을 실패하게 하거나, 클라이언트가 처리할 수 없을 정도로 응답이 의미 있게 달라지게 만드는 모든 것입니다.
다음은 흔한 깨지는 변경입니다(엔드포인트가 여전히 존재하더라도):
- 클라이언트가 읽던 응답 필드를 제거함
- 필드 타입 변경(예:
"total": "12"에서"total": 12로) - 선택 필드를 필수로 바꿈(또는 새 필수 요청 필드 추가)
- 인증 규칙 변경(공개 엔드포인트가 토큰을 필요로 하게 됨)
- 상태 코드나 에러 형태 변경(200 -> 204, 또는 새 에러 포맷)
대부분의 팀은 안전한 대안 선택으로 버전 업 없이 문제를 피할 수 있습니다. 더 많은 데이터가 필요하면 필드를 새로 추가하고 기존 필드는 그대로 두세요. 더 나은 엔드포인트가 필요하면 새 경로를 추가하고 옛 경로는 계속 동작하게 두세요. 유효성 검사를 강화해야 하면 잠시 동안 옛 입력과 새 입력 모두를 받아들이고, 점진적으로 새 규칙을 강제하세요. 계약 테스트는 기존 소비자가 여전히 기대를 받는지를 증명하도록 강제하므로 여기서 도움이 됩니다.
권고된 폐기 정책은 팀 속도를 유지하면서 사용자에게 피해를 주지 않습니다. 웹 클라이언트는 매일 업데이트할 수 있지만 모바일 앱은 리뷰 대기와 느린 채택 때문에 수주간 지연될 수 있습니다. 희망이 아니라 실제 클라이언트 행동을 기준으로 폐기를 계획하세요.
실용적인 폐기 정책 예시는 다음과 같습니다:
- 변경을 조기에 알리기(릴리스 노트, 내부 채널, 티켓)
- 사용량이 합의된 임계값 아래로 떨어질 때까지 옛 동작 유지
- 폐기 중인 경로가 사용될 때 헤더/로그에 경고 반환
- 대부분의 클라이언트가 업그레이드된 것을 확인한 후에만 제거 날짜 설정
- 계약 테스트가 더 이상 활성 소비자가 필요로 하지 않는다고 확인한 후에 옛 동작 삭제
버전 관리는 호환 불가능한 변경(예: 리소스 형태나 보안 모델의 근본적 변화)이 불가피할 때만 사용하세요. 버전 관리는 장기적으로 비용을 증가시킵니다: 두 가지 동작, 두 세트의 문서, 더 많은 엣지 케이스를 유지해야 합니다. 버전은 드물고 신중하게 사용하고, 계약을 사용해 옛 버전이 안전하게 제거될 때까지 두 버전 모두 정직하게 유지되도록 하세요.
흔한 계약 테스트 실수(및 회피 방법)
계약 테스트는 실제 기대를 검사할 때 가장 잘 작동합니다. 많은 실패는 팀이 안전하다고 느끼게 만들면서도 버그는 여전히 프로덕션에 스며들게 하는 몇 가지 예측 가능한 패턴에서 비롯됩니다.
실수 1: 계약을 "화려한 목(mock)"처럼 취급하기
오버-모킹은 고전적인 함정입니다: 계약 테스트는 목으로 만든 제공자 동작 때문에 통과하지만, 실제 서비스가 그걸 실제로 할 수 있는지는 확인하지 못합니다. 배포 후 첫 실제 호출에서 실패합니다.
더 안전한 규칙은 간단합니다: 계약은 실행 중인 제공자(또는 동일하게 동작하는 빌드 아티팩트)에서 검증되어야 하며, 실제 직렬화, 실제 유효성 검사, 실제 인증 규칙을 사용해야 합니다.
자주 보이는 실수와 그 해결책은 다음과 같습니다:
- 과도한 제공자 동작 모킹: 제공자 검증은 스텁 서비스가 아닌 실제 제공자 빌드에 대해 수행하세요.
- 계약을 지나치게 엄격하게 작성: ID, 타임스탬프, 배열 같은 항목에는 유연한 매칭을 사용하세요; 클라이언트가 의존하지 않는 모든 필드를 단정하지 마세요.
- 에러 응답 무시: 최소한 주요 에러 케이스(401, 403, 404, 409, 422, 500)와 클라이언트가 파싱하는 에러 바디 형태를 계약 테스트하세요.
- 소유권 부재: 요구사항이 바뀔 때 누가 계약을 업데이트하는지 지정하고, API 변경의 "완료 정의(definition of done)"에 포함시키세요.
- 모바일 현실 잊기: 최신 빌드와 빠른 Wi‑Fi만 고려하지 말고 느린 네트워크와 오래된 앱 버전도 테스트하세요.
실수 2: 사소한 변경도 막는 깨지기 쉬운 계약
새로운 선택 필드를 추가하거나 JSON 키 순서를 바꿨다고 계약이 실패하면 개발자는 빨간 빌드를 무시하게 됩니다. 그건 목적을 무력화합니다.
"중요한 곳에서는 엄격하고, 그렇지 않은 곳에서는 유연하게"를 목표로 하세요. 필수 필드, 타입, 열거형 값, 유효성 규칙에는 엄격하세요. 추가 필드, 순서, 자연스럽게 변하는 값에는 유연하게 대처하세요.
작은 예: 백엔드가 status를 "active" | "paused"에서 "active" | "paused" | "trial"로 변경했습니다. 모바일 앱이 알 수 없는 값을 크래시로 처리하면 이건 깨지는 변경입니다. 계약은 클라이언트가 알 수 없는 enum 값을 어떻게 처리하는지 확인하거나, 모든 클라이언트가 새 값을 처리할 수 있을 때까지 제공자가 알려진 값만 반환하도록 요구해야 합니다.
모바일 클라이언트는 배포 후 더 오래 남아 있으므로 좀 더 신경 써야 합니다. 변경을 "안전하다"고 부르기 전에 다음을 물어보세요:
- 오래된 앱 버전도 응답을 파싱할 수 있는가?
- 타임아웃 후 재시도하면 무슨 일이 발생하는가?
- 캐시된 데이터가 새 포맷과 충돌하지 않는가?
- 필드가 없을 때의 폴백이 있는가?
API가 자주 생성되거나 빠르게 업데이트된다면(예: AppMaster 포함) 계약은 실용적인 가드레일입니다: 빠르게 움직이면서도 각 변경 후 웹과 모바일 클라이언트가 계속 동작함을 증명할 수 있게 합니다.
배포 전 빠른 체크리스트
API 변경을 병합하거나 배포하기 직전에 이 목록을 사용하세요. 웹과 모바일이 자주 배포될 때 가장 큰 화재를 일으키는 작은 편집들을 잡아내도록 설계되었습니다. 이미 계약 테스트를 사용하고 있다면 이 목록은 계약이 차단해야 할 깨짐에 집중하도록 도와줍니다.
매번 물어볼 5가지 질문
- 클라이언트가 읽는 응답 필드를 추가, 제거, 이름 변경했는가(중첩 필드 포함)?
- 상태 코드가 변경되었는가(200 vs 201, 400 vs 422, 404 vs 410 등) 또는 에러 바디 형식이 바뀌었는가?
- 어떤 필드가 필수/선택 간에 바뀌었는가(또는 "null 허용" vs "반드시 존재"의 변경 포함)?
- 정렬, 페이지네이션, 기본 필터가 바뀌었는가(페이지 크기, 정렬 순서, 커서 토큰, 기본값 등)?
- 제공자와 모든 활성 소비자(웹, iOS, Android, 내부 도구 포함)에 대해 계약 테스트가 실행되었는가?
간단한 예: API가 이전에 totalCount를 반환했고 클라이언트는 이를 사용해 "24개의 결과"를 표시했습니다. 당신은 "리스트에 이미 항목이 있으므로"라며 이것을 제거합니다. 백엔드에서는 아무 문제가 없지만 UI는 일부 사용자에게 빈 화면이나 "0 결과"를 표시하기 시작합니다. 엔드포인트는 200을 반환하지만 이것은 실제로 깨지는 변경입니다.
위 질문 중 어느 것에든 "예"라고 답했다면
배포 전에 다음 확인을 하세요:
- 오래된 클라이언트가 업데이트 없이도 여전히 동작하는가? 그렇지 않으면 하위 호환 경로를 추가하세요(옛 필드 유지 또는 둘 다 지원).
- 클라이언트의 에러 처리 로직을 점검하세요. 많은 앱이 알 수 없는 에러 형태를 "무언가 잘못됨"으로 처리해 유용한 메시지를 숨깁니다.
- 최신 브랜치뿐 아니라 지원하는 모든 릴리스된 클라이언트 버전에 대해 소비자 계약 테스트를 실행하세요.
내부 도구(예: 관리자 패널 또는 지원 대시보드)를 빠르게 빌드한다면 그 소비자들도 포함되었는지 확인하세요. AppMaster로 웹 앱과 모바일 앱을 같은 백엔드 모델에서 생성하는 팀은 스키마의 작은 수정이 배포된 클라이언트를 망가뜨릴 수 있다는 것을 잊기 쉽습니다. 계약이 CI에서 체크되지 않으면 문제가 생길 수 있습니다.
예: 웹과 모바일이 배포되기 전에 깨지는 변경을 잡아내기
흔한 설정을 상상해 보세요: API 팀은 하루에 여러 번 배포하고, 웹 앱은 매일 배포하며, 모바일 앱은 앱 스토어 리뷰와 단계적 롤아웃 때문에 주간 단위로 배포됩니다. 모두 빠르게 움직이므로 실제 위험은 악의가 아니라 작지만 무해해 보이는 변경이 문제를 일으키는 것입니다.
지원 티켓으로 사용자 프로필 응답의 명확한 명명 요청이 들어옵니다. API 팀은 GET /users/{id}의 필드 이름을 phone에서 mobileNumber로 바꿉니다.
이름 변경은 깔끔하게 보일 수 있지만 깨지는 변경입니다. 웹 클라이언트는 프로필 페이지에서 전화번호가 비어 보일 수 있습니다. 더 나쁜 경우 모바일 클라이언트는 phone을 필수로 취급하면 크래시가 발생하거나 프로필 저장 시 유효성 검사가 실패할 수 있습니다.
계약 테스트가 있다면 이 변경은 사용자에게 가기 전에 잡힙니다. 검사 방식에 따라 일반적으로 다음과 같이 실패합니다:
- 제공자 빌드 실패(백엔드 측): API CI 작업이 웹과 모바일의 저장된 소비자 계약을 기준으로 제공자를 검증합니다. 소비자가 여전히
phone을 기대하는데 제공자가mobileNumber만 반환하면 검증이 실패하고 배포가 차단됩니다. - 소비자 빌드 실패(클라이언트 측): 웹 팀이 API가 배포되기 전에
mobileNumber를 요구하도록 계약을 업데이트하면, 해당 계약 테스트가 제공자가 아직 그 필드를 제공하지 않기 때문에 실패합니다.
어느 쪽이든 실패는 조기에, 크게, 구체적으로 발생합니다: 정확한 엔드포인트와 필드 불일치를 가리키지 프로덕션에서 "프로필 페이지가 깨졌다"는 식으로 나타나지 않습니다.
수정은 보통 간단합니다: 파괴적 변경 대신 추가적 변경으로 만드세요. API가 두 필드를 모두 반환하도록 합니다:
mobileNumber추가phone은 별칭으로 유지(같은 값)- 계약 노트에
phone을 폐기 예정으로 표시 - 웹과 모바일이
mobileNumber를 읽도록 업데이트 - 대부분의 지원되는 클라이언트 버전이 이동한 것을 확인한 후
phone제거
압박이 있는 현실적인 타임라인 예시는 다음과 같습니다:
- 월 10:00: API 팀이
mobileNumber를 추가하고phone을 유지. 제공자 계약 테스트 통과. - 월 16:00: 웹이
mobileNumber로 전환하고 배포. - 목: 모바일이
mobileNumber로 전환하고 릴리스를 제출. - 다음 화요일: 모바일 릴리스가 대부분의 사용자에게 도달.
- 다음 스프린트: API가
phone을 제거하고 계약 테스트가 더 이상 해당 소비자를 필요로 하지 않음을 확인.
이것이 핵심 가치입니다: 계약 테스트는 "깨질지 모르는 룰렛"을 통제된 시간 기반 전환으로 바꿉니다.
빠르게 움직이는 팀을 위한 다음 단계(노코드 옵션 포함)
계약 테스트가 실제로 고장을 예방하게 하려면(단순히 더 많은 검사를 추가하는 것이 아니라) 도입을 작게 시작하고 소유권을 명확히 하세요. 목표는 단순합니다: 깨지는 변경이 웹 및 모바일 릴리스에 도달하기 전에 잡아내는 것입니다.
가볍게 롤아웃 계획을 시작하세요. 변경 시 가장 큰 문제를 일으키는 상위 3개 엔드포인트(보통 인증, 사용자 프로필, 핵심 리스트/검색 엔드포인트)를 선택해 먼저 계약으로 보호하고 팀이 워크플로를 신뢰하게 되면 확장하세요.
관리 가능한 실용적 롤아웃 예시:
- 1주차: 상위 3개 엔드포인트에 대한 계약 테스트를 각 풀 리퀘스트에서 실행
- 2주차: 모바일 사용량이 많은 다음 5개 엔드포인트 추가
- 3주차: 에러 응답과 엣지 케이스(빈 상태, 유효성 오류) 커버
- 4주차: 백엔드 변경의 릴리스 게이트로 "계약 통과" 조건 추가
다음으로 누가 무엇을 할지 결정하세요. 누가 실패를 처리하고 누가 변경을 승인할지 분명할 때 팀이 더 빠르게 움직입니다.
역할은 단순하게 유지하세요:
- 계약 소유자: 보통 백엔드 팀, 동작이 바뀔 때 계약 업데이트 책임
- 소비자 리뷰어: 웹 및 모바일 리드가 변경이 자신의 클라이언트에 안전한지 확인
- 빌드 셜리프(build sheriff): 매일 또는 매주 순환, CI에서 계약 테스트 실패를 분류
- 릴리스 오너: 계약이 깨지면 릴리스를 차단할지 결정
모두가 신경 쓸 수 있는 하나의 성공 지표를 추적하세요. 많은 팀에게 가장 좋은 신호는 릴리스 후 핫픽스 감소와 앱 크래시, 빈 화면 또는 체크아웃 실패 같은 "클라이언트 회귀" 감소입니다.
더 빠른 피드백 루프가 필요하면 노코드 플랫폼이 변경으로 인한 드리프트를 줄이는 데 도움이 될 수 있습니다. 로직이나 데이터 모델이 바뀔 때 재생성하면 행동을 의도치 않게 바꾸는 패치를 쌓는 일을 피할 수 있습니다.
AppMaster로 API와 클라이언트를 빌드한다면, 다음 실용적 단계는 애플리케이션을 생성하고 Data Designer(PostgreSQL)에서 데이터를 모델링한 다음 Business Process Editor에서 워크플로를 업데이트하고 빌드를 재생성해 클라우드에 배포(또는 소스 코드 내보내기)하는 것입니다. 이를 CI의 계약 검사와 결합하면, 재생성된 각 빌드가 웹과 모바일이 기대하는 동작과 여전히 일치함을 증명할 수 있습니다.


