Skip to content
isdnetworks
Go back

찾다가 관련 API 둘을 더 발견했다

(수정됨)

주문 상태를 조회하는 API 하나를 찾았고 그것만 쓰면 되는 상황이었는데 openapi.json 을 보다가 옆에 둘이 더 있는 것을 봤다.

GET /v1/orders/{id}/status
GET /v1/orders/status/bulk      ← 여러 건 한 번에
POST /v1/orders/status/webhook  ← 바뀌면 알려 준다

Table of contents

Open Table of contents

상황 — 주변에 있던 둘

셋의 성격이 서로 달랐다. 단건 조회는 지금 상태를 알려 주고 bulk 는 여러 건을 한 번에 주며 webhook 은 값이 바뀌는 시점에 먼저 알려 준다.

우리가 하려던 것은 상태가 바뀌면 그것을 반영하는 일이었다. 단건 조회로 하려면 cron 으로 계속 물어봐야 하는데 웹훅이 있으면 그럴 필요가 없다. 찾던 것보다 주변에 있던 것이 목적에 더 맞았다.

판단 기준 — 셋의 성격 차이

웹훅을 주 수단으로 붙이고 나니 밖으로 나가는 호출량이 크게 줄었다. 5분마다 수만 건을 조회하던 것이 바뀔 때만 하루 수백 건을 받는 것으로 바뀌어 호출이 몇 자릿수 줄었다.

다만 웹훅만 믿지는 않았다. 우리 서버가 죽어 있거나 상대가 못 보내거나 망에 문제가 생기면 아무것도 안 온다. 웹훅은 빠른 대신 안 왔다는 사실이 아무 흔적을 남기지 않는다.

조치 — 웹훅과 대조 조회의 병행

bulk 조회를 하루 한 번 돌려 우리 쪽 상태와 array_diff_assoc() 으로 대조했다.

$ours = $this->orderRepo->statusMap($orderIds);
$theirs = $this->api->bulkStatus($orderIds);
$diff = array_diff_assoc($theirs, $ours);
if ($diff) {
    Log::warning('웹훅 누락', ['count' => count($diff)]);
    foreach ($diff as $id => $status) { $this->orderService->updateStatus($id, $status); }
}

결국 셋을 다 쓰게 됐다. 웹훅으로 빠르게 받고 bulk 로 빠진 것을 찾고 단건 조회로 필요할 때 개별 확인을 한다. 빠른 것과 확실한 것을 함께 두면 한쪽이 놓친 것을 다른 쪽이 잡는다.

목록을 훑는 습관과 규격 변경 추적

이 일 뒤로 무언가를 찾을 때 주변도 함께 보게 됐다. OpenAPI 명세의 Paths Object 가 개별 엔드포인트의 상대 경로를 전부 담는 자리라, jq 로 .paths 의 키를 통째로 뽑아 훑는 것이 검색보다 나았다. 검색은 검색어에 맞는 것만 주고 목록은 이름이 달라도 눈에 띈다.

규격이 언제 바뀌었는지도 함께 봤다. 옛 openapi.json 을 저장해 두고 지금 것과 경로 목록을 diff 하면 그 사이에 새로 생긴 것이 나온다.

$ diff <(cat cached/openapi-2026-01.json | jq -r '.paths|keys[]') \
       <(curl -s .../openapi.json | jq -r '.paths|keys[]')

월 1회 돌리니 새 기능을 놓치지 않았다. 검토한 것 중 안 쓰기로 한 것과 그 이유도 함께 적었다. /orders/{id}/history 는 우리 쪽에 이력이 있어서 안 썼는데 그 이유를 적어 두니 나중에 왜 안 쓰느냐는 물음에 답이 됐다.

받는 쪽의 준비

웹훅을 쓰기로 하고 나니 그것을 받는 쪽을 만들어야 했다. 그 전에는 우리가 부르기만 했으므로 밖에서 우리로 들어오는 경로가 처음 생긴 셈이었다. 방화벽과 인증과 부하를 다시 봐야 했다.

방화벽은 상대가 주는 IP 목록을 받아 그 대역만 열었고 인증은 요청에 실려 오는 X-Signature 를 HMAC 으로 검증했다. 누구나 보낼 수 있는 주소가 되면 상태를 임의로 바꿀 수 있게 된다. 부하는 재시도를 감안했다. 우리가 실패로 답하면 상대가 다시 보내므로 그것이 몰릴 수 있다.

$this->queue->push(new ProcessWebhook($payload));
return response('OK');

받는 쪽은 두 가지 방법이 있었는데 요청 안에서 상태까지 반영하고 응답하는 것과 받자마자 ProcessWebhook 을 큐에 넣고 OK 를 돌려주는 것이다. 뒤쪽을 골랐다. 이유는 처리가 오래 걸려 상대가 시간 초과로 판단하면 같은 것을 또 보내서다. 대신 큐가 밀리면 상태 반영이 몇 분 늦어지는 것을 감수했다. 근거는 상대의 재전송이 우리 응답 시간만 보고 결정된다는 점이다.

정리


Share this post on:

Previous Post
스스로를 봉인하는 되먹임 없는 경로
Next Post
다른 종류를 같게 다룬 처리