네트워크 통신에서는 아래와 같은 예외적인 상황이 존재할 수 있습니다.
- 같은 요청이 짧은 시간에 두 번 이상 발생한 경우
- 네트워크 순서가 뒤집힌 경우
- 각종 타임아웃
이러한 상황에 맞서 요청하는 쪽은 알 수 없는 에러를 처리해야 하며, 요청 받는 쪽은 멱등성 API를 제공해야 합니다.
아래와 같은 주문요청에 대한 흐름이 있다고 가정합니다.
알 수 없는 에러 처리
대표적으로 read timeout 으로 인해서 응답을 받지 못하였으면, 해당 요청이 성공했는지 실패했는지 명확하게 판단하기 어렵습니다. 주문서버가 결제 요청을 했을 때 결제 서버에서는 성공했지만 주문 서버에서 응답을 제대로 받지 못하여 실패처리로 했다면 결제는 됐는데 주문처리가 되지 않은 이상한 상황이 연출됩니다.
이에 따라서 클라이언트에서 할 수 있는 방법은 아래와 같습니다.
- 즉시 재요청
- 일정 시간 뒤 재요청
- 요청이 성공했는지 확인 후 재요청
- 결제 취소 요청 (보상 트랜잭션)
- 수기로 처리
그러나 알 수 없음 에러에 대한 대응책을 실현하더라도 똑같은 API요청이므로 해당 요청이 다시 재현되지 않을거라는 보장은 없습니다. 무한 루프 에러 처리에 빠질 수 있습니다.
멱등성 API
- 주문 서비스는 후처리를 위해서 결제 서비스에게 동일한 요청을 진행하게 됩니다.
- 결제 서비스에서 이미 성공한 결제 요청이 두 번(혹은 여러 번) 들어왔을 때 실패로 응답할지 성공으로 응답할지 결정해야 합니다.
- 즉 결제 서비스는 결제 요청 API에 대해서 멱등성을 보장해야 합니다.
- 멱등성은 동일한 요청을 여러번 보내도 같은 응답을 줘야한다는 개념입니다.
- 이렇게 같은 요청에 대해서 몇번이고 같은 응답을 준다면 주문 서비스에서는 알 수 없는 오류에 대해서 보상 트랜잭션 요청을 할 경우가 줄어듭니다.
- 여기서 동일한 요청이 무엇인지 정의하는 것은 매우 중요합니다.
방법
멱등성 요청을 수행하려면 요청에 추가 멱등성 키 헤더를 제공하는데 해당 키를 통해서 동일한 요청인지 아닌지를 구분할 수 있습니다. 또한 오용을 방지하기 위해서 키뿐만 아니라 매개변수를 원래 요청과 비교합니다.
- Idempotency-Key: <key>
- 멱등성 키는 클라이언트에 의해서 생성된 고유 값(V4 UUID를 추천 - 랜덤 값 기준, V1 UUID는 timestamp 기준)
- 최소 24시간 이 지나면 시스템에서 자동으로 제거될 수 있으며 제거 된 이후 키를 재사용하면 새 요청으로 간주
결과를 성공 여부에 관계없이 멱등 키에 대한 요청의 상태 코드와 본문을 저장하고 같은 키에 대해서는 500에러를 포함하여 항상 같은 결과를 리턴합니다. 파라미터의 유효성 검사에 실패했다거나 네트워크의 이슈로 API가 실행되지 않은 경우는 따로 저장하지 않습니다.
curl https://api.stripe.com/v1/charges \
-u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \
-H "Idempotency-Key: zl82qVmTBEPhAozq" \
-d amount=2000 \
-d currency=usd \
'Learn business > 방법론' 카테고리의 다른 글
JWT란? (0) | 2021.09.12 |
---|