왜 우리는 단순히 구현하는 대신 스페인 Fiscal ID 검증을 위한 API를 만들었는가
Source: Dev.to
위에 제공된 텍스트 외에 번역할 내용이 없습니다. 번역이 필요한 본문을 제공해 주시면 한국어로 번역해 드리겠습니다.
Introduction
몇 달 전, 나는 프로젝트에 재무 식별자 검증을 통합하고 있었다. 30줄짜리 JavaScript 함수를 찾아 복사하고, 네 가지 사례로 테스트했더니 작동했다. 나는 그것을 코드베이스에 넣고 잊어버렸다.
3개월 후, 사용자가 이메일을 보냈다: 그들의 CIF가 검증되지 않는다. 그것은 완전히 유효한 CIF였다. 그때 나는 검증을 구현하는 것과 이를 올바르게 유지 관리하는 것 사이에 차이가 있다는 것을 깨달았다.
스페인 세금 식별자 검증 시 흔히 발생하는 실수
NIF
기본 알고리즘(8자리 숫자 + 1자리 문자, modulo 23)은 간단해 보이지만, 특정 경우에 사용되는 K, L 및 M NIF와 같은 특수 형식이 존재하며 대부분의 구현에서는 이를 무시합니다.
NIE
NIE는 X, Y 또는 Z로 시작하고, 이후 NIF 알고리즘을 대체하여 적용합니다. 온라인에서 찾을 수 있는 많은 정규식은 7자리와 8자리를 혼용해서 허용하지만, 올바른 형식은 접두사에 따라 달라집니다.
CIF
거의 모든 것이 여기서 깨집니다:
- 제어 문자는 엔터티 유형(즉, CIF의 첫 번째 문자)에 따라 문자 또는 숫자가 될 수 있습니다.
- 대부분의 구현은 모든 유형에 대해 둘 다 허용하는데, 이는 잘못된 동작입니다.
(10 - sum % 10) % 10 === 0인 경우, 특정 상황에서는 제어 문자가 J가 되어야 합니다—이러한 엣지 케이스는 추적하기 매우 어려운 무음 버그를 발생시킵니다.
IBAN
MOD‑97 알고리즘은 매우 큰 숫자를 사용한 연산이 필요합니다. JavaScript에서는 BigInt가 필요하며, 이를 사용할 수 없거나 구현이 부실한 환경에서는 검증이 눈에 보이는 오류 없이 실패합니다.
The Maintenance Problem
이러한 버그는 개발 단계에서는 나타나지 않으며, 실제 사용자들의 실제 식별자를 사용한 프로덕션 환경에서 나타납니다.
검증이 눈에 보이게 실패할 때—예외를 발생시키거나 오류를 반환할 때—당신은 이를 잡아내고 수정합니다. 재무 검증 버그의 진짜 문제는 경고 없이 잘못된 식별자를 허용한다는 점입니다. 사용자가 잘못된 제어 숫자를 가진 CIF를 입력했지만, 코드가 “유효함”이라고 판단하고 데이터를 저장합니다. 그리고 몇 달 후 재무 작업 중에 문제가 드러나게 되면, 그때는 잘못된 데이터가 어디서 왔는지 전혀 알 수 없습니다.
오늘 모든 것을 올바르게 구현하더라도 규칙은 변할 수 있습니다. 스페인은 과거에 재무 식별자 형식을 업데이트했으며, NIE 형식도 진화해 왔습니다. 이런 변화가 발생하면 누군가 코드를 업데이트해야 하는데, 그 사람은 원 작성자가 아니거나 다른 팀에 있거나, 단순히 각 결정이 왜 내려졌는지 기억하지 못할 수도 있습니다.
API가 도움이 되는 이유
API를 사용하면 유지보수 부담이 API 유지관리자에게 전가됩니다. 안정적인 엔드포인트를 사용하고, 그들은 알고리즘을 최신 상태로 유지합니다.
우리는 Valix—공식 스페인 알고리즘을 사용하여 NIF, NIE, CIF 및 IBAN을 검증하고, 자동 유형 감지와 구조화된 JSON 응답을 제공하는 REST API를 만들었습니다.
Valix API Example (Python)
import requests
response = requests.post(
"https://api.getvalix.io/v1/validate/trial",
json={
"items": [
{"value": "12345678Z", "type": "AUTO"},
{"value": "X1234567L", "type": "AUTO"},
{"value": "A12345674", "type": "AUTO"},
{"value": "ES9121000418450200051332", "type": "AUTO"}
]
}
)
result = response.json()
for item in result["results"]:
status = "valid" if item["valid"] else f"invalid: {', '.join(item['errors'])}"
print(f"{item['value']} → {item['detected_type']} — {status}")
Output
12345678Z → NIF — valid
X1234567L → NIE — valid
A12345674 → CIF — valid
ES9121000418450200051332 → IBAN — valid
시험 엔드포인트는 등록이나 API 키가 필요하지 않으며, IP당 하루에 50회 검증할 수 있으므로, 어떤 작업을 진행하기 전에 테스트해볼 수 있습니다.
내부 구현을 사용할 때
검증량이 매우 적고, 항상 동일한 식별자 유형만 검증하며, 실제 사례를 포함한 포괄적인 테스트가 있다면 내부 구현이 의미가 있을 수 있습니다.
하지만 실제 사용자로부터 식별자를 검증하고, 유형을 혼합(NIF + NIE + CIF + IBAN)하거나, 이 로직을 유지 관리하는 데 시간을 들이고 싶지 않다면 API를 사용하는 것이 더 합리적입니다.
리소스
- API 및 문서:
- 코드 예제 (Python, JavaScript, PHP, cURL):
- JavaScript/TypeScript SDK:
npm i @valix/sdk
Disclaimer
나는 Valix의 저자입니다.