메뉴

API 경계 검증: 클라이언트와 서버의 역할

번호 검증을 클라이언트와 서버 중 어디에 두어야 하는지, 외부 조회를 섞을 때 생기는 문제와 재시도 설계, 오류를 나누는 기준을 정리합니다.

게시일

  • API 설계
  • 오류 처리

검증기를 만들다 보면 같은 규칙을 화면과 서버 양쪽에 두게 됩니다. 두 곳의 목적이 다르기 때문입니다. API 경계 검증은 어느 검사를 어디에 두고, 실패를 어떤 신호로 돌려줄지 정하는 일입니다. 이 글에서는 층을 나누는 기준과 외부 조회가 끼어들 때의 설계를 정리합니다.

검증을 클라이언트와 서버 중 어디에 두어야 하나요?

둘 다 두되 역할을 나눕니다. 화면 쪽 검사는 입력을 빠르게 되돌려주기 위한 것이고, 서버 쪽 검사는 저장되는 값의 조건을 지키기 위한 것입니다. 화면 검사만 있으면 요청을 직접 보내는 경로로 우회할 수 있고, 서버 검사만 있으면 사용자는 저장을 누른 뒤에야 오류를 봅니다.

그래서 규칙의 원본은 서버에 두고, 화면에는 같은 규칙의 사본을 두는 구성이 일반적입니다. 사본이 원본과 어긋나면 화면에서 통과한 값이 서버에서 거부되는 일이 생깁니다. 규칙에 버전을 붙이고 화면이 어느 버전을 쓰는지 알 수 있게 하면 이런 어긋남을 추적할 수 있습니다.

로컬에서 판단할 수 있는 검사와 없는 검사는 무엇인가요?

값의 형태와 산술 규칙만 보는 검사는 로컬에서 끝납니다. 자릿수 확인과 검증값 계산이 여기 속하며, 바깥과 통신하지 않아도 같은 답이 나옵니다. 이런 검사는 어느 층에서든 같은 결과를 내야 하므로 시험도 쉽습니다.

반면 발급 여부나 등록 상태처럼 외부 자료가 필요한 확인은 로컬에서 할 수 없습니다. 이 확인은 응답 시간이 들고 실패할 수도 있으며, 조회 시점에 따라 답이 달라집니다. 성격이 다른 두 검사를 한 함수에 묶으면, 응답이 늦어질 때 산술 검사까지 함께 느려지는 구조가 됩니다.

검사 종류 판단 근거 실패 시 의미
형식 검사 자릿수와 문자 입력 오류
산술 검사 검증값 계산 값 불일치
외부 조회 발급 기관 자료 확인 불가 또는 미등록

외부 조회가 끼면 무엇이 달라지나요?

가장 큰 변화는 검증이 즉시 끝나지 않는다는 점입니다. 조회가 늦어지면 요청을 붙잡고 있을지, 먼저 답하고 나중에 알릴지 정해야 합니다. 사용자에게 빠른 피드백이 중요하면 산술 결과를 먼저 돌려주고 외부 확인은 별도 상태로 표시하는 방식이 낫습니다.

또 하나는 결과가 확정적이지 않다는 점입니다. 조회 실패는 값이 틀렸다는 뜻이 아니라 지금 확인할 수 없다는 뜻입니다. 이 구분을 응답에 담지 않으면 화면은 조회 실패를 무효 판정으로 표시하게 됩니다. 원칙은 번호 검증의 원리 편의 상태 구분과 같습니다.

재시도와 시간 초과는 어떻게 다뤄야 하나요?

산술 검사는 재시도할 이유가 없습니다. 같은 값에 같은 규칙을 적용하면 결과가 달라지지 않기 때문입니다. 반면 외부 조회는 일시적인 실패가 흔하므로 제한된 횟수의 재시도가 의미를 가집니다.

재시도에는 두 가지 장치가 필요합니다. 하나는 기다리는 시간을 점점 늘리는 방식이고, 다른 하나는 전체 시간의 상한입니다. 상한이 없으면 한 요청이 오래 붙잡혀 뒤의 요청이 밀립니다. 같은 조회를 짧은 시간에 반복하면 결과를 잠시 저장해 두는 편이 낫습니다. 다만 캐시한 값에는 유효 기간을 붙여야 하며, 기간이 지난 값을 현재 상태처럼 보여주면 안 됩니다.

