본문 바로가기

코딩·의존성·빌드·패키징·API 구현

코드 자체가 같아도 컴파일러 판본, 의존성 그래프, 환경변수, 운영체제, 네트워크 서비스, 데이터 스키마가 달라지면 실행 결과가 달라질 수 있다. 구현은 소스코드 작성만이 아니라 소스→의존성→빌드→테스트→패키지→API 계약→배포 가능한 산출물의 경계를 함께 고정하는 일이다.

1. 내 컴퓨터에서는 되는데 왜 배포하면 깨질까

코드 자체가 같아도 컴파일러 판본, 의존성 그래프, 환경변수, 운영체제, 네트워크 서비스, 데이터 스키마가 달라지면 실행 결과가 달라질 수 있다. 구현은 소스코드 작성만이 아니라 소스→의존성→빌드→테스트→패키지→API 계약→배포 가능한 산출물의 경계를 함께 고정하는 일이다.

모듈 경계 위에 언어 선택을 올린다

모듈·캡슐화·객체·인터페이스에서는 모듈을 함께 변하는 기능과 데이터를 경계로 묶은 배포·재사용 단위로 정의했다. 언어 패러다임·타입·메모리 모델의 선택에서는 패러다임·타입·메모리·동시성·실행환경·도구체인을 요구에 따라 선택하는 법을 배웠다. 이번 절은 이 모듈 경계와 언어 선택을 실제 코드와 반복 가능한 산출물로 옮긴다.

인터페이스는 입력·출력·오류까지 계약이었다

시스템SW 기술문서와 인터페이스 계약은 인터페이스의 입력·출력·상태·오류·실행문맥과 판본을 한 계약으로 보았다. API 구현에서도 이름만 맞는 것이 아니라 의미·오류·시간·재시도 규칙을 유지한다.

응용SW 구현의 담당 경계

응용SW 구현은 설계된 기능과 품질 요구를 코드·의존성·빌드 규칙·패키지·API 계약으로 구체화하고, 동일한 입력과 환경에서 재현 가능한 산출물과 검증증거를 만들도록 구성하는 활동이다.

언어 기능의 선택은 앞 절이 담당한다. 이번 절은 실제 구현 경계와 산출물 재현성, 의존성·API 실패처리를 담당한다.

소스에서 배포물까지의 체인

소스에서 배포물로 잇는 단계함께 보존할 근거
요구·설계 → 소스코드정적검사·테스트
소스코드 → 빌드의존성 그래프·도구체인
빌드 → 패키지·이미지해시·메타데이터
패키지 → 배포API 계약·설정

중간 단계가 숨겨지면 동일 소스에서 다른 결과가 나와도 원인을 찾기 어렵다.

2. 코드는 기능 경계와 오류 경계를 함께 표현한다

함수·모듈·패키지는 한 책임을 갖도록 나누고 입력검증·권한검사·오류반환·자원정리를 정상경로와 같이 설계한다. 예외를 잡아 무시하거나 실패를 정상값으로 바꾸면 호출자는 오류를 구분할 수 없다.

구현 경계에서 묻는 네 질문

질문나쁜 예확인할 것
입력문자열이면 모두 허용형식·범위·단위
상태전역변수에서 암묵 공유소유권·수명
오류로그만 남기고 성공 반환오류코드·재시도 가능성
자원성공경로에서만 close모든 종료경로 정리

문자열 결합으로 SQL·명령을 만들지 않는다

외부 입력을 명령문에 그대로 결합하면 데이터와 코드의 경계가 무너질 수 있다. 해당 플랫폼의 매개변수 바인딩·안전한 API를 사용하고 입력검증을 방어선으로 추가한다. “특수문자 제거”만으로 모든 문맥의 안전성을 보장하지 않는다.

3. 의존성은 직접 사용하는 패키지보다 넓은 그래프다

프로젝트가 직접 선언한 라이브러리 A가 내부적으로 B와 C를 사용하면 B·C도 실행 산출물에 영향을 줄 수 있다. 직접·전이 의존성을 구분하고 이름·판본·출처·무결성·라이선스·업데이트 책임을 추적한다.

