Skip to content
블로그로 돌아가기
튜토리얼

TOML vs JSON vs YAML: 어떤 설정 형식을 써야 할까?

설정 파일을 위한 TOML, JSON, YAML을 비교합니다. 주석, 데이터 타입, 날짜, 중첩, 실제 함정을 정리하고 명확한 선택 기준과 온라인 변환 팁을 제공합니다.

13 분 소요

TOML vs JSON vs YAML: 어떤 설정 형식을 써야 할까?

TOML vs JSON vs YAML를 짧게 요약하면 이렇습니다. JSON은 모든 언어가 파싱하는 기계 간 교환의 기본값이고, YAML은 Kubernetes와 CI 파이프라인을 돌리는 사람 친화적인 형식이며, TOML은 Cargo.toml이나 pyproject.toml 같은 도구·애플리케이션 설정을 위해 만들어진 명시적이고 타입이 분명한 형식입니다. 어디서나 이기는 단일 형식은 없습니다. 올바른 설정 파일 형식은 세 가지에 달려 있습니다. 누가 편집하는지, 주석이 필요한지, 타입이 얼마나 엄격해야 하는지입니다.

간단한 경험칙입니다. 기계가 쓰고 기계가 읽는다면 JSON을 고르세요. 사람이 매일 깊게 중첩된 인프라를 직접 편집한다면 YAML은 그 복잡함만큼의 값을 합니다. 실수하기 어려운, 분명하고 타입이 명시된 설정을 원한다면 TOML이 가장 안전한 선택입니다. 이 형식들은 서로 경쟁한다기보다 서로 다른 차선을 차지합니다. JSON은 기계용, YAML은 DevOps용, TOML은 도구 설정용입니다. 아래에서는 나란히 놓은 예제와 실제로 버그를 일으키는 차이, 다음 프로젝트에 바로 적용할 수 있는 의사 결정 매트릭스로 이를 뒷받침합니다.

30초 요약

30초밖에 없다면, 이 표가 설정 파일 형식 비교를 한눈에 담고 있습니다.

