The Interface Specification — The Document That Causes Most Incidents
한국어 원문으로 표시합니다.
한 줄 요약
인터페이스 정의서는 설명 문서가 아니라 두 조직이 서명하는 합의 문서이고, 여기에 응답 코드별 조치와 비기능 항목이 빠지면 그 빈칸은 장애 때 서로의 책임 공방으로 채워진다.
왜 이게 문제인가
연동 사고의 대부분은 코드가 아니라 합의하지 않은 것에서 난다. 필드 하나의 길이를 서로 다르게 알고 있었다거나, 타임아웃이 났을 때 재전송할지 조회할지 정해 두지 않았다거나, 응답 코드 9500 을 한쪽은 재시도 대상으로 다른 쪽은 중단으로 이해하고 있었다거나.
이런 것들은 개발 중에는 드러나지 않는다. 정상 흐름만 시험하기 때문이다. 그러다 오픈하고 첫 장애가 났을 때, 정의서에 적혀 있지 않은 항목은 전부 "그건 그쪽에서 해 주시는 걸로 알았는데요" 가 된다. 그래서 정의서는 나중에 누가 무엇을 하기로 했는지 되짚을 수 있는 문서여야 하고, 그러려면 서명이 필요하다.
연결이 늘어나는 속도
시스템 다섯 개를 서로 직접(P2P) 연결하면 연결 수는 몇 개인가?
N(N-1)/2
5개 → 10
10개 → 45
20개 → 190
50개 → 1,225
이게 EAI(Enterprise Application Integration)라는 개념이 생긴 이유다.
가운데 허브를 두면 연결 수가 N 이 된다. 각 시스템은 허브와의 연동만 알면 된다.
허브가 하는 일은 넷이다.
- 라우팅 — 이 전문을 누구에게 보낼 것인가
- 변환 — 송신 형식 → 수신 형식 (매핑)
- 보장 — 실패 시 재시도, 순서, 중복 처리
- 관제 — 무엇이 언제 몇 건 오갔는가
국내 금융권은 여기에 계층이 더 있다.
[인터넷뱅킹 · 모바일 · ATM · 텔러]
↓
MCI (Multi Channel Integration) ← 채널 통합
↓
EAI ← 내부 시스템 간
↓
[코어뱅킹 · CRM · 리스크 · 수신 · 여신]
↓
FEP (Front-End Processor) ← 대외 기관
↓
[금융결제원 · 카드사 · 보험사 · 신용정보원]
MCI 는 채널 쪽, FEP 는 대외 쪽이라고 기억하면 회의에서 헤매지 않는다. 그리고 이 구간의 상당수가 아직도 고정길이 전문 + TCP 소켓이다. JSON REST 만 해 본 사람에게는 낯설지만, 24시간 무중단과 건당 수 ms 응답이 요구되는 구간에서는 여전히 합리적인 선택이다.
공통 데이터 모델(CDM)의 산수
시스템 5개가 서로 다른 포맷을 쓰면 매핑은 N(N-1) = 20 개다(양방향).
가운데 공통 모델을 두면 각 시스템은 "내 것 ↔ 공통" 두 개만 만들면 되니 N×2 = 10 개다.
시스템 하나를 추가할 때 드는 비용도 2N 이 아니라 2 가 된다.
이것이 "표준 전문"을 만들자는 주장의 근거다. 다만 현실에서는 공통 모델을 만드는 협의 자체가 프로젝트가 된다. 그래서 연동 대상이 3개 이하면 그냥 P2P 가 낫다는 판단도 정당하다. 숫자를 알고 판단하는 것과 유행을 따르는 것은 다르다.
인터페이스 정의서에 반드시 있어야 하는 것
현장 격언 하나. "인터페이스 정의서에 없는 건 반드시 다르게 구현돼 있다." 양쪽 회사가 다르고, 개발자가 다르고, 테스트 일정이 다르기 때문이다.
(1) 식별 정보
- 인터페이스 ID (
IF-ORD-001처럼 체계 있게) - 업무명, 송신 시스템, 수신 시스템, 담당자와 연락처
- 연계 방식: REST / SOAP / 파일 / MQ / DB 링크 / 소켓
- 주기: 실시간 / 준실시간(N분) / 일배치(시각 명시)
(2) 전문 레이아웃
항목마다 이름 / 타입 / 길이 / 필수 여부 / 샘플값 / 비고. 여기서 빠지면 반드시 사고 나는 것들:
| 항목 | 안 적으면 |
|---|---|
| 문자셋 | 한쪽 UTF-8, 한쪽 EUC-KR → 한글 깨짐 |
| 날짜 포맷 | YYYYMMDD vs YYYY-MM-DD vs ISO8601 |
| 금액 소수 자릿수 | 원 단위인가 전 단위인가. 반올림 규칙은? |
| 부호 표현 | 음수를 -1000 으로? 뒤에 부호를? 별도 부호 필드? |
| 널 표현 | 빈 문자열인가, 공백 채움인가, 문자열 NULL 인가 |
| 길이 초과 시 | 자를 것인가 오류로 볼 것인가 |
한글 3바이트 문제를 특히 조심해야 한다. 컬럼 길이 20 에 한글 10자를 넣으려는데 UTF-8 이면 30바이트라 들어가지 않는다. 정의서에 "길이 20"이라고만 적혀 있으면 한쪽은 글자 수로, 한쪽은 바이트 수로 구현한다. "20 바이트(UTF-8)" 라고 단위까지 적어야 한다.
(3) 응답 코드 체계와 수신측 조치
이게 가장 자주 빠진다. 코드 목록은 있는데 각 코드에 무엇을 해야 하는지가 없다.
| 코드 | 의미 | 수신측 조치 |
|---|---|---|
0000 |
정상 | 정상 처리 |
9001 |
필수값 누락 | 재시도 금지. 데이터 수정 후 재전송 |
9002 |
인증 실패 | 재시도 금지. 담당자 통보 |
9003 |
중복 요청 | 정상으로 간주 (멱등) |
9500 |
상대 시스템 일시 오류 | 재시도 (백오프) |
9999 |
알 수 없는 오류 | 1회 재시도 후 DLQ |
"재시도해도 되는 오류"와 "재시도하면 안 되는 오류"의 구분이 핵심이다. 이게 정의서에 없으면 개발자는 전부 재시도하거나 전부 포기한다. 전자는 잘못된 데이터를 100번 보내고, 후자는 일시 장애에 업무가 멈춘다.
(4) 비기능 항목
- 예상 건수(일/피크), 최대 전문 크기
- 타임아웃(연결/응답), 재시도 횟수와 간격
- 장애 시 연락 체계, 복구 목표 시간
- 보관 기간(전문 원본, 로그)
- 개인정보 포함 여부와 암호화 대상 항목
정의서는 합의 문서다 — 서명을 받아라
인터페이스정의서는 우리가 쓰는 설계서가 아니라 양쪽이 서명하는 계약에 가깝다. 그래서 이 세 가지는 반드시 지킨다.
- 버전과 개정 이력을 문서 안에 남긴다. "그건 예전 버전인데요"가 실제로 자주 나온다.
- 양쪽 담당자의 확인을 받는다. 메일 회신도 증거다.
- 변경은 반드시 양쪽 합의로. 한쪽이 필드를 하나 추가하면 상대의 파서가 죽을 수 있다. 특히 고정길이 전문은 한 글자만 밀려도 전부 깨진다.
연동 개발의 표준 순서
상대 시스템이 준비되지 않았다는 이유로 개발이 멈추는 것이 SI 의 흔한 리스크다. 그래서 순서를 이렇게 잡는다.
1. 인터페이스정의서 확정 (양쪽 서명)
2. ★ Mock 서버 구축 — 정의서대로 응답하는 가짜 상대 시스템
3. 우리 쪽 개발 + Mock 으로 단위테스트
4. 상대 시스템 준비되면 연동 테스트 (개발계)
5. 오류 케이스 테스트 ← 여기가 진짜 테스트다
6. 운영 리허설 (방화벽·인증서·계정 포함)
2번을 건너뛰면 상대 일정에 우리 일정이 묶인다. 그리고 5번을 건너뛰는 프로젝트가 정말 많다. 정상 케이스만 확인하고 오픈하면 첫 장애 때 재처리 절차가 없다는 것을 알게 된다.
6번의 괄호 안이 중요하다. 개발계에서 되던 연동이 운영계에서 안 되는 이유는 코드가 아니라 방화벽 정책, 인증서, 계정 권한 셋 중 하나인 경우가 대부분이다. 그리고 이 셋은 신청부터 반영까지 며칠씩 걸린다. 이행 당일에 발견하면 늦는다.
현장에서 만나는 모습
정의서가 부실할 때 그 대가는 늘 늦게, 그리고 남의 시간으로 청구된다.
- 필드 길이를 서로 다르게 알고 있었다. 우리는 16 자로 자르고 상대는 20 자로 받는다. 정상 데이터에서는 안 드러나다가, 어느 날 긴 주문번호가 들어오면서 뒤가 잘린 채 적재된다. 이건 오류가 아니라 조용한 데이터 오염이라 발견까지 몇 주가 걸린다.
- 응답 코드의 조치가 안 정해져 있었다. 9500 을 우리는 재시도로, 상대는 "중단하고 문의" 로 이해하고 있었다. 장애 때 우리가 성실히 재시도한 것이 상대에게는 폭격으로 기록된다.
- 비기능 항목이 없었다. 초당 몇 건까지 받아 줄 수 있는지, 최대 전문 크기가 얼마인지 적혀 있지 않으면, 그 한계는 오픈 첫날 트래픽으로 알게 된다.
그래서 정의서 검토에서 봐야 할 것은 문장이 아니라 빈칸이다. 안 적힌 항목이 곧 합의되지 않은 항목이고, 합의되지 않은 항목은 장애 때 분쟁이 된다.