IM-1: 직접 의존성 2개가 실제로는 7개가 될 수 있다

앱이 A와 D만 직접 사용하지만 A→B,C, D→E,F, F→G라면 실행 그래프에는 A,B,C,D,E,F,G의 7개 노드가 존재한다. 직접 선언 2개만 점검하면 B·C·E·F·G의 판본과 취약점·라이선스 변화를 놓칠 수 있다.

범위 표현과 잠금파일의 역할을 구분한다

매니페스트의 판본 범위는 어떤 버전을 허용하는지 나타내고 잠금파일은 한 해석 결과를 고정하는 데 사용될 수 있다. 잠금파일이 있어도 레지스트리·컴파일러·플랫폼·빌드스크립트가 달라지면 바이트가 달라질 수 있다.

최신 버전 자동 선택을 재현 가능한 빌드로 부르지 않는다

어제는 의존성 X 1.4가 선택되고 오늘은 같은 명령이 1.5를 선택했다면 소스가 같아도 결과가 달라질 수 있다. 개발 중 업데이트 정책과 릴리스 빌드의 고정 정책을 구분한다.

4. 빌드는 입력과 도구체인을 명시한다

빌드 입력에는 소스뿐 아니라 컴파일러·런타임·빌드도구·의존성·환경변수·생성코드·시간·지역설정이 포함될 수 있다. 가능한 비결정 요소를 제거하고 필요한 값은 명시적으로 주입한다.

빌드 입력을 해시 가능한 단위로 본다

네 고정 입력과 레시피를 산출물 해시에 연결한다

화살표의 방향과 조건을 따라 연결을 읽습니다.

네 고정 입력과 레시피를 산출물 해시에 연결한다소스 S, 컴파일러 C, 잠금파일 L, 설정 K의 네 입력이 빌드 레시피 R에 각각 들어가며 산출물 A와 digest가 나온다. 입력 하나가 바뀌어도 산출물 바이트가 달라질 수 있다.산출물·해시source@Scompiler@Clockfile@Lconfig@Kbuild recipe@R입력·규칙 식별artifact@A + digest산출물 바이트 비교
독립 입력 네 개의 빌드 출처소스 S·컴파일러 C·잠금파일 L·설정 K의 독립 입력은 각각 레시피 R에 들어가 산출물 A와 digest로 연결된다. 입력 간 처리 순서가 없으며 소스/잠금 동일만으로 바이트 재현성을 보증하지 않는다.산출물·해시소스source@S컴파일러판본 C잠금파일판본 L설정config@K빌드 레시피 R입력·규칙 식별직접 입력 4개산출물 Aartifact + digest산출물 바이트 비교S·C·L·K·R 고정 식별자@는 식별 표기 · 연산 아님소스·잠금만 같아도 부족

S·C·L·K·R은 고정 식별자이며 @는 식별자를 붙인 자체 표기다. A나 digest가 달라지면 각 입력을 대조한다. 잠금파일이나 소스의 동일성만으로 바이트 재현성을 단정하지 않는다.

A가 달라졌다면 S,C,L,K,R 중 무엇이 달라졌는지 추적할 수 있어야 한다.

도식의 source@S는 소스의 식별자 S, compiler@C는 컴파일러 판본 C라는 뜻이다. @는 이 도식에서 대상과 고정한 식별자를 붙이는 표기이며 연산 기호가 아니다. artifact는 빌드 산출물, digest는 그 바이트를 비교할 해시값이다. 예를 들어 S·C·L은 같은데 K의 설정에서 포함 언어가 바뀌면 패키지에 들어가는 파일과 A의 해시가 달라질 수 있다. 그래서 소스 S가 같다는 사실만으로 산출물 바이트도 같다고 답하면 안 된다. 원인을 대조할 때는 먼저 이 입력 목록을 확인하고, 시각이 숨어 들어가는 경우는 IM-2: 시간이 산출물에 들어가면 바이트가 달라진다에서 설명한 예로 이어 간다.

IM-2: 시간이 산출물에 들어가면 바이트가 달라진다