검증 실패는 곧 번호가 없다는 뜻인가요?

아닙니다. 산술 검사에서 어긋났다는 사실은 그 숫자열이 규칙을 만족하지 않는다는 뜻입니다. 조회에서 찾지 못했다는 사실은 그 시점의 자료에서 확인되지 않았다는 뜻입니다. 어느 쪽도 그 번호가 세상에 존재하지 않는다는 결론으로 이어지지 않습니다.

응답을 설계할 때는 이 세 가지를 나눠 담습니다. 형식이 어긋난 경우, 산술이 어긋난 경우, 확인하지 못한 경우입니다. 사유를 하나로 뭉치면 화면에서도 구분할 수 없고, 사용자는 확인 불가를 잘못된 번호로 읽습니다. 로그에도 같은 구분을 남겨야 나중에 원인을 되짚을 수 있습니다.

규칙이 바뀌면 과거에 통과한 값이 지금의 규칙에서는 어긋날 수 있습니다. 이때 저장된 값을 다시 검사해 덮어쓰는 방식은 위험합니다. 사용자가 아무것도 하지 않았는데 어느 날 값이 무효로 표시되기 때문입니다. 저장된 판정은 그 시점의 규칙과 함께 남기고, 새 규칙은 새 검사부터 적용하는 편이 안전합니다.

화면에 보여줄 때는 지금의 규칙으로 다시 검사한 결과와 저장된 결과를 구분해 안내하는 것이 좋습니다. 두 결과가 다르면 무엇이 달라졌는지 설명할 수 있어야 합니다. 이 구분을 위해 응답과 저장 항목에 규칙 버전을 담아 두는 관행이 필요하며, 버전이 없다면 어느 규칙으로 판정했는지 사후에 알 수 없습니다.

응답 시간이 길어질 때 화면이 무엇을 보여줄지도 정해 두어야 합니다. 로컬 검사는 즉시 끝나므로 화면은 곧바로 결과를 그릴 수 있습니다. 문제는 외부 확인이 붙는 경우입니다. 이때 화면을 붙잡고 있으면 사용자는 아무 반응 없는 화면을 보게 되고, 먼저 답하고 나중에 채우면 결과가 두 번 바뀝니다.

무난한 순서는 산술 결과를 먼저 보여주고 외부 확인 자리에는 확인 중이라는 상태를 두는 것입니다. 확인이 끝나면 그 자리만 갱신합니다. 확인이 실패하면 판정이 아니라 확인 실패로 표시하고 다시 시도할 수 있는 경로를 남깁니다. 이렇게 하면 사용자는 기다리는 동안에도 값의 형식이 맞는지 알 수 있습니다.

개발자를 위한 메모: 경계에서 남길 것

  • 요청과 응답에 사용한 규칙의 버전을 담습니다. 규칙이 바뀐 뒤에는 과거 요청을 재현할 수 없습니다.
  • 판정 사유를 코드값으로 돌려주고 문구는 화면에서 만듭니다. 여러 언어를 지원할 때 문구를 서버에 두면 관리가 어려워집니다.
  • 응답 시간 상한을 정하고, 상한을 넘긴 조회는 실패가 아니라 확인 불가로 처리합니다.
  • 로그에 정리된 번호 전체를 남기지 않습니다. 필요한 경우 가린 형태로 남기고 원본은 따로 보관합니다.
  • 화면 검사와 서버 검사에 같은 시험 자료를 돌려 결과가 일치하는지 주기적으로 확인합니다.

이 글의 요청과 응답 예시는 인터페이스 구조를 설명하기 위해 구성한 값이며, 실제 번호나 발급 기관의 자료가 아닙니다. 서비스 로그와 오류 보고에 실제 번호를 그대로 남기지 말고, 필요한 범위만 남기는 규칙을 먼저 정해야 합니다.

다음 단계

같은 값을 화면과 서버 양쪽에 넣어 판정이 어긋나지 않는지 번호 검증 도구에서 확인해 보고, 여러 건을 묶어 처리하는 쪽은 대량 검증 작업 흐름 편에서 이어집니다.

이어 읽기

카드번호·신분증번호 검증기 관련 글