YAML vs JSON vs TOML: 강점, 사용 사례, YAML의 암시적 타입 함정
각 형식이 강세를 보이는 영역
각 데이터 직렬화 형식은 자신의 영역에서 두각을 나타냅니다. JSON(JavaScript Object Notation, ECMA-404 및 RFC 8259로 표준화)은 HTTP API의 공통 언어입니다. 사실상 모든 REST 엔드포인트가 사용하고, 모든 언어에 의존성 없는 JSON 파서가 있으며, 문법은 한 페이지에 들어갑니다. YAML(YAML Ain't Markup Language)은 DevOps 도구의 설정 파일을 지배합니다——Kubernetes 매니페스트, GitHub Actions 워크플로우, Ansible 플레이북, Docker Compose 파일 모두 YAML입니다. 여러 줄 문자열과 주석 지원 덕분에 사람이 매일 편집하는 파일에는 JSON보다 훨씬 편합니다. TOML(Tom's Obvious, Minimal Language)은 프로젝트 수준 설정에 표준 선택입니다. Rust 패키지의 Cargo.toml, Python 빌드 메타데이터의 pyproject.toml, Hugo 사이트 설정 모두 TOML을 사용합니다.
이러한 영역 차이는 우연이 아닙니다——각 형식의 설계 우선순위를 반영합니다. JSON은 상호운용성과 결정성을 우선시하고, YAML은 인간 가독성과 표현력을 우선시하며, TOML은 타입 안전성과 예측 가능한 파싱을 우선시합니다.
YAML의 암시적 타입 변환: 노르웨이 문제
YAML에서 가장 악명 높은 함정은 공격적인 암시적 타입 강제 변환입니다. YAML 1.1(PyYAML < 6.0 및 Ruby의 Psych 4.0 이전 포함, 최근까지 대부분의 파서가 사용한 버전)에서 따옴표 없는 스칼라는 타입을 결정하기 위해 일련의 정규식에 대해 테스트됩니다. 불리언 테스트는 yes, no, on, off, true, false에 대소문자 구분 없이 일치합니다. 이로 인해 ISO 3166-1 alpha-2 국가 코드를 사용하는 소프트웨어에서 실제 데이터 무결성 버그가 발생했습니다. 노르웨이 코드는 NO인데, YAML 1.1은 이를 불리언 false로 자동 변환합니다. norway: NO 같은 매핑은 런타임에 {norway: false}가 됩니다——오류도, 경고도 없이.
YAML 1.2(2009년 발행, ruamel.yaml 및 최신 파서에서 채택)는 불리언 집합을 대소문자를 구분하는 true와 false만으로 축소하고, yes/no/on/off 변형을 제거했습니다. 그러나 수백만 개의 프로덕션 파일과 도구는 여전히 YAML 1.1 파서에서 실행됩니다. 안전 규칙: 잘못 읽힐 수 있는 문자열 값은 항상 따옴표로 감싸기——국가 코드, 플래그 같은 단어, 숫자처럼 보이는 문자열.
다른 YAML 함정: 탭, 앵커, 문서 구분자
들여쓰기는 YAML의 문법이며, 탭은 YAML 들여쓰기로 절대 유효하지 않습니다. 사양은 들여쓰기 위치에서 탭 문자를 명시적으로 금지합니다. 그러나 탭은 대부분의 편집기에서 기본적으로 보이지 않으며, 실수로 입력된 탭은 일부 파서에서 잘못된 줄 번호를 가리키는 스캐너 오류를 생성합니다. 해결책은 편집기에서 '공백 표시'를 활성화하고 .yaml 파일에서 탭을 공백으로 확장하도록 설정하는 것입니다.
YAML 앵커(&)와 앨리어스(*)는 문서 전체에서 노드를 재사용할 수 있게 합니다. 반복되는 컨테이너 스펙이 있는 긴 Kubernetes 매니페스트에 유용합니다. 그러나 앨리어스 깊이를 제한하지 않는 파서에 대한 '억 웃음' 스타일 확장 공격도 가능합니다. 대부분의 프로덕션 파서(PyYAML 5.1+, SafeLoader의 snakeyaml)는 앨리어스 깊이를 제한합니다. 항상 안전한 로드 API를 사용하세요. --- 문서 구분자는 하나의 파일에 여러 YAML 문서를 허용합니다——kubectl apply -f가 이에 의존——하지만 일부 파서는 명시적으로 반복하지 않으면 첫 번째 문서만 반환하여 나머지를 자동으로 버립니다.
TOML의 명시적 타입과 날짜시간 장점
TOML은 구문 수준에서 각 값에 타입을 할당하며, 암시적 강제 변환이 없습니다. 정수는 따옴표 없이 작성(port = 8080), 부동 소수점은 소수점 필요(timeout = 1.5), 불리언은 소문자 true 또는 false, 문자열은 항상 따옴표 필요. 따옴표 없는 단어를 생성하는 오타는 파싱 오류이며, 자동 타입 변경이 아닙니다. TOML 1.0(2021년 출시)은 4개의 날짜시간 타입을 일급 리터럴로 규정합니다: offset_date_time(1979-05-27T07:32:00Z), local_date_time, local_date, local_time.
[table]과 [[array of tables]] 구문은 중첩 객체와 객체 배열에 명확하게 매핑됩니다. [[servers]] 블록 뒤에 또 다른 [[servers]] 블록이 오면 servers 배열에 두 번째 요소가 추가됩니다——명확하고 읽기 쉽고 실수 공백으로 깰 수 없습니다. 트레이드오프: TOML은 앵커나 멀티 문서 파일을 지원하지 않습니다.
JSON의 엄격함을 기능으로
JSON 문법에는 선택적 기능, 타입 강제 변환, 문서 수준 지시문이 없습니다. 어떤 플랫폼에서도 호환 파서가 {"active": true}를 읽으면 불리언을 생성합니다——문자열 "true"나 정수 1이 아닙니다. 이 결정성이 JSON을 인간 친화적이지 않음에도 API의 기본 전송 형식으로 만든 이유입니다. RFC 8259는 사양을 강화합니다: JSON 텍스트는 직렬화된 값입니다. 객체 내 중복 키는 명시적으로 '해서는 안 됨'이고, 인코딩은 BOM 없는 UTF-8이어야 합니다.
주석이 없는 것은 JSON에서 가장 많이 언급되는 불만입니다. 해결책: JSON5(주석과 후행 쉼표가 있는 슈퍼셋), JSONC(VS Code의 settings.json에서 사용), 파싱 전 // 줄 제거. 주석이 필요한 설정의 관용적 해결책은 작성에 TOML이나 YAML을 사용하고 JSON은 빌드 단계에서 생성되는 기계 교환 형식으로만 사용하는 것입니다.
올바른 형식 선택
실용적 결정 규칙은 간단합니다: JSON은 서비스 경계를 넘는 모든 데이터(HTTP API, 메시지 큐, 코드로 생성된 설정); YAML은 운영자가 직접 편집하고 주석이나 여러 줄 문자열이 필요한 설정 파일——특히 이를 강제하는 생태계(Kubernetes, GitHub Actions); TOML은 강한 타입 지정과 플랫 파일 구조가 YAML의 표현력보다 중요한 프로젝트 수준 설정. 의심스러우면 이미 생태계가 사용하는 형식을 선호하세요.
대형 YAML 설정 파일을 넘겨받아 암시적 타입 버그를 의심한다면, 빠른 감사는 YAML 1.2 린터(yamllint, spectral)로 실행하고 불리언 또는 숫자 패턴과 일치하는 따옴표 없는 값을 검색하는 것입니다. 새 프로젝트에는 스키마(JSON Schema는 도구를 통해 세 형식 모두에 작동)추가를 고려하세요. TeaFun의 YAML / JSON / TOML 변환기는 설치 없이 브라우저에서 세 형식을 전환할 수 있습니다.