빌드 시각을 바이너리 메타데이터에 현재시간으로 넣는다고 하자. 소스와 컴파일러가 같아도 09:00 빌드와 10:00 빌드의 바이트는 달라질 수 있다. 재현성을 요구한다면 시간정보를 분리하거나 결정적으로 주입하는 방법을 검토한다.

재현 가능한 빌드와 동일 동작을 구분한다

재현 가능한 빌드(reproducible build)는 정한 소스·빌드 환경·절차로 다른 사람이 지정된 산출물의 바이트까지 동일하게 다시 만들 수 있는 빌드다. 어떤 산출물과 환경 속성을 비교 대상으로 삼는지도 먼저 정한다. 프로그램이 같은 테스트를 통과해도 포함된 시각이나 파일 순서가 다르면 바이트 재현성은 아직 확인되지 않은 것이다.

바이트 단위 재현성은 공급망·감사의 근거가 될 수 있지만 그것만으로 기능의 정확성이나 안전성을 증명하지는 않는다. 아직 바이트 동일성을 달성하지 못한 프로젝트도 입력·도구·환경을 기록하고 기능·테스트를 반복 확인할 수 있다. 이때에는 ‘동일 기능의 반복 확인’과 ‘산출물 바이트 재현’ 중 무엇을 확인했는지 구별해 보고한다.

5. 패키지는 실행에 필요한 내용과 메타데이터를 묶는다

패키지에는 실행파일뿐 아니라 의존성 선언, 설정 기본값, 스키마, 라이선스·SBOM 같은 메타데이터가 포함될 수 있다. 비밀키·운영 비밀번호를 패키지에 굽지 않고 배포환경의 비밀관리 경계를 사용한다.

여기서 SBOM(Software Bill of Materials)은 산출물에 포함한 소프트웨어 구성요소를 식별하는 명세를 가리킨다. IM-1의 앱에서는 직접 선언한 A·D만 적기보다 실제 포함한 A~G의 이름과 판본·관계를 추적할 자료로 연결한다. 특정 SBOM 형식의 모든 필드나 적합성은 이 예에서 정하지 않으며, 구성요소 목록이 있다는 사실만으로 취약점이 없거나 사용 권한이 모두 확인되었다고 판단하지 않는다.

개발 설정을 운영 기본값으로 복사하지 않는다

CORS(Cross-Origin Resource Sharing, 다른 출처 자원 공유)의 origin은 요청 페이지의 스킴·호스트·포트로 구별하는 출처다. 디버그 로그, 과도하게 허용한 CORS 출처 목록, 테스트 계정, 로컬 DB 주소가 운영 패키지에 들어가면 기능은 실행되더라도 보안·개인정보·운영 안정성이 달라진다. 환경별 설정과 안전한 기본값을 분리한다.

6. API는 메서드 이름보다 입력·상태·오류·재시도 계약이다

POST /orders가 주문을 만든다는 이름만으로는 중복 요청, 타임아웃, 부분실패를 처리할 수 없다. 입력 스키마, 성공·오류 상태, 재시도 시 중복 여부, 인증·인가, 버전과 호환성을 함께 정한다.

IM-3: 응답을 못 받았다고 주문이 실패한 것은 아니다

클라이언트가 주문 요청을 보냈고 서버는 저장에 성공했지만 응답 직전 네트워크가 끊겼다고 하자. 클라이언트가 같은 요청을 그대로 재시도하면 주문이 두 번 생성될 수 있다. 생성 API는 멱등키·중복검사·조회확인 같은 계약을 설계할 수 있다.

IM-3의 구체 계약은 같은 호출자 U1 안에서 키 K7과 주문내용 A를 묶는 것이다. 인증·인가를 통과한 뒤 (U1,K7)의 유일성, 요청 내용, 주문과 응답 결과를 같은 저장 확정 경계에서 관리한다. 외부 결제는 이 작은 주문 저장 예에 포함하지 않는다.

