</>DevTools

Y/JJSON ↔ YAML 변환

JSON과 YAML 포맷 간 변환

JSON과 YAML 상호 변환: 무엇이 보존되고 무엇이 사라지는가

YAML은 JSON의 상위집합이라서 모든 JSON은 유효한 YAML입니다. 그래서 JSON에서 YAML로 가는 변환은 손실이 없습니다. 반대 방향은 사정이 다릅니다. YAML에는 JSON에 대응물이 없는 기능들이 있고, 변환 과정에서 조용히 사라지거나 형태가 바뀝니다. 어느 방향으로 변환하든 이 비대칭을 알고 있어야 합니다.

같은 데이터, 두 표기

YAML이 사람이 쓰기 편한 이유는 따옴표와 괄호, 쉼표가 대부분 필요 없고 주석을 달 수 있기 때문입니다. 그래서 사람이 손으로 편집하는 설정 파일(Kubernetes 매니페스트, GitHub Actions 워크플로, Docker Compose)은 YAML을 쓰고, 프로그램이 주고받는 데이터는 JSON을 씁니다.

JSON
{
  "name": "my-app",
  "version": "1.0.0",
  "ports": [8080, 8443],
  "env": {
    "NODE_ENV": "production",
    "DEBUG": false
  }
}
YAML
name: my-app
version: 1.0.0
ports:
  - 8080
  - 8443
env:
  NODE_ENV: production
  DEBUG: false

사용 방법

  1. 변환할 JSON 또는 YAML을 입력창에 붙여넣습니다.
  2. 변환 방향을 선택합니다.
  3. 결과를 확인합니다. 입력 문법이 잘못된 경우 오류 메시지가 표시됩니다.
  4. YAML에서 JSON으로 변환할 때는 아래의 손실 항목을 먼저 확인하세요.

YAML에서 JSON으로 갈 때 사라지는 것

실무에서 가장 아픈 것은 주석입니다. Kubernetes 매니페스트나 CI 설정 파일의 주석에는 '이 값을 바꾸면 안 되는 이유'처럼 코드로 표현되지 않는 지식이 담겨 있는데, JSON을 거쳐 되돌리면 전부 없어집니다. 설정 파일을 왕복 변환해 원본을 덮어쓰는 작업은 피해야 합니다.

YAML 기능JSON 변환 결과
# 주석완전히 소실
앵커(&)와 별칭(*)값이 전개되어 중복 복사됨
여러 문서(--- 구분)첫 문서만 남거나 오류
멀티라인 블록(| 과 >)\n이 포함된 하나의 문자열로
날짜 타입문자열로 변환
정수가 아닌 키(숫자·불리언 키)문자열 키로 강제 변환
태그(!!str 등)소실

앵커와 별칭

YAML은 같은 값을 재사용하는 문법을 제공합니다. &이름 으로 정의하고 *이름 으로 참조하며, <<: *이름 으로 매핑을 병합할 수 있습니다. Docker Compose나 GitLab CI에서 공통 설정을 한 번만 쓰기 위해 흔히 사용됩니다. JSON으로 변환하면 참조가 모두 실제 값으로 펼쳐지므로 결과는 정확하지만 중복이 생기고 파일이 커집니다.

앵커로 공통 설정 재사용
defaults: &defaults
  adapter: postgres
  encoding: utf8

development:
  <<: *defaults
  database: myapp_dev

test:
  <<: *defaults
  database: myapp_test

YAML의 타입 추론이 만드는 사고

YAML은 따옴표 없는 값의 타입을 스스로 추론합니다. 이 편의성이 유명한 버그들의 원인입니다. 가장 잘 알려진 것이 노르웨이 문제입니다. 국가 코드 NO를 따옴표 없이 쓰면 YAML 1.1 파서가 이를 불리언 false로 해석합니다. 같은 이유로 yes, no, on, off, y, n 도 불리언이 됩니다.

버전 번호도 자주 문제가 됩니다. version: 1.0 은 숫자 1.0으로 파싱되어 문자열 "1.0"이 아니게 되고, version: 1.0.0 은 점이 두 개라 문자열로 남습니다. 같은 파일 안에서 일관성이 깨지는 셈입니다. 또 앞자리가 0인 숫자(08)는 8진수로 해석을 시도해 오류가 나거나 다른 값이 되며, 시각 표기(12:30)는 60진수로 해석되어 750이 되는 구현도 있습니다.

해결책은 단순합니다. 문자열로 다뤄야 하는 값에는 따옴표를 붙이세요. 특히 버전, 국가·언어 코드, 전화번호, 앞자리 0이 있는 식별자, 시각 표기는 예외 없이 따옴표를 쓰는 습관이 안전합니다.

따옴표 유무가 만드는 차이
country: NO        # → false (불리언!)
country: "NO"      # → "NO"

