재시도와 실패 상황을 포함한 API 설계

주문 생성 요청의 응답이 끊기면 클라이언트는 주문이 접수됐는지 알 수 없습니다. API 개발자는 주문 상태를 확인할 방법과 안전하게 재시도할 조건을 정해야 합니다. 성공 응답의 필드만 정의해서는 이 상황을 처리할 수 없습니다.
주문 API는 응답을 잃은 재시도에서도 중복 주문을 만들지 않아야 합니다. 목록 API는 데이터가 추가되는 동안에도 정한 순서와 페이지 크기를 지켜야 합니다. avrl이 정리한 API 설계 개념을 이 두 상황과 오류 처리에 연결해 살펴보겠습니다.
API 계약은 클라이언트가 보낼 요청과 서버에서 기대할 결과를 정한 규칙입니다. 주문 생성에서는 성공 응답의 필드, 중복 요청의 처리, 대기 시간과 오류 응답이 여기에 포함됩니다.
응답을 잃은 주문 요청
주문 생성 요청을 보낸 뒤 응답이 끊겼다고 가정해보겠습니다. 서버가 주문을 만들기 전에 실패했는지, 만든 뒤 응답만 전달하지 못했는지 클라이언트는 알 수 없습니다. 이때 단순 재시도는 같은 주문을 다시 만들 수 있습니다.
멱등성은 같은 요청을 반복했을 때 의도한 서버 상태 변화가 한 번 실행했을 때와 같은 성질입니다. 모든 응답 바이트가 같아야 한다는 뜻은 아닙니다. 이 정의는 HTTP 명세의 멱등 메서드 설명에 나옵니다. 주문 생성에 쓰는 POST는 메서드 자체로 멱등성을 보장하지 않으므로, 중복 효과를 막으려면 요청을 식별하는 키와 처리 결과를 연결하는 등의 설계가 필요합니다.
키를 도입한다면 유효 기간, 같은 키로 다른 내용을 보냈을 때의 처리, 동시에 들어온 요청의 처리를 정해야 합니다. 예를 들어 Stripe의 멱등 요청 API는 기존 요청과 매개변수를 비교하고 결과를 재사용합니다. 키 필드 하나를 추가하는 것으로 중복 처리가 해결되지는 않습니다.
타임아웃과 재시도도 함께 설계합니다. 타임아웃은 기다릴 시간을 제한하며, 이미 진행 중인 서버 작업이 반드시 취소됐음을 뜻하지 않습니다. 재시도 가능한 오류를 구분하고, 횟수와 대기 시간을 제한해야 합니다. 실패한 요청을 모두 즉시 반복하면 서버가 복구할 시간을 줄일 수 있습니다.

직접 작성한 멱등 키 K의 요청 예시입니다. 응답이 유실되면 클라이언트는 생성 여부를 알 수 없으므로 같은 입력과 키로 재시도합니다.
데이터가 바뀌는 목록의 순서
목록 API에는 페이지네이션, 필터, 정렬을 함께 정의합니다. offset 방식은 앞에서 몇 개를 건너뛸지 지정합니다. 커서 방식은 특정 위치 이후의 결과를 요청합니다. 데이터가 바뀌는 상황에서 어느 방식을 사용할지 판단하려면 중복과 누락을 어디까지 허용할지도 정해야 합니다.
예를 들어 생성 시각만으로 정렬하면 시각이 같은 항목의 순서가 불안정할 수 있습니다. 고유 ID를 추가 정렬 기준으로 두고 커서에도 필요한 값을 포함하는 식으로 순서를 명확히 합니다. 페이지 크기의 최대값도 정해 한 요청이 자원을 과도하게 사용하지 않도록 합니다.
필터와 정렬 필드는 허용 목록으로 관리합니다. 응답의 일부 필드만 선택하는 기능은 전송량을 줄일 수 있지만, 숨겨야 할 필드를 요청할 수 있게 해서는 안 됩니다. 필드 선택과 접근 권한은 별도로 검증해야 합니다.
오류 응답 뒤의 사용자 행동
오류 응답은 클라이언트가 다음 행동을 결정할 수 있게 구성합니다. “오류가 발생했습니다”만 반환하면 재시도할지, 입력을 수정할지 판단하기 어렵습니다. 서버가 오류 코드, 사람이 읽을 설명, 관련 필드, 요청 추적 정보를 일관되게 반환하면 클라이언트 개발자가 오류별 처리를 구현할 수 있습니다.
내부 스택이나 비밀을 공개할 필요는 없습니다. 사용자가 취할 행동을 설명하는 정보와 운영자가 조사할 정보는 목적이 다릅니다. 같은 오류 구조를 여러 API에서 유지하면 클라이언트의 예외 처리도 반복해서 만들 필요가 줄어듭니다.
요청 제한은 호출 빈도와 자원 사용을 제어하는 장치입니다. 제한 기준과 초과 시 응답을 정하되, 이것만으로 모든 서비스 거부 공격을 막는다고 보기는 어렵습니다.
공통 기능과 변경의 책임
API Gateway는 인증, 라우팅, 요청 제한 같은 공통 기능을 처리하는 진입점으로 사용할 수 있습니다. 그래도 개별 서비스의 데이터 권한과 업무 규칙까지 자동으로 해결되지는 않습니다.
응답에 다음 행동의 링크를 제공하는 HATEOAS는 클라이언트가 가능한 동작을 탐색하도록 돕는 방식입니다. 모든 API에 같은 수준으로 적용할 필요는 없지만, 상태에 따라 가능한 작업이 달라질 때 검토할 수 있습니다.
API 개발자는 기존 클라이언트에 영향을 주는 변경의 전환 기간을 정합니다. 필드 삭제, 필드 의미 변경, 오류 처리 변경을 구분해 전달해야 클라이언트 개발자가 수정할 부분을 알 수 있습니다.
주문 화면의 검증에는 응답 유실과 같은 키의 재시도를 포함합니다. 재시도 후 주문이 중복 생성되지 않는지 확인하고, 화면에 주문 상태와 다음 행동이 표시되는지 검사합니다. 서버의 중복 처리와 화면의 상태 안내를 함께 확인해야 합니다.