입력·현재 상태판정·동작저장 후 상태·응답
K7 없음, 내용 A로 최초 요청주문 O42와 K7→A·O42 결과를 한 트랜잭션으로 확정주문 1개·키 결과 1개, O42 반환
확정 직후 응답 유실, 같은 U1·K7·A 재요청저장된 내용과 일치하면 기존 결과 조회새 주문 0개, 같은 O42 반환
같은 U1·K7, 다른 내용 B기존 의도와 충돌하므로 거부O42·A 유지, 추가 주문 없음
두 요청이 동시에 K7 없음으로 관찰, 선행 요청이 확정유일성 제약과 트랜잭션으로 한 확정만 허용충돌한 요청은 확정된 기존 결과 조회
선행 요청이 커밋 전에 트랜잭션을 롤백하고 종료확정 결과가 없는지 다시 확인한 뒤 같은 키·내용으로 처리이후 확정한 요청만 주문·키 결과를 함께 남김
저장 확정 여부를 아직 확인 못함실패로 단정해 새 키를 만들지 않음미확인 상태와 조회·재시도 계약 반환

단순히 조회 후 삽입하는 두 동작만 두면 동시 요청 둘 다 빈 상태를 보고 중복 저장할 수 있다. 키와 주문 중 하나만 확정되는 경로도 배제해야 한다. 보관기간·만료 이후 요청·새 키 사용은 별도 계약으로 정하며 이 예가 임의 기간의 중복 방지나 외부 결제까지 증명한 것은 아니다. 직접 판단: 응답을 못 받아도 키 K7→O42가 확정돼 있다면 재시도의 기대 결과는 O43 생성이 아니라 O42 재조회다. 잘못 답했다면 이 표의 확정·미확인 분기를 다시 대조한다.

호환 변경과 파괴적 변경을 구분한다

변경기존 클라이언트 위험
선택 필드 추가보통 낮음, 파서 확인 필요
필수 필드 추가기존 요청 실패 가능
enum 값 추가폐쇄형 파서 실패 가능
필드 의미 변경이름 같아도 매우 위험
필드 삭제기존 소비자 실패

호환성은 문법만이 아니라 의미와 소비자 구현을 함께 확인한다.

200 응답만 자동화 테스트하지 않는다

인증실패, 권한부족, 잘못된 입력, 중복요청, 의존서비스 타임아웃, DB 충돌, 부분성공을 시험한다. 오류응답도 스키마와 의미가 안정돼야 호출자가 안전하게 복구할 수 있다.

7. 구현 증거를 소스와 함께 남긴다

커밋, 코드검토, 정적검사, 단위시험, 빌드로그, 의존성 해석결과, 패키지 해시, API 계약판본을 연결한다. “통과했다”는 스크린샷보다 어떤 입력과 판본에서 무엇이 통과했는지 기계적으로 추적 가능한 증거가 낫다.

실패 시 수정 범위를 최소화한다

의존성 판본 문제면 비즈니스 로직 전체를 다시 쓰지 않고 의존성 경계를 수정한다. API 의미 문제면 호환성 계약을 고친다. 빌드 재현성 문제면 입력·도구체인을 고친다. 원인을 분리해 장기적인 구조를 유지한다.

공식 범위 연결 — 응용SW 기초 기술 활용

응용SW 기초 기술 활용은 코드를 작성하는 행위에 한정되지 않는다. 의존성·빌드·패키징·API·오류처리·검증증거를 연결하여 동일한 기능을 반복적으로 만들고 배포할 수 있어야 한다.

출처와 적용 경계

프로그래밍 언어와 시스템 인터페이스의 기초는 앞의 모듈·언어 선택·인터페이스 계약과 연결한다. 의존성 7개, 빌드 시각, 주문 재시도 사례는 자체 유한 예제다. 재현성의 범위는 Reproducible Builds의 정의, 멱등키와 상태 변경을 함께 확정하는 경계는 AWS Builders’ Library의 멱등 API 설명을 2026-10-06에 확인해 독립적으로 설명했다. 두 자료의 예제 코드·그림을 가져오지는 않았다. 특정 패키지 관리자·API 표준·SBOM 형식의 세부 규칙은 실제 도구의 공식 문서와 판본을 확인해 적용한다.

