회사 코드가 조금 익숙해질 무렵 Unity 화면에 서버 데이터를 연결하는 일을 맡았다. 처음에는 버튼을 누르면 요청하고 응답을 텍스트에 넣으면 끝이라고 생각했다. 막상 해보니 요청을 보내는 부분은 전체 작업의 시작에 가까웠다. 서버에서는 값이 왔는데 화면이 그대로이거나, 다른 탭으로 이동한 뒤 늦게 도착한 응답이 이전 화면을 다시 바꾸기도 했다.
문제가 API인지 Unity인지 구분하는 것부터 어려웠다. 그래서 주소, 응답 변환, 화면 갱신을 한꺼번에 보지 않고 경계를 나눠 확인하기 시작했다.
요청 성공과 화면 유효성의 차이
예를 들어 목록 API가 정상적으로 200을 반환해도 사용자가 이미 화면을 닫았을 수 있다. 요청 당시 선택한 계좌와 응답 시점의 계좌가 다를 수도 있었다. 응답 성공만 확인하고 바로 UI를 바꾸면 오래된 결과가 최신 화면을 덮었다.
int requestedAccountId = selectedAccountId;
var response = await api.GetAsync($"https://api.example.com/accounts/{requestedAccountId}/orders");
if (!isActiveAndEnabled || requestedAccountId != selectedAccountId)
return;
Render(response.items);
실제 코드의 취소 방식은 달랐지만, 응답을 적용하기 전에 지금도 같은 화면과 조건인지 확인해야 한다는 의미였다.
서버 응답과 UI 모델의 분리
응답 필드 이름과 화면에서 필요한 값은 꼭 같지 않았다. 금액은 자릿수 규칙이 필요했고 null이나 빈 배열은 별도 상태로 보여야 했다. API 모델을 곧바로 Text 컴포넌트에 흩어 넣으면 같은 가공 코드가 여러 화면에 생겼다.
OrderRow ToRow(OrderDto dto)
{
return new OrderRow(
dto.symbol ?? "-",
FormatAmount(dto.amount),
ParseServerTime(dto.createdAt));
}
화면은 표시용 모델만 받아 그리는 쪽으로 읽으니 데이터 변환과 UI 문제를 따로 볼 수 있었다.
성공·빈 결과·실패 상태의 구분
처음에는 목록이 없을 때도 실패처럼 보였고, 요청이 실패했을 때는 이전 목록이 남아 있었다. 로딩 중, 성공 목록, 정상적인 빈 결과, 재시도 가능한 오류를 각각 상태로 두니 화면 조건이 훨씬 분명해졌다.
Loading -> Success(items)
-> Empty
-> Error(message, retry)
로그도 요청 URL만 남기지 않고 요청 식별값, 선택 조건, 응답 개수, 화면 적용 여부를 함께 봤다. 실제 도메인과 계정 값은 기록에 남기지 않고 재현에 필요한 문맥만 사용했다.
API와 화면 경계의 연결
처음에는 서버 데이터가 도착하면 일이 끝난다고 생각했다. 실제로는 외부 응답을 앱이 이해하는 데이터로 바꾸고, 현재 화면에 적용해도 되는지 확인하고, 사용자에게 상태를 설명하는 과정까지 포함됐다.
이 작업 이후 API 관련 문제를 볼 때 주소부터 고치려 하지 않는다. 누가 요청했고 어떤 조건으로 기다렸는지, 응답이 어디에서 변환되고 어느 시점에 화면에 들어가는지를 순서대로 본다. 아직 기존 구조를 따라가며 배운 단계였지만 화면 밖의 데이터 흐름을 보기 시작한 중요한 경험이었다.
후속 확인 항목
나중에 같은 증상을 다시 만나지 않으려고 문서에 적힌 기준으로 구현을 한 번 더 정리했다.
RFC 9110은 HTTP 메서드의 의미와 멱등성을 구분한다. 같은 요청을 다시 보내도 의도한 서버 효과가 한 번과 같아야 멱등하다고 말할 수 있다. 클라이언트에서 버튼을 잠그는 것은 중복 조작을 줄이지만, 타임아웃 뒤 재전송이나 다른 기기 요청까지 막아 주지는 않는다.
또 상태 코드만으로 화면 상태를 모두 결정하기보다 응답이 어떤 요청과 선택 조건에 대한 것인지 확인해야 한다. 네트워크 성공과 현재 화면에 적용 가능한 응답은 다른 판단이다.
다음에 Unity API 연동과 화면 데이터 같은 문제를 보면 아래 순서부터 확인하려고 한다.
- 요청 DTO와 화면 모델의 분리
- HTTP 성공과 업무 성공의 구분
- 취소·타임아웃·재시도 정책
- 예시 도메인으로 재현 가능한 로그
재시도는 횟수보다 같은 요청을 식별하는 키와 서버의 중복 처리 규칙이 먼저 정해져야 한다.
공식 참고 자료
- RFC 9110 HTTP Semantics — HTTP 메서드·상태 코드·멱등성 의미