클라이언트·서버·API
화면이 주문 서비스에 주문 생성을 요청할 때 양쪽은 함수 이름만 맞추는 것이 아니다. 어떤 값을 보내는지, 성공하면 무엇을 돌려주는지, 실패를 어떻게 알리는지, 같은 요청을 다시 보내도 되는지까지 맞아야 한다. 이 약속이 없으면 각 프로그램은 혼자서는 정상이어도 연결 순간에 실패한다.
호출이 된다는 말만으로는 함께 동작할 수 없다
화면이 주문 서비스에 주문 생성을 요청할 때 양쪽은 함수 이름만 맞추는 것이 아니다. 어떤 값을 보내는지, 성공하면 무엇을 돌려주는지, 실패를 어떻게 알리는지, 같은 요청을 다시 보내도 되는지까지 맞아야 한다. 이 약속이 없으면 각 프로그램은 혼자서는 정상이어도 연결 순간에 실패한다.
먼저 되짚기: 시스템 경계와 인터페이스
시스템 경계는 책임질 내부와 외부 환경을 가르고, 인터페이스는 두 요소가 교환할 입력·출력·규칙·오류의 약속이다. 클라이언트·서버 역할과 API 계약은 이 두 개념을 원격 상호작용의 책임과 접점에 적용한다.
클라이언트·서버와 API 계약의 정확한 뜻
클라이언트는 서비스를 요청하는 역할이고 서버는 요청을 받아 기능이나 데이터를 제공하는 역할이다. 이 말은 고정된 장비 이름이 아니라 한 상호작용 안의 책임이므로 같은 프로그램이 다른 관계에서는 두 역할을 모두 할 수 있다. 응용 프로그램 인터페이스(Application Programming Interface, API)는 한 소프트웨어가 다른 소프트웨어의 기능이나 데이터에 접근하도록 공개한 접점이다. API 계약은 그 접점의 입력, 출력, 상태 변화, 오류, 권한, 시간 조건과 버전을 함께 정한 약속이다. 요청 주소와 데이터 형식만 적은 문서는 계약의 일부일 뿐이며, 호출 결과의 의미와 실패 처리까지 있어야 서로 독립적으로 변경할 수 있다.
요청에서 결과까지
주문 생성 API를 예로 들면 클라이언트는 상품, 수량, 요청 식별자를 보낸다. 서버는 입력 형식과 권한을 확인하고 업무규칙을 실행한 뒤 주문 식별자와 처리상태를 돌려준다. 입력 오류, 권한 거부, 서버 장애는 서로 다른 오류로 표현하고, 응답이 늦을 때 클라이언트가 재시도할 수 있는지도 계약에 적는다. 버전을 바꿀 때는 기존 호출자가 해석하던 의미를 깨는지 먼저 판단한다.
계약을 판단하는 네 질문
무엇을 보냈는가, 무엇이 바뀌는가, 실패를 어떻게 구분하는가, 변경을 어떻게 견디는가를 확인한다. 성공 응답만 정의하면 시간초과 뒤 중복 실행이 생기고, 오류를 한 값으로 뭉치면 재시도와 사용자 수정을 구분할 수 없다. 필드 이름은 그대로인데 단위나 의미만 바꾸는 변경도 계약 파괴이므로 형식과 의미를 함께 관리해야 한다.
요청·상태변경·응답을 한 경계로 본다
상자 안의 대상과 화살표의 조건을 함께 읽으세요. 좁은 화면에서는 같은 관계를 세로로 재배치한 도식을 보여 줍니다.
클라이언트는 상품·수량·요청 식별값·인증정보를 보내고 제한시간·취소·재시도 정책을 지킨다. API 공개 계약을 거쳐 서버가 검증·업무규칙·상태변경을 수행하고 의존 서비스를 호출한다. 주문 식별값·처리상태·오류종류·재시도 가능성으로 결과를 돌려준다. 외부 의존 효과가 서버 저장과 자동으로 같은 확정 경계에 포함되지는 않는다.
계약은 전송되는 필드만이 아니라 호출 전후에 어떤 상태가 바뀌는지까지 포함한다. 클라이언트는 서버 내부 테이블을 알 필요가 없지만, 요청이 접수만 된 것인지 최종 완료된 것인지, 시간초과 뒤 결과를 어떻게 조회할지는 알아야 한다. 서버 역시 호출자가 지킬 입력·권한·중복 방지 조건을 명시해야 한다.
역할·접점·계약을 구분한다
| 구분 | 답하는 질문 | 주문 예 | 빠지면 생기는 문제 |
|---|---|---|---|
| 클라이언트 | 누가 기능을 요청하는가 | 주문 화면 | 재시도·취소 책임이 모호함 |
| 서버 | 누가 요청을 처리하고 상태를 소유하는가 | 주문 서비스 | 권한·업무규칙 책임이 모호함 |
| API | 어떤 접점으로 기능을 사용할 수 있는가 | 주문 생성 연산 | 내부 구현에 직접 의존함 |
| API 계약 | 어떤 입력·결과·효과·실패·시간·버전을 약속하는가 | 수량 규칙, 접수상태, 오류코드 | 형식은 맞아도 의미가 어긋남 |
클라이언트와 서버는 장비의 영구 정체성이 아니라 한 상호작용의 역할이다. API는 공개 접점이고 계약은 그 접점을 안전하게 사용하는 전체 의미다.
계약 변경은 소비자의 기존 해석으로 판정한다
새 필드를 선택사항으로 추가하고 옛 기본 의미를 유지하면 기존 소비자가 계속 읽을 가능성이 크다. 필수 입력을 추가하거나 같은 필드의 단위·상태 의미·오류 의미를 바꾸면 이름이 같아도 파괴적 변경이다. 먼저 소비자가 새 응답을 무시하거나 처리할 수 있게 확장하고, 생산자를 바꾼 뒤 구버전 사용량을 관측해 종료한다. 즉시 결과가 꼭 필요하면 동기 응답을, 처리가 길고 완료를 나중에 확인할 수 있으면 접수 식별값과 상태조회가 있는 비동기 계약을 검토한다.
사례: 2초 시간초과와 2.4초 주문 처리
클라이언트의 제한시간은 2초인데 서버가 2.4초에 주문을 저장했다고 하자. 클라이언트에는 시간초과가 보이지만 서버에서는 주문이 성공했다. 같은 본문을 그대로 재전송하면 주문이 두 개 생길 수 있다. 계약에 요청 식별값 R-731, 중복 요청 시 같은 주문 결과 반환, 접수·완료·거절 상태, 결과조회 연산을 둔다. 입력 오류는 사용자가 고쳐야 하므로 재시도하지 않고, 일시적 서버 오류만 전체 기한 안에서 간격을 늘려 정한 횟수만큼 재시도한다. 구체 간격과 전체 예산은 뒤의 시간초과·재시도 절에서 계산한다. 이 사례는 오류코드뿐 아니라 상태효과와 시간 규칙이 계약임을 보여 준다.
이 예는 호출자와 요청 ID의 쌍을 식별키로 하고 같은 키의 입력도 같아야 한다. 수량 1로 시작한 R-731을 수량 2로 다시 보내면 이전 결과를 무조건 반환하지 않고 입력 불일치로 거절한다.
| 시각 | 요청·보존 상태 | 허용 결과 |
|---|---|---|
| 0.0초 | R-731·수량 1을 처음 수신, 처리 담당을 하나만 확보 | 접수/처리 중 |
| 0.1초 | 같은 ID·같은 입력이 동시 도착 | 두 번째 업무실행 없이 처리 중 또는 계약된 대기 응답 |
| 2.0초 | 호출자 시간초과, 서버는 아직 처리 중 | 실패 확정 금지, 같은 ID로 조회 |
| 2.4초 | 주문 생성 효과와 ID·완료 결과를 함께 확정 | 주문 O-91 하나, 완료 |
| 2.5초 | 같은 ID 조회/재요청 | O-91의 기존 결과 |
여기서 “함께 확정”은 둘 다 남거나 둘 다 남지 않게 저장하는 경계다. 효과를 먼저 만들고 결과 기록 전에 장애가 나면 단순한 ID 조회로 재실행 여부를 판단할 수 없다. 같은 저장소 안에서는 이 경계를 하나의 트랜잭션으로 구성할 수 있지만 외부 결제까지 자동으로 포함되지는 않는다. 외부 효과는 상대의 동일 ID 계약·결과조회·대사로 확인하고 미확정 상태의 무조건 재실행을 막는다. 처리 중 기록의 복구, 결과 보존기간과 만료 뒤 요청 처리도 계약에 둔다.
자체 10점 문제
클라이언트–서버 구조와 API 계약의 구성요소를 설명하고 안전한 변경방안을 제시하시오.
요구어는 설명, 제시다. 역할과 장비를 구분해 정의하고 입력·출력뿐 아니라 상태효과, 오류, 권한, 시간, 중복과 버전을 계약요소로 제시한다. 마지막에는 시간초과에 따른 중복 실행과 의미 변경의 위험을 소비자 선확장·계약시험·사용량 관측으로 통제한다.
10점 풀이 방향과 모범답안 보기
답안 목차: 역할–계약–흐름–진화
- 클라이언트·서버와 API 계약의 정의
- 계약 구성: 입력·출력·상태효과·오류·권한·시간·중복·버전
- 요청–검증–처리–응답 및 시간초과 후 결과확인 흐름
- 호환/비호환 변경 판단과 소비자 선확장 절차
- 계약시험·관측·구버전 종료와 중복 실행 통제
답안 도식: API 계약의 여덟 칸
| API 계약 요소 | 확인할 약속 |
|---|---|
| 입력 | 상품·수량·요청 식별값의 형식·단위 |
| 결과 | 주문 식별값·처리상태의 의미 |
| 상태효과 | 접수·최종완료와 실제 변경 경계 |
| 오류 | 입력 오류·권한 거부·일시 장애의 구분 |
| 권한 | 호출자가 허용받은 요청 |
| 시간 | 제한시간·취소·조회·전체 기한 |
| 중복규칙 | 같은 ID·같은 입력의 기존 결과, 입력 불일치 거절 |
| 버전 | 소비자의 기존 해석을 유지하는 변경 |
요청·상태효과·응답 그림에 적용하고 계약시험·사용량 관측으로 확인한다.
모범답안 축약본
클라이언트는 서비스를 요청하고 서버는 기능이나 데이터를 제공하는 상호작용 역할이다. API는 소프트웨어 기능을 사용하는 공개 접점이며, API 계약은 입력·출력·상태변화·오류·권한·시간·중복 처리와 버전을 정한 약속이다. 주문 생성은 상품·수량과 요청 식별값을 받고 주문 식별값과 처리상태를 반환하며, 입력 오류·권한 거부·일시 장애를 구분해야 한다. 응답 유실 뒤 재호출에도 중복 주문이 생기지 않도록 요청 식별값과 결과조회 규칙을 둔다. 변경은 기존 소비자가 같은 의미로 해석할 수 있는지로 판단한다. 소비자를 먼저 새 형식에 대응시키고 생산자를 변경한 뒤 계약시험과 구버전 호출 관측을 거쳐 종료한다. 성공 응답만 정의하거나 필드 이름을 유지한 채 단위·의미를 바꾸는 것이 대표 실패다.
자체 25점 문제
주문 생성 API의 2초 시간초과·중복 실행·호환성 변경을 함께 통제하는 계약과 배포 절차를 설계하시오.
요구어는 설계다. 요청 결과가 불확실한 시간축과 계약 변경의 배포 순서를 한 흐름에서 다루고, 중복 효과와 구버전 소비자의 의미 파괴를 각각 막아야 한다.
25점 풀이 방향과 모범답안 보기
25점 답안 목차
- 실패 시나리오와 업무 불변조건
- 요청 식별값과 결과 상태
- 시간초과·결과조회·제한 재시도
- 입력·출력·오류·권한·시간 계약
- 호환/비호환 변경 판정
- 소비자 선확장과 생산자 전환
- 계약시험·관측·구버전 종료
- 중복·의미 변경 실패의 보정
25점 답안 도식
R-731의 시간축과 저장 경계를 사용한다. 2초 시간초과 뒤에는 같은 ID로 결과를 조회하고 제한 재시도를 판정한다. 입력·효과·오류 계약은 최초 요청과 재요청에 함께 적용한다.
계약 변경은 소비자 선확장→계약시험→생산자 전환→호출 관측→잔존 구버전 종료 순서이며, 버전 공존과 네 조합 검증을 재사용한다.
25점 모범답안
클라이언트의 2초 시간초과는 서버 실패의 증명이 아니라 관찰 한계다. 요청 식별값 R-731을 계약에 포함하고 서버는 최초 처리결과를 보존해 같은 식별값의 재요청에는 새 주문을 만들지 않고 기존 결과를 반환한다. 응답이 없으면 결과조회로 접수·완료·거절·확인 필요를 구분하고, 입력 오류는 재시도하지 않으며 일시 장애만 전체 업무기한 안에서 정한 횟수만큼 재시도한다.
계약에는 입력·출력·상태효과·오류·권한·시간·중복규칙·버전을 적는다. 새 선택 필드처럼 기존 소비자가 같은 의미로 처리할 수 있는 변경과 필수 입력 추가·단위 변경처럼 기존 해석을 깨는 변경을 구분한다. 변경이 필요하면 소비자가 먼저 새 응답을 허용하도록 배포하고 계약시험을 통과시킨 뒤 생산자를 바꾼다. 구버전 호출량을 관측해 잔존 사용자가 없음을 확인한 뒤 옛 계약을 종료하며, 의미 변경을 필드 이름 유지로 숨기지 않는다.
구체적으로 R-731·수량 1의 동시 중복은 한 처리 담당만 실행하고 나머지에는 처리 중을 반환한다. 2.4초의 주문 O-91과 ID·완료 결과는 같은 저장 경계에서 확정한다. ID는 같아도 수량이 달라지면 거절하며, 외부 결제 효과가 확정되지 않은 장애는 확인 필요로 남긴다. 시험은 동시 두 요청, 입력 불일치, 효과/기록 사이 장애를 각각 주입해 주문 하나·중복 거절·미확정 상태가 유지되는지 확인한다.
출처와 적용 경계
클라이언트·서버 역할과 API 계약은 안정된 소프트웨어 인터페이스 기초개념이다. 2초·2.4초와 R-731은 실패경계를 학습하기 위한 자체 사례이며 특정 서비스의 실제 SLA·API 규격을 뜻하지 않는다.
자기교정과 조건 변경
| 잘못 쓴 답 | 수정 | 복습 |
|---|---|---|
| 클라이언트와 서버는 고정된 장비 종류다 | 한 상호작용에서 요청·제공 책임을 맡는 역할이다 | 정의 |
| 응답의 상태코드만 정하면 API 계약이 완성된다 | 입력·출력·상태효과·오류·권한·시간·중복·버전을 함께 본다 | 여덟 칸 |
| 시간초과면 서버 작업은 실패했다 | 응답을 못 본 것이며 처리 여부는 별도로 확인해야 한다 | 2초 사례 |
| 필드 이름이 같으면 호환 변경이다 | 단위·상태·오류 의미가 바뀌어도 계약이 깨질 수 있다 | 변경 판단 |
| 생산자를 먼저 바꾸고 소비자를 맞춘다 | 소비자를 선확장하고 생산자 전환 뒤 구버전 사용량을 관측한다 | 변경 판단 |
주문 처리가 즉시 완료되지 않고 비동기 접수로 바뀌면? 완료값 대신 접수 식별값과 상태조회·취소·완료 통지를 계약에 포함한다.
요청 식별값을 보낼 수 없는 구형 소비자가 남아 있다면? 중복 효과가 큰 쓰기에는 무조건 재시도하지 말고 구형 경로 격리·결과조회·보정 절차를 둔다.
금액 필드의 단위가 원에서 전으로 바뀐다면? 같은 필드명을 유지하지 말고 명시적 버전·새 필드로 의미를 분리해 소비자 선확장 뒤 전환한다.
한 번에 되찾기
클라이언트는 요청 역할, 서버는 제공 역할이며 API는 둘 사이의 접점이다. API 계약은 입력·출력·상태·오류·권한·시간·버전을 정해 실패와 변경 뒤에도 양쪽이 같은 의미를 해석하게 한다.