8. 한 장으로 정리하기

  1. 구현은 소스코드뿐 아니라 의존성·빌드·패키지·API까지 포함한다.
  2. 직접·전이 의존성을 모두 추적한다.
  3. 잠금파일과 도구체인·환경 재현성을 구분한다.
  4. 패키지에 비밀과 개발 기본값을 섞지 않는다.
  5. API는 재시도·오류·호환성을 계약한다.
  6. 빌드·테스트·해시·판본을 추적 가능한 증거로 남긴다.

독립 연습 — 같은 키에 다른 내용이 들어오면 무엇을 보존하는가

다음은 본문 사례의 조건을 적용하거나 바꾼 자체 연습이다. 먼저 판단과 근거를 적고 풀이를 펼친다.

IM-3의 U1·K7·내용 A와 O42가 함께 저장 확정되었다. 응답을 놓친 호출자가 같은 U1·K7로 내용 B를 제출한다. 이후 U1·K7·A를 다시 보낸다. 외부 결제와 만료정책은 원래 사례처럼 범위 밖이다.

  • B 요청과 그다음 A 요청의 판정·추가 주문 수·유지할 저장내용을 차례로 쓰라.
  • 조회 후 삽입 두 줄만으로 동시 최초요청을 막을 수 없는 이유를 설명하라.
풀이와 오답 교정 보기

B는 같은 키의 기존 의도 A와 충돌하므로 거부하고 O42·A·기존 결과를 유지한다. 다음 A는 내용이 일치하므로 기존 O42를 반환하고 새 주문은 만들지 않는다. 최초요청 둘이 각각 빈 키를 읽을 수 있으므로 단순 조회 후 삽입만으로는 배타적 확정이 되지 않는다. 유일성·내용 검사·주문·키 결과를 같은 확정 경계에서 관리하고 충돌한 요청이 승자의 결과를 확인하도록 한다.

B를 새 주문으로 만들었다면 IM-3의 충돌 행, 저장된 키만 보고 외부 결제까지 안전하다고 썼다면 같은 절의 범위 제외를 함께 적는다.

9. 자체 10점 문제

응용SW 구현에서 의존성 관리와 재현 가능한 빌드, API 계약이 중요한 이유를 설명하시오.

요구어는 설명이다. 세 항목을 공급망·배포재현성·호출자 복구라는 공통 목적에 연결한다.

10점 풀이와 답안 구성 보기

10점 답안 목차

  1. 응용SW 구현의 범위
  2. 직접·전이 의존성 관리
  3. 빌드 입력·도구체인·잠금
  4. 패키지와 산출물 무결성
  5. API 입력·오류·재시도·호환성

10점 답안 도식

고정 입력과 산출물 그림에 source + deps + toolchain을 포함한다. build → package + digest를 추적하고, 배포물 체인의 API contract와 연결한다.

10점 모범답안

응용SW 구현은 소스코드 작성뿐 아니라 의존성, 빌드, 패키징, API 계약까지 동일한 실행산출물로 연결하는 활동이다. 직접 의존성뿐 아니라 전이 의존성의 판본·출처·무결성을 추적하고 매니페스트와 잠금 결과를 구분한다. 재현 가능한 빌드를 위해 소스·컴파일러·의존성·환경·설정을 명시하고 산출물 해시와 빌드증거를 남긴다. API는 입력·출력·오류·인증·재시도와 중복처리·호환성을 계약하여 네트워크 실패나 판본 변경에도 호출자가 안전하게 복구할 수 있게 한다.

10. 자체 25점 문제

주문 API를 신규 구현하여 여러 환경에 배포하려 한다. 코드 구조, 의존성, 재현 가능한 빌드, 패키징, 설정·비밀, API 중복요청·오류·호환성, 검증증거 관점의 구현 방안을 설계하시오.

요구어는 설계다. 정상경로뿐만 아니라 재시도·부분실패·판본 차이를 포함한다.

25점 풀이와 답안 구성 보기

