Skip to content
isdnetworks
Go back

검증과 매핑이 다른 필드를 본다

(수정됨)

새 관리자 API 로 코인을 등록해야 하는데 형식을 몰라서 GET /api/coins/{id} 로 기존 것을 조회해 템플릿으로 쓰려고 했다. 값만 바꿔 POST /api/coins 로 보냈더니 필수 필드가 없다는 400 이 돌아왔다.

Table of contents

Open Table of contents

원인 — 조회 응답과 등록 요청의 형식 차이

두 형식을 나란히 놓고 보니 같은 것을 다른 이름으로 부르고 있었다. 체인은 응답에는 chainId 로 있고 등록에서는 chain 코드 문자열을 받으며 networkFee 와 network_fee 처럼 표기도 각각 달랐다.

지갑 설정은 이름이 아니라 구조 자체가 달랐다. 조회 결과를 그대로 등록 입력으로 쓸 수 있다는 전제가 성립하지 않았다.

검증 — 검증과 처리가 다른 필드를 본다

더 이상한 것은 CoinCreateValidator 와 실제 CoinService.create() 가 서로 다른 필드를 본다는 점이었다. 검증은 network_fee 를 필수로 요구하고 처리는 networkFee 를 읽고 있었다.

그러면 양쪽 이름을 다 보내야 검증을 통과하면서 동작한다. 하나만 보내면 검증에서 막히거나 값이 빈 채로 처리되고 뒤쪽은 오류도 안 난다.

검증 재사용이 남긴 흔적

git log 를 보니 원래 옛 콘솔용 검증 클래스가 있었고 리브랜딩으로 새 API 가 생기면서 처리 코드만 새로 쓴 것으로 보였다. 두 화면이 다른 필드명을 쓰는데 검증만 공유한 셈이다.

검증 클래스 안에 옛 콘솔의 중첩 구조 wallet.config 를 참조하는 코드도 남아 있었다. 새 요청에는 그런 구조가 없으므로 그 부분은 항상 빈 값으로 검증을 통과한다.

판단 기준 — 실제 성공한 요청이라는 권위

두 가지 방법이 있었다. 각 계층이 요구하는 것을 코드에서 읽어 합집합으로 조립하는 것과, 실제로 들어온 요청을 본문까지 기록하는 request_logs 테이블에서 성공한 요청 하나를 찾는 것이다. 뒤쪽을 골랐다. 이유는 검증과 처리가 다르고 지갑 설정 구조는 문서에도 없어서 합집합은 불필요한 필드까지 보내게 되어서다. 대신 그 테이블에 개인정보가 섞여 있어 조회 권한을 따로 받아야 하는 것을 감수했다.

성공한 클라이언트의 요청 본문 하나가 여러 계층에서 추론한 것보다 확실한 답이다.

주의 — 여기 있다와 확인했다의 차이

여기까지 알아내고 정리했지만 request_logs 를 실제로 조회하지는 않았다. 권한 승인이 늦어졌고 작업 범위가 다른 곳에 있어 이 부분은 다음으로 미뤘다.

그래서 형식을 어디서 확인할 수 있는지를 적으면서 이번에 조회하지 않았으므로 미검증이라고 함께 적었다. 나중에 이 메모를 보는 사람이 확인된 것으로 오해하면 같은 자리에서 다시 막히기 때문이다.

정리


Share this post on:

Previous Post
부수효과를 원하는지로 도구를 고른다
Next Post
두 곳에 살아 있던 매핑