The Interface Specification — The Document That Causes Most Incidents
Summary
An interface specification is not an explanatory document but an agreement document that two organizations sign, and if response-code actions and non-functional items are missing from it, those blanks get filled by each side blaming the other during an outage.
Why this is a problem
Most integration incidents come not from code but from what was not agreed. One side and the other knew a field's length differently; nobody decided whether to resend or to query on a timeout; or response code 9500 was understood as a retry case by one side and as a stop by the other.
These things do not show up during development, because only the normal flow is tested. Then, when the first outage happens after launch, every item not written in the specification becomes "I thought you were going to handle that." So the specification must be a document from which you can retrace later who agreed to do what, and for that you need signatures.
How fast connections grow
If you connect five systems directly to each other (P2P), how many connections is that?
N(N-1)/2
5개 → 10
10개 → 45
20개 → 190
50개 → 1,225
This is why the concept of EAI (Enterprise Application Integration) arose.
If you put a hub in the middle, the number of connections becomes N. Each system only needs to know its integration with the hub.
The hub does four things.
- Routing — who should this message be sent to
- Transformation — sender format → receiver format (mapping)
- Guarantee — retry on failure, ordering, duplicate handling
- Monitoring — what went back and forth, when, and how many
Korean financial institutions have more layers on top of this.
[인터넷뱅킹 · 모바일 · ATM · 텔러]
↓
MCI (Multi Channel Integration) ← 채널 통합
↓
EAI ← 내부 시스템 간
↓
[코어뱅킹 · CRM · 리스크 · 수신 · 여신]
↓
FEP (Front-End Processor) ← 대외 기관
↓
[금융결제원 · 카드사 · 보험사 · 신용정보원]
If you remember that MCI is on the channel side and FEP is on the external side, you will not get lost in meetings. And a large part of this section is still fixed-length messages + TCP sockets. It is unfamiliar to someone who has only done JSON REST, but in a section that requires 24-hour uninterrupted operation and a few ms of response per transaction, it is still a reasonable choice.
The arithmetic of the common data model (CDM)
If 5 systems use different formats, the mappings are N(N-1) = 20 (in both directions).
If you put a common model in the middle, each system only needs to make two, "mine ↔ common," so it is N×2 = 10.
The cost of adding one system also becomes 2 and not 2N.
This is the basis of the argument for creating a "standard message." In reality, though, the negotiation to create the common model itself becomes a project. So the judgment that if there are 3 or fewer integration targets, simply using P2P is better is also legitimate. Judging by knowing the numbers is different from following a fashion.
What an interface specification must contain
A field maxim. "Whatever is not in the interface specification is certainly implemented differently." Because the two companies are different, the developers are different, and the test schedules are different.
(1) Identification information
- Interface ID (systematic, like
IF-ORD-001) - Business name, sending system, receiving system, owner and contact
- Integration method: REST / SOAP / file / MQ / DB link / socket
- Frequency: real-time / near-real-time (N minutes) / daily batch (specify the time)
(2) Message layout
For each item, name / type / length / required / sample value / remarks. What must not be missing here, or an incident is certain:
| Item | If not written |
|---|---|
| Character set | One side UTF-8, the other EUC-KR → garbled Korean |
| Date format | YYYYMMDD vs YYYY-MM-DD vs ISO8601 |
| Amount decimal places | Is it in units of won or of jeon (hundredths)? What is the rounding rule? |
| Sign representation | Negative as -1000? Sign at the end? A separate sign field? |
| Null representation | Is it an empty string, space padding, or the string NULL |
| When the length is exceeded | Truncate or treat as an error |
You must be especially careful about the Korean 3-byte problem. You try to put 10 Korean characters in a column of length 20, but in UTF-8 that is 30 bytes and it does not fit. If the specification says only "length 20," one side implements it in characters and the other in bytes. You must write the unit too, as "20 bytes (UTF-8)."
(3) The response code scheme and the receiver's action
This is the most often missing. There is a list of codes, but what to do for each code is missing.
| Code | Meaning | Receiver's action |
|---|---|---|
0000 |
Success | Process normally |
9001 |
Missing required value | Do not retry. Fix the data and resend |
9002 |
Authentication failure | Do not retry. Notify the owner |
9003 |
Duplicate request | Treat as success (idempotent) |
9500 |
Temporary error in the other system | Retry (with backoff) |
9999 |
Unknown error | Retry once, then DLQ |
The key is the distinction between "errors that may be retried" and "errors that must not be retried." If it is not in the specification, developers either retry everything or give up on everything. The former sends wrong data 100 times, and the latter stops the business on a temporary outage.
(4) Non-functional items
- Expected volume (daily/peak), maximum message size
- Timeouts (connect/response), retry count and interval
- Contact chain during an outage, recovery time objective
- Retention period (original messages, logs)
- Whether personal information is included and which items to encrypt
A specification is an agreement — get signatures
An interface specification is not a design document we write but closer to a contract that both sides sign. So always observe these three things.
- Leave the version and revision history inside the document. "That is an old version" really does come up often.
- Get confirmation from the owners on both sides. An email reply is evidence too.
- Changes must always be by agreement of both sides. If one side adds a field, the other side's parser can die. Especially with fixed-length messages, everything breaks if even one character shifts.
The standard order of integration development
A common SI risk is development stalling because the other system is not ready. So set the order like this.
1. 인터페이스정의서 확정 (양쪽 서명)
2. ★ Mock 서버 구축 — 정의서대로 응답하는 가짜 상대 시스템
3. 우리 쪽 개발 + Mock 으로 단위테스트
4. 상대 시스템 준비되면 연동 테스트 (개발계)
5. 오류 케이스 테스트 ← 여기가 진짜 테스트다
6. 운영 리허설 (방화벽·인증서·계정 포함)
If you skip step 2, our schedule gets tied to the other side's schedule. And there are really a lot of projects that skip step 5. If you confirm only the normal case and launch, you learn at the first outage that there is no reprocessing procedure.
What is inside the parentheses of step 6 matters. The reason an integration that worked in the development environment does not work in production is, in most cases, not the code but one of firewall policy, certificates, and account permissions. And these three take days from request to application. Discovering it on cutover day is too late.
What it looks like in the field
When the specification is thin, the price is always billed late, and in someone else's time.
- The two sides knew the field length differently. We cut at 16 characters and the other side accepts 20. With normal data it does not show, and then one day a long order number comes in and is loaded with its tail cut off. This is not an error but silent data corruption, so it takes weeks to discover.
- The action for a response code was not decided. We understood 9500 as retry, and the other side as "stop and inquire." What we diligently retried during the outage is recorded on the other side as a bombardment.
- There were no non-functional items. If it is not written how many requests per second they can accept and what the maximum message size is, you find that limit out with the traffic on launch day.
So what to look at in a specification review is not the sentences but the blanks. An item not written is an item not agreed, and an item not agreed becomes a dispute during an outage.