version: 1.0       # → 1 (숫자)
version: "1.0"     # → "1.0"

zip: 08301         # → 8진수 해석 시도, 오류 또는 다른 값
zip: "08301"       # → "08301"

enabled: yes       # → true
enabled: "yes"     # → "yes"

들여쓰기 규칙

  • 탭 문자는 사용할 수 없습니다. YAML 규격이 명시적으로 금지하므로 반드시 공백을 쓰세요. 에디터가 탭을 삽입하도록 설정되어 있으면 원인을 찾기 어려운 파싱 오류가 납니다.
  • 들여쓰기 폭은 자유롭지만 같은 계층에서는 일치해야 합니다. 관례적으로 2칸을 씁니다.
  • 리스트 항목의 하이픈은 부모와 같은 열에 두어도 되고 한 단계 들여써도 됩니다. 둘 다 유효하지만 파일 안에서 하나로 통일하세요.
  • 콜론 뒤에는 공백이 필요합니다. key:value 는 하나의 문자열로 해석됩니다.
  • 값에 콜론과 공백이 함께 들어가면(예: 시간: 10: 30) 따옴표로 감싸야 합니다.

어느 형식을 쓸까

상황권장이유
API 요청·응답JSON파서가 어디에나 있고 모호함이 없음
사람이 편집하는 설정YAML주석과 간결한 문법
로그 (한 줄 한 레코드)JSON Lines줄 단위 처리와 스트리밍에 적합
빌드·CI 파이프라인 정의YAML생태계 표준
외부에 노출되는 스키마JSON검증 도구 생태계가 성숙
신뢰할 수 없는 입력 파싱JSONYAML은 파서 기능 범위가 넓어 위험 표면이 큼

자주 묻는 질문

모든 JSON은 유효한 YAML인가요?
YAML 1.2 규격상 그렇습니다. YAML 1.2가 JSON의 상위집합으로 정의되어 있어 JSON 문서를 YAML 파서에 그대로 넣을 수 있습니다. 다만 실제 구현은 YAML 1.1을 따르는 것도 많고 그 경우 일부 예외가 있으니, 중요한 파이프라인이라면 실제 파서로 확인하는 편이 안전합니다.
변환하면 키 순서가 유지되나요?
이 도구는 입력 순서를 유지합니다. 다만 YAML 매핑은 규격상 순서가 없는 집합으로 정의되어 있어, 다른 도구를 거치면 순서가 바뀔 수 있습니다. 순서에 의미를 두는 설계는 피하는 것이 좋습니다.
YAML 주석을 살릴 방법이 없나요?
JSON에는 주석 문법이 없으므로 왕복 변환으로는 보존할 수 없습니다. 주석을 유지하면서 YAML을 프로그램으로 수정해야 한다면, ruamel.yaml(Python)이나 yawn·yaml AST를 다루는 라이브러리처럼 주석을 보존하는 라운드트립 파서를 쓰세요. JSON을 중간 단계로 두지 않는 것이 핵심입니다.
멀티라인 문자열의 | 와 > 는 어떻게 다른가요?
| 는 리터럴 블록으로 줄바꿈을 그대로 보존하고, > 는 접힌 블록으로 줄바꿈을 공백으로 바꿉니다. 스크립트를 넣을 때는 |, 긴 설명 문장을 여러 줄로 나눠 쓸 때는 > 가 적합합니다. 뒤에 -를 붙이면(|-) 마지막 줄바꿈을 제거하고, +를 붙이면 끝의 빈 줄까지 보존합니다.
YAML 파싱이 보안 위험이 될 수 있나요?
됩니다. 일부 언어의 기본 YAML 로더는 태그를 통해 임의 객체를 생성할 수 있어, 신뢰할 수 없는 입력을 파싱하면 코드 실행으로 이어질 수 있습니다. Python은 yaml.load 대신 yaml.safe_load를, Ruby는 YAML.safe_load를 쓰세요. JavaScript의 js-yaml은 기본 스키마가 안전하지만 load에 넘기는 옵션을 확인하는 것이 좋습니다.
--- 로 나뉜 여러 문서를 변환하려면?
JSON 문서는 최상위 값이 하나여야 하므로 여러 YAML 문서를 하나의 JSON으로 바로 옮길 수 없습니다. 각 문서를 개별 JSON으로 변환하거나, 전체를 JSON 배열로 감싸는 형태로 다뤄야 합니다. Kubernetes 매니페스트를 다룰 때 자주 마주치는 상황입니다.

💡 참고: YAML에서 값이 예상과 다르게 들어왔다면 거의 항상 타입 추론입니다. 문자열이어야 하는 값에 따옴표를 붙였는지 먼저 확인하세요.

🔗관련 도구🔄 텍스트/데이터 변환