25점 답안 목차

  1. 모듈·입력·오류·자원 경계
  2. 직접·전이 의존성·잠금·무결성
  3. 도구체인·설정·결정적 빌드
  4. 패키지·해시·메타데이터
  5. 환경설정·비밀관리
  6. 주문 API 멱등성·오류·타임아웃
  7. 스키마·판본 호환성
  8. 테스트·로그·빌드증거·추적성

25점 답안 도식

서로 다른 연결끝까지 추적할 것
commit → locked deps → deterministic build → package#hash같은 커밋과 패키지에 연결한 tests/evidence
client → idempotency key → order API → DBduplicate 처리와 error contract

빌드 입력 그림과 IM-3의 확정·미확인 표를 함께 사용한다.

25점 모범답안

먼저 주문 도메인의 입력·출력·상태·오류를 모듈 경계로 나누고 자원정리가 모든 종료경로에서 수행되도록 구현한다. 직접·전이 의존성의 판본·출처·무결성을 추적하고 릴리스 시 잠금결과와 도구체인·환경설정을 고정한다. 빌드는 소스·의존성·컴파일러·설정·생성코드를 명시하여 반복 가능하게 하고 산출물 해시·빌드로그를 남긴다. 패키지에는 실행에 필요한 메타데이터를 포함하되 비밀키와 운영 비밀번호는 넣지 않는다. 주문 생성 API는 IM-3처럼 호출자 U1·키 K7·내용 A와 주문 O42 결과를 같은 트랜잭션으로 확정한다. 응답 유실 뒤 같은 K7·A는 O42를 조회하고 내용 B 재사용은 거부한다. 동시 요청은 유일성 제약·충돌 뒤 조회로 한 확정만 허용하며, 확정 미확인은 새 주문 성공·실패로 단정하지 않는다. 인증·인가·검증실패·타임아웃·충돌의 오류계약과 키 보관·만료 범위를 명시하고 외부 결제는 별도 효과 경계로 검증한다. 필드 추가·삭제·의미변경의 호환성을 소비자와 검증하고 정상·오류·재시도·부분실패 테스트를 자동화한다. 최종적으로 커밋–테스트–빌드–패키지해시–API 판본을 연결하여 어떤 입력과 도구에서 어떤 산출물이 만들어졌는지 추적할 수 있게 한다.

이 페이지 목차

이 페이지 목차

1. 내 컴퓨터에서는 되는데 왜 배포하면 깨질까모듈 경계 위에 언어 선택을 올린다인터페이스는 입력·출력·오류까지 계약이었다응용SW 구현의 담당 경계소스에서 배포물까지의 체인2. 코드는 기능 경계와 오류 경계를 함께 표현한다구현 경계에서 묻는 네 질문문자열 결합으로 SQL·명령을 만들지 않는다3. 의존성은 직접 사용하는 패키지보다 넓은 그래프다IM-1: 직접 의존성 2개가 실제로는 7개가 될 수 있다범위 표현과 잠금파일의 역할을 구분한다최신 버전 자동 선택을 재현 가능한 빌드로 부르지 않는다4. 빌드는 입력과 도구체인을 명시한다빌드 입력을 해시 가능한 단위로 본다IM-2: 시간이 산출물에 들어가면 바이트가 달라진다재현 가능한 빌드와 동일 동작을 구분한다5. 패키지는 실행에 필요한 내용과 메타데이터를 묶는다개발 설정을 운영 기본값으로 복사하지 않는다6. API는 메서드 이름보다 입력·상태·오류·재시도 계약이다IM-3: 응답을 못 받았다고 주문이 실패한 것은 아니다호환 변경과 파괴적 변경을 구분한다200 응답만 자동화 테스트하지 않는다7. 구현 증거를 소스와 함께 남긴다실패 시 수정 범위를 최소화한다공식 범위 연결 — 응용SW 기초 기술 활용출처와 적용 경계8. 한 장으로 정리하기독립 연습 — 같은 키에 다른 내용이 들어오면 무엇을 보존하는가9. 자체 10점 문제10점 답안 목차10점 답안 도식10점 모범답안10. 자체 25점 문제25점 답안 목차25점 답안 도식25점 모범답안