JSONYAMLTOML
주석없음있음 (#)있음 (#)
데이터 타입명시적, 최소한암묵적 (형태로 추론)명시적, 풍부함
네이티브 날짜없음버전에 따라 다름있음 (네 가지 타입)
중첩 방식중괄호 {}들여쓰기[section] 헤더
들여쓰기 민감아니요예 (탭 금지)아니요
여러 줄 문자열없음 (\n만)있음 (|>)있음 (""")
후행 쉼표금지해당 없음배열에서 허용
JSON의 상위집합예 (1.2)아니요
적합한 용도API, 데이터 교환K8s, CI, AnsibleRust/Python 도구 설정

그 표에서 한 줄짜리 결론 세 가지가 나옵니다.

  • JSON을 고르세요. 파일을 프로그램이 생성하고 소비할 때입니다. API 페이로드, package.json, tsconfig.json, 시스템 경계를 넘나드는 모든 것이 여기 해당합니다.
  • YAML을 고르세요. 사람이 깊고 중첩된 설정을 직접 편집하고 생태계가 이미 그것을 기대할 때입니다. Kubernetes 매니페스트, GitHub Actions, Docker Compose, Ansible 플레이북이 그렇습니다.
  • TOML을 고르세요. 도구나 애플리케이션을 위한 명확하고 타입이 분명한 설정을 원할 때, 대부분 평탄하고 섹션이 몇 개뿐이며 실력이 제각각인 기여자들이 편집할 때입니다. Cargo.toml, pyproject.toml, Hugo, Netlify가 그렇습니다.

그 결론들이 성립하는지는 이유를 파고들어야 드러납니다. 진짜 버그가 숨어 있는 곳도 바로 그 이유입니다.

같은 설정, 세 가지 방식

같은 설정을 세 형식으로 나란히 써 보면 차이가 가장 빠르게 드러납니다. 다음은 작은 서비스 설정입니다. 이름과 버전, 최상위 플래그 몇 개, 기능 목록, 그리고 중첩된 데이터베이스 블록으로 이루어져 있습니다.

JSON:

{
  "name": "acme-api",
  "version": "2.4.0",
  "debug": false,
  "released": "2026-07-02",
  "features": ["auth", "metrics", "tracing"],
  "database": {
    "host": "db.internal",
    "port": 5432,
    "max_connections": 100
  }
}

YAML:

name: acme-api
version: "2.4.0"
debug: false
released: "2026-07-02"
features:
  - auth
  - metrics
  - tracing
database:
  host: db.internal
  port: 5432
  max_connections: 100

TOML:

name = "acme-api"
version = "2.4.0"
debug = false
released = "2026-07-02"
features = ["auth", "metrics", "tracing"]

[database]
host = "db.internal"
port = 5432
max_connections = 100

셋 다 동일한 데이터를 서술합니다. 차이는 표기에서 드러납니다. JSON은 문장 부호가 가장 많습니다. 모든 키를 큰따옴표로 감싸고, 모든 단계마다 중괄호가 늘어나며, 후행 쉼표 하나만 잘못 남아도 구문 오류입니다. YAML은 그 대부분을 걷어내서 구조가 오직 들여쓰기에서 나옵니다. 탭이 몰래 끼어들기 전까지는 깔끔하게 읽힙니다. TOML은 그 중간에 있습니다. 문자열에만 따옴표를 쓰고, key = value 쌍을 쓰며, [database] 헤더가 예전 INI 파일이 하던 방식으로 중첩 블록에 이름을 붙입니다. released 필드가 셋 모두에서 따옴표로 감싼 문자열이라 여기서는 데이터가 동일하게 유지됩니다. 이는 의도적입니다. 날짜야말로 이 형식들의 합의가 깨지는 지점이기 때문입니다.

JSON — 기계 간 교환의 기본값

JSON은 생각 없이 손이 가는 형식이고, 대개 그 직감이 맞습니다. 주요 언어마다 파서를 기본 제공하고, 모든 HTTP API가 이 형식으로 말하며, 문법이 머릿속에 담아 둘 만큼 작습니다. 엄격하고 모호하지 않습니다. 문자열은 문자열이고, 5432는 숫자이며, true는 불리언이고, 각각을 쓰는 방법은 정확히 하나뿐입니다. 그 엄격함 덕분에 JSON은 한 번도 만난 적 없는 시스템들 사이에서 안전하게 주고받을 수 있습니다. Node 서비스가 Go 서비스로 JSON을 보내면, 둘은 바이트 단위로 의미가 일치합니다.

바로 그 견고함 때문에 JSON은 자기 영역을 지배합니다. package.json, tsconfig.json, composer.json이 JSON인 이유는 도구가 이들을 끊임없이 생성하고 다시 쓰기 때문이며, 기계가 쓰는 설정은 기계처럼 엄격한 형식을 원합니다. API 페이로드와 메시지 큐라면 다른 것을 고를 이유가 애초에 없습니다.

JSON의 약점은 사람이 직접 손으로 편집해야 하는 순간 모두 드러납니다. 주석이 없습니다. 후행 쉼표가 없어서 목록의 순서를 바꾸려면 쉼표를 손봐야 합니다. 여러 줄 문자열이 없고 \n 이스케이프만 있습니다. 모든 키에 큰따옴표가 필요합니다. 그리고 날짜 타입이 없어서 2026-07-02는 따옴표로 감싼 문자열로 존재하며 관례에 따라 파싱되어야 합니다. 사람이 유지 관리하는 설정 파일이라면 이런 빈틈이 쌓여 마찰이 됩니다.

”JSON에는 주석이 없다” 문제

가장 많이 요청되는 JSON 기능 하나는 Douglas Crockford가 일부러 빼놓은 것, 바로 주석입니다. 그의 논리는 주석이 사람들로 하여금 파싱 지시문을 설정 파일에 몰래 심게 만들어 상호 운용성을 깨뜨린다는 것이었습니다. 그 판단을 어떻게 생각하든, 평범한 JSON 설정에는 주석을 달 수 없고, 이는 사람이 유지 관리하는 모든 것에 고통스럽습니다. 실용적인 해법은 상위집합입니다. JSON5는 주석, 후행 쉼표, 따옴표 없는 키, 작은따옴표를 추가합니다. JSONC(JSON with Comments)는 VS Code가 설정에 사용하는 더 가벼운 변형입니다. 둘 다 JSON의 형태를 유지하면서 편집 가능하게 만듭니다. 주석이 필요하지만 JSON 계열에 머물고 싶다면, 각각을 언제 쓰고 도구를 어떻게 만족시킬지 다룬 JSON5와 JSONC 포매팅 가이드를 읽어 보세요.

YAML — 사람 친화적인 DevOps 표준

YAML은 키보드 앞의 사람에게 최적화되어 있습니다. 주석을 지원하고, 들여쓰기 기반 배치가 깊게 중첩된 구조를 깔끔하게 유지하며, 앵커를 쓰면 블록을 한 번 정의해 두고 복사·붙여넣기 대신 별칭으로 재사용할 수 있습니다.

defaults: &defaults
  timeout: 30
  retries: 3

staging:
  <<: *defaults
  host: staging.internal

production:
  <<: *defaults
  host: prod.internal

&defaults 앵커가 블록에 이름을 붙이고, <<: *defaults가 그것을 두 환경 모두에 병합하므로 공유 타임아웃을 바꾸는 일이 한 곳에서 일어납니다. JSON에도 TOML에도 이와 비슷한 것은 없습니다. 그 가독성 덕분에 YAML은 운영의 공용어가 되었습니다. Kubernetes 매니페스트, GitHub Actions 워크플로, Docker Compose 파일, Ansible 플레이북이 모두 YAML입니다. 설정이 다섯 단계 깊이이고 사람이 매일 손보는 경우라면, YAML의 적은 문장 부호는 진짜 안도감을 줍니다.

대가는 복잡함과 뜻밖의 상황입니다. YAML 1.2 명세는 방대하고 완전한 준수는 드물어서, 파서마다 가장자리에서 의견이 갈립니다. 들여쓰기가 의미를 가지고, 탭은 아예 금지되며, 어긋난 공백 하나가 의미를 바꾸거나 파싱을 실패시킬 수 있습니다. 가장 날카로운 부분은 암묵적 타이핑입니다. YAML은 따옴표 없는 스칼라의 타입을 그 형태로부터 추측하는데, 별명이 붙을 만큼 자주 틀리게 추측합니다.

한 문단으로 보는 노르웨이 문제

YAML에 country: NO라고 쓰면 많은 파서가 문자열 "NO"가 아니라 불리언 false를 내놓습니다. 대부분의 Kubernetes 도구가 여전히 따르는 YAML 1.1이 NO, YES, ON, OFF, Y, N을 불리언으로 취급하기 때문입니다. 노르웨이의 국가 코드가 오류 하나 없이 조용히 false가 됩니다. 같은 암묵적 타이핑이 0755를 8진수로, 1.201.2로 바꿉니다. 해법은 지루하지만 믿음직합니다. 다른 것으로 오해될 수 있는 문자열은 따옴표로 감싸세요. 이 자책골은 실제 장애 사례와 YAML 1.1 대 1.2의 역사를 포함해 별도의 심층 분석을 받을 만큼 유명하며, 이는 YAML 노르웨이 문제 가이드에서 다룹니다. 이 글에서 얻을 요점은 간단합니다. YAML의 편리함과 위험은 같은 기능에서 나옵니다.

YAML은 사람들이 깊게 중첩된 설정을 매일 편집하고 주변 생태계가 이미 그것을 요구할 때 이깁니다. Helm 차트를 작성하고 있다면 여러분은 YAML을 작성하고 있는 것이고, 그것으로 괜찮습니다.

TOML — 도구를 위해 만들어진 명시적 설정

TOML(Tom’s Obvious, Minimal Language, Tom Preston-Werner가 만듦)은 YAML 사용자들이 갖고 싶어 했던 설정 형식, 즉 읽기 좋으면서도 추측이 없는 형식이 되도록 설계되었습니다. 그 정의적 특징은 명시성입니다. 타입이 모호하지 않아서 port = 5432는 언제나 정수이고 name = "acme"는 언제나 문자열이며, 걸려 넘어질 형태 기반 추론이 없습니다. TOML 구문은 INI 파일에서 [section] 헤더를 빌려와 설정의 최상위를 훑어보기 쉽게 만들고, 들여쓰기에 민감하지 않아서 공백이 의미를 바꾸는 일이 결코 없습니다. TOML 1.0.0 명세는 작고 안정적인데, 이는 장점입니다. 잘못 기억할 것이 더 적으니까요.

TOML의 대표 기능은 네이티브 날짜·시간 타입이며, 이는 JSON도 순수 YAML도 깔끔하게 다루지 못합니다. 네 가지가 있습니다. 타임존이 있는 오프셋 date-time(1979-05-27T07:32:00Z), 타임존이 없는 로컬 date-time, 로컬 date(1979-05-27, 그냥 달력상의 하루), 그리고 로컬 time(07:32:00)입니다. 이는 배포 날짜가 다시 파싱해야 하는 문자열이 아니라 진짜 날짜로 남는다는 뜻입니다.

TOML 구문 세 가지가 대부분의 일을 합니다. [section] 헤더는 테이블을 엽니다. [tool.ruff] 같은 점 표기 헤더는 추가 들여쓰기 없이 한 테이블을 다른 테이블 안에 중첩합니다. 그리고 인라인 테이블 { version = "1.0", features = ["derive"] }은 작은 객체를 한 줄에 담습니다. 반복되는 섹션은 이중 헤더, 곧 테이블 배열을 씁니다.

[[servers]]
name = "alpha"
ip = "10.0.0.1"

[[servers]]
name = "beta"
ip = "10.0.0.2"

그 블록은 servers 키 아래에 객체 두 개로 이루어진 JSON 배열이 됩니다. 평탄한 목록에서는 읽기 좋으며, 이는 대부분의 도구 설정이 정확히 필요로 하는 것입니다.

약점은 실재하지만 좁습니다. TOML에는 null 타입이 없어서 값이 없다는 것은 그저 키를 생략한다는 뜻입니다. 깊은 중첩은 장황해집니다. 반복되는 중첩 구조의 모든 단계가 [[path]] 헤더 전체를 되풀이하기 때문이며, 이는 같은 내용의 YAML보다 더 시끄러워집니다. 그리고 TOML은 JSON이나 YAML보다 더 젊고 덜 보편적이어서 모든 도구가 이 형식으로 말하지는 않습니다. TOML은 이름표가 붙은 섹션 몇 개로 대부분 평탄한 설정에 가장 잘 맞으며, 이는 도구 설정의 압도적 다수를 서술합니다.

왜 Rust와 Python에 TOML인가?

TOML의 부상은 이를 표준으로 채택한 두 생태계를 따릅니다. Rust의 패키지 매니저 Cargo는 모든 크레이트에 Cargo.toml을 쓰므로, 모든 Rust 개발자가 첫날부터 TOML을 읽고 씁니다. Python이 뒤를 이었습니다. PEP 518이 빌드 요구 사항을 선언하기 위해 pyproject.toml을 도입했고, PEP 621이 같은 파일 안에 프로젝트 메타데이터(이름, 버전, 의존성, 그리고 [tool.*] 섹션)를 표준화하여 여기저기 흩어져 있던 setup.py, setup.cfg, 도구별 설정을 대체했습니다. 이 둘 말고도 Hugo, Netlify, Poetry, Foundry가 모두 TOML을 기본값으로 씁니다. 공통점은 기여자가 손으로 편집하며 영리하기보다 분명한 편이 이로운 도구 설정이라는 점입니다.

정면 대결 — 실제로 발목을 잡는 차이

기능 표는 깔끔합니다. 버그는 그렇지 않습니다. 다음은 실제 문제를 일으키는 구체적인 차이들이며, 각각 어떤 파서에든 넣어 볼 수 있는 작은 예제가 딸려 있습니다.

주석

JSON에는 주석 구문이 전혀 없습니다. TOML과 YAML은 둘 다 줄 끝까지 가는 #을 씁니다.

# TOML: 앞에 붙는 주석
port = 5432  # 뒤에 붙는 주석
# YAML: 동일한 주석 스타일
port: 5432   # 후행 주석

엄격한 JSON에 //#을 붙여 넣는 순간 파싱이 실패합니다. 이는 겉치레 문제가 아닙니다. 주석 없이 사람이 유지 관리하는 설정은 누군가의 머릿속에만 사는 암묵적 지식을 쌓아 갑니다.

데이터 타입과 날짜

JSON의 타입은 명시적이지만 빈약하고 날짜 타입이 없습니다. TOML의 타입은 명시적이고 풍부합니다. YAML의 타입은 암묵적이며, 앞서 다뤘듯이 이따금 틀립니다. 날짜가 가장 뚜렷한 분기점입니다. TOML은 네 종류 모두를 네이티브로 표현합니다.

odt = 1979-05-27T07:32:00Z   # 오프셋 date-time (타임존 있음)
ldt = 1979-05-27T07:32:00    # 로컬 date-time (타임존 없음)
ld  = 1979-05-27             # 로컬 date (달력상의 하루)
lt  = 07:32:00               # 로컬 time

그 TOML을 JSON으로 변환하면 각 값은 의미를 유지하는 문자열이 됩니다. 로컬 date는 가짜 자정 타임스탬프로 부풀려지는 대신 "1979-05-27"로 남습니다. 저희 TOML to JSON 변환기는 그 날짜 종류를 정확히 보존하는데, 이는 순진한 변환기들이 흔히 틀리는 부분입니다. 한편 YAML은 파서와 스키마 버전에 따라 1979-05-27을 날짜로 취급할 수도, 안 할 수도 있으며, 이것이 바로 프로덕션 설정에서 원치 않는 모호함입니다.

중첩 깊이

설정이 깊게 중첩될수록 형식들이 더 갈라집니다. 작은 Docker Compose 스타일 트리를 봅시다.

services:
  web:
    build:
      context: .
      args:
        NODE_ENV: production
    ports:
      - "8080:8080"

YAML은 깊이를 순수한 들여쓰기로 표현하며 간결하게 유지됩니다. 같은 구조를 TOML로 쓰면 각 헤더에 전체 경로를 일일이 적어야 하고, 스칼라 값을 자식 테이블보다 앞으로 옮겨야 합니다.

[services.web]
ports = ["8080:8080"]

[services.web.build]
context = "."

[services.web.build.args]
NODE_ENV = "production"

JSON은 트리를 중첩된 중괄호로 담는데, 모호하지 않지만 문장 부호가 많습니다. 얕은 설정에서는 셋이 비슷하게 느껴집니다. 세 단계나 네 단계를 넘어서면 YAML이 눈에 띄게 날씬하고 TOML이 눈에 띄게 반복적입니다. 바로 그 한 가지 차이가 Kubernetes가 YAML을 고르고 Cargo가 TOML을 고른 이유를 설명합니다.

들여쓰기 민감성

공백을 신경 쓰는 것은 YAML뿐입니다. JSON과 TOML에서는 원하는 대로 들여쓰거나 전혀 들여쓰지 않아도 의미가 동일합니다. YAML에서는 들여쓰기가 구조이고 탭이 불법이라, 탭을 삽입하는 에디터나 잘못된 깊이에 붙여 넣은 블록이 문서를 조용히 바꾸거나 불러오기를 거부합니다. 목록 항목 하나가 한 칸 더 들여쓰이면 아무 오류 없이 엉뚱한 부모 키에 달라붙을 수 있는데, 파일이 여전히 멀쩡해 보이기 때문에 눈으로 잡아내기 미칠 노릇인 버그입니다. 기여자들이 제각각인 에디터와 설정을 쓴다면, 그것은 YAML이 물리고 나머지 둘은 물리지 않는 상시 세금이며, 큰 YAML 설정이라면 CI에서 린터를 돌려야 할 강력한 이유입니다.

여러 줄 문자열

JSON은 문자열 안에 실제 줄바꿈을 담지 못하며, \n으로 이스케이프합니다. YAML과 TOML은 둘 다 진짜 여러 줄 문자열을 가지고 있습니다.

{ "note": "line one\nline two" }
note: |
  line one
  line two
note = """
line one
line two
"""

YAML의 |은 줄바꿈을 유지하고(> 블록은 대신 줄바꿈을 공백으로 접습니다), TOML의 """도 비슷하게 동작하며 여는 따옴표 바로 뒤에 오는 줄바꿈을 잘라냅니다. 내장 스크립트, SQL, 도움말 텍스트라면 이것 하나만으로 형식을 결정할 수 있습니다.

후행 쉼표와 엄격성

JSON은 셋 중 가장 엄격합니다. 배열의 마지막 요소 뒤에 오는 후행 쉼표는 구문 오류입니다.

# 유효한 TOML — 후행 쉼표는 괜찮습니다
ports = [
  8001,
  8002,
]

JSON에서 8002 뒤에 붙은 같은 후행 쉼표는 파싱에 실패하며, 그래서 JSON 배열에 한 줄을 추가하는 일이 종종 윗줄의 쉼표까지 손보는 일이 됩니다. TOML은 후행 쉼표를 허용하고, YAML의 줄마다 대시를 붙이는 목록 구문은 이 문제를 아예 비켜 갑니다. 엄격함은 기계 간 교환에서는 미덕이고 손 편집에서는 성가심이며, 이는 반대편에서 본 같은 절충입니다. 이것 또한 JSON5와 JSONC가 특별히 JSON을 위해 없애고자 한 마찰입니다.

큰 정수와 2^53 천장

세 형식 모두 64비트 정수를 텍스트로 수 있습니다. 문제는 그 값이 자바스크립트(JavaScript)를 거칠 때 시작됩니다. 브라우저의 JSON 숫자는 IEEE-754 double이라 정수를 2^53 − 1(9007199254740991)까지만 정확히 표현할 수 있기 때문입니다. Snowflake ID나 나노초 타임스탬프는 그보다 크므로, JS 기반 도구를 왕복하면 값이 반올림되어 손상됩니다.

snowflake = 1420070400000000000   # TOML 텍스트에서는 정확함
{ "snowflake": "1420070400000000000" }

모든 형식에서 믿음직한 해법은 그런 값을 따옴표로 감싼 문자열로 저장하여 숫자 파서가 절대 건드리지 않게 하는 것입니다. 이는 특정 형식의 결함이 아니라 변환을 수행하는 런타임의 한계입니다. 저희 변환기는 정수가 그 선을 넘을 때 조용히 손상시키는 대신 경고해 줍니다.

어떻게 고를까 — 의사 결정 매트릭스와 흐름도

어떤 설정 형식을 쓸지 실제로 정할 때는, 질문을 순서대로 짚어 가다가 처음으로 확실한 ‘예’가 나오는 곳에서 멈추세요.

  1. 파일을 주로 프로그램이 쓰고 읽는가, 아니면 생태계가 이미 형식을 강제하는가? 그렇다면 JSON을 쓰세요. API 페이로드는 JSON입니다. package.json 옆에 있는 파일은 JSON입니다. 도구와 싸우지 마세요.
  2. 사람이 그것을 기대하는 스택(Kubernetes, CI, Ansible) 안에서 깊고 중첩된 설정을 매일 직접 편집하는가? 그렇다면 YAML을 쓰고, 노르웨이 문제를 피하기 위한 따옴표 규칙을 채택하세요.
  3. 도구나 애플리케이션 설정이고, 대부분 평탄하며 섹션이 몇 개뿐이고, 실력이 제각각인 기여자들이 편집하며, 타입이 분명하고 명확한 편이 간결한 편보다 나은가? 그렇다면 TOML을 쓰세요.

두 답이 비긴다면, 이 축 지도로 가르세요.

요구 사항가장 적합이유
파일 내 주석TOML 또는 YAMLJSON에는 없음
네이티브 날짜/시간 값TOML명시적 날짜 타입 네 가지
매우 깊은 중첩YAML들여쓰기가 간결하게 유지됨
공백으로 인한 뜻밖의 상황 없음JSON 또는 TOML들여쓰기에 민감하지 않음
생태계 파일에 고정됨JSONpackage.json, tsconfig.json
사람이 편집, 섹션 적음TOML명시적 타입, INI 같은 헤더
기계 대 기계 교환JSON보편적, 엄격, 빠름
타입 추론이 절대 추측하면 안 됨JSON 또는 TOMLYAML은 암묵적으로 추론함

대부분의 프로젝트는 결국 둘 이상을 쓰게 됩니다. 한 저장소에 손으로는 절대 건드리지 않는 JSON package.json, Python 도구를 위한 TOML pyproject.toml, .github 안의 YAML 워크플로, 그리고 이 문법들 중 어느 것도 따르지 않는 로컬 비밀 값용 .env 파일이 함께 있을 수 있습니다. 그 혼합은 정상이며, 바로 그것이 핵심입니다. 각 파일은 자신의 편집자에게 맞는 형식으로 존재합니다. .env 계층이 여러분의 구성에 포함된다면, 저희 .env 파일 형식 가이드가 그것이 JSON 설정 곁에서 어디에 들어맞는지, 그리고 둘 사이를 어떻게 변환하는지 다룹니다.

TOML, JSON, YAML 사이의 변환

여러분은 예상보다 자주 이 형식들 사이를 변환하게 됩니다. CI 작업이 손으로 쓴 pyproject.toml을 읽어 의존성 대시보드에 넣기 위해 JSON으로 바꿔야 합니다. 마이그레이션이 더 엄격한 타이핑을 위해 앱을 YAML 설정에서 TOML로 옮깁니다. 코드 리뷰는 공백에 민감한 원본보다 두 파일의 JSON 형태를 비교할 때 더 쉽습니다. 각 방향에는 붙여 넣기 전에 알아 둘 만한 함정이 있습니다.

TOML에서 JSON으로. 주된 위험은 날짜입니다. 1979-05-27 같은 로컬 date는 시간과 타임존을 지어내는 자정 UTC 타임스탬프가 아니라 달력상의 날짜로 남아야 합니다. 주석도 사라집니다. JSON이 그것을 담을 수 없기 때문입니다. TOML to JSON 변환기는 각 날짜 종류를 충실히 보존하여 왕복이 무손실로 유지되게 합니다.

JSON에서 TOML로. TOML은 구조에 더 엄격하여 두 가지가 변환을 막을 수 있습니다. TOML 문서는 항상 루트가 테이블이므로 최상위는 객체여야 하며, 헐벗은 배열이나 스칼라는 갈 곳이 없습니다. 그리고 TOML에는 null이 없어서 null 객체 값은 (어떤 키인지 나열하는 경고와 함께) 버려지고, 배열 안의 null은 유효한 TOML 표현이 아예 없습니다. JSON to TOML 변환기는 깨진 출력을 내놓는 대신 두 경우를 모두 명시적으로 드러냅니다.

JSON과 YAML, 양방향. 여기서 지켜볼 것은 노르웨이 문제입니다. 따옴표 없는 NO0755가 경계를 넘으면서 타입이 뒤집힐 수 있습니다. JSON to YAML 변환기YAML to JSON 변환기는 따옴표 처리를 맡아 문자열이 문자열로 남게 합니다.

어떤 변환이든 끝난 뒤에는 결과를 검증할 가치가 있습니다. 출력을 JSON 포맷터에 넣어 보면, 커밋하거나 하류로 보내기 전에 JSON이 올바른 형식이고 일관되게 들여쓰기되었는지 확인됩니다. 그리고 설정 파일은 비밀 값(레지스트리 토큰, 데이터베이스 자격 증명, 배포 키)을 담기 때문에, 이 모든 것은 전적으로 여러분의 브라우저에서 실행됩니다. 아무것도 업로드되지 않으므로, 비공개 레지스트리 토큰이 담긴 Cargo.toml이나 자격 증명이 담긴 values 파일이 여러분의 기기를 떠나는 일은 결코 없습니다.

자주 묻는 질문 (FAQ)

TOML이 YAML보다 나은가요?

어느 쪽도 보편적으로 낫지는 않습니다. TOML vs YAML 선택은 형태로 귀결됩니다. TOML은 명시적 타입과 들여쓰기 함정이 없는 덕분에 틀리기가 더 어려워서, 대부분 평탄한 도구 설정에서 이깁니다. YAML은 깊은 중첩을 더 간결하게 표현해서, Kubernetes 같은 크고 계층적인 인프라에서 이깁니다.

설정 파일에는 JSON과 YAML 중 무엇을 써야 하나요?

사람이 편집하는 설정이라면 YAML을 선호하세요. 주석을 허용하고 깔끔하게 읽히는데, JSON은 그렇지 못합니다. 프로그램이 생성하고 소비하는 설정이라면 JSON을 선호하세요. 엄격하고, 빠르고, 보편적입니다. 갈림선은 누가 편집하느냐, 즉 사람이냐 기계냐입니다.

JSON은 왜 주석을 허용하지 않나요?

JSON을 만든 Douglas Crockford는 주석을 일부러 제거했습니다. 그는 사람들이 주석에 파싱 지시문을 심어 파서 간 상호 운용성을 깨뜨릴까 걱정했습니다. JSON 형태의 파일에 주석이 필요하다면, 핵심 구조를 바꾸지 않고 주석을 되살려 주는 JSON5나 JSONC를 쓰세요.

YAML의 노르웨이 문제란 무엇인가요?

YAML 1.1이 따옴표 없는 특정 단어를 불리언으로 취급하는 것으로, country: NO가 문자열 "NO"가 아니라 false가 됩니다. YES, ON, OFF도 똑같이 동작합니다. 값을 따옴표로 감싸면 막을 수 있습니다. 전체 이야기는 위에 링크한 전용 가이드를 참고하세요.

TOML은 주석을 지원하나요?

예. TOML은 YAML과 똑같이 주석에 #을 쓰며, 별도의 줄에도 값 뒤에도 붙일 수 있습니다. 다만 TOML을 JSON으로 변환하면 주석은 사라지는데, JSON에는 그것을 담을 주석 구문이 없기 때문입니다.

TOML은 JSON이 표현할 수 있는 모든 것을 표현할 수 있나요?

거의 그렇습니다. JSON vs TOML 격차는 작지만 실재합니다. TOML에는 null 타입이 없어서 JSON의 null은 변환 시 버려지거나 거부되고, TOML 문서는 최상위가 테이블이어야 해서 헐벗은 JSON 배열이나 스칼라는 먼저 키 아래에 감싸지 않고서는 변환할 수 없습니다.

YAML은 JSON의 상위집합인가요?

YAML 1.2부터는 그렇습니다. 유효한 JSON 문서는 모두 유효한 YAML이기도 해서, YAML 파서는 JSON을 바로 읽을 수 있습니다. 유용한 사실이지만, 이를 보안 경계로 의지하지는 마세요. YAML 파서는 JSON에 없는 기능(앵커 같은 것)을 추가하기 때문입니다.

어떤 설정 형식이 파싱이 가장 빠른가요?

JSON이 대체로 가장 빠르며, 모든 언어에서 가장 성숙하고 최적화된 파서를 갖고 있습니다. YAML은 방대한 명세와 암묵적 타이핑 때문에 파싱이 가장 느리고 가장 복잡합니다. TOML은 그 중간에 있으며, 속도 면에서 YAML보다 JSON에 더 가깝습니다.

태그: toml json yaml configuration data-conversion