포맷팅 · 2026년 9월 3일

JSON 포맷팅 모범 사례 — 들여쓰기, 가독성, 그리고 끝나지 않는 토론

탭 vs 공백, 쉼표, 정렬된 키, 컴팩트 vs 예쁘게 — 모든 JSON 포맷팅 결정에는 트레이드오프가 있습니다. 실제로 중요한 것을 설명합니다.

JSON의 문법은 최소한입니다. 6가지 값 타입, 주석 없음, 쉼표 없음, 문자열 인용 방식의 유연성 없음. 이 엄격함이 기계에게는 강점이지만 인간에게는 약점입니다. 인간이 JSON을 읽거나 써야 할 때 — 설정 파일, API 응답, diff — 포맷팅이 중요합니다.

이 게시물은 직면할 모든 포맷팅 결정, 생태계가 무엇을 결정했는지, 그리고 토론이 아직 진행 중인 곳을 다룹니다.

들여쓰기: 2공백이 승자

탭 vs 공백 전쟁은 JSON 세계에서 승자를 맞았습니다: 2공백. 거의 모든 주요 스타일 가이드, 린터, 포맷터는 기본적으로 2공백 들여쓰기를 사용합니다:

  • Google JSON 스타일 가이드 — 2공백
  • Prettier — 2공백(기본값)
  • ESLint — 2공백(대부분의 설정)
  • AWS CloudFormation — 2공백
  • Kubernetes 매니페스트 — 2공백

이유는 실용적입니다: JSON은 이미 따옴표와 중괄호로 장황합니다. 4공백 들여쓰기는 중첩된 객체를 대부분의 에디터 오른쪽 끝으로 밀어냅니다. 2공백은 수평 공간을 낭비하지 않으면서 가독성을 유지합니다.

팀이 선호하고 일관성이 있다면 4공백을 사용하세요.必要하다면 탭을 사용하지만, 대부분의 JSON 도구는 공백을 가정하며, JSON 파일에서 혼합된 들여쓰기는 파싱 에러의 원인이 된다는 것을 알아두세요.

쉼표: 아직 안 됨

JSON은 쉼표를 허용하지 않습니다. 이것은 수동으로 편집된 JSON 파일에서 가장 흔한 구문 에러입니다. 이렇게 씁니다:

{
  "name": "Alice",
  "items": ["a", "b",],
}

엄격한 파서는它을 거부합니다. "b" 뒤의 쉼표와 닫는 중괄호 } 뒤의 쉼표는 둘 다 불법입니다.

YAML은 쉼표를 허용합니다(대부분의 언어가 그렇듯). JSON은 허용하지 않습니다. 도구가 JSONC(VS Code의 tsconfig.json과 settings.json에서 사용되는 주석이 있는 JSON)를 지원하는 경우 쉼표는 허용됩니다. 하지만 순수 JSON — API를 통해 전달되는 종류 — 은它을 용납하지 않습니다.

최선의 방어: 이것이 자동으로 잡히는 포맷터를 사용하세요. 커밋 전에 JSON을 검증기에 붙여넣으세요.

예쁘게 vs 컴팩트

예쁘게 포맷된 JSON에는 줄 바꿈과 들여쓰기가 있습니다. 가독성이 좋고, diff 가능하며, 디버깅 가능합니다:

{
  "status": "ok",
  "count": 42
}

컴팩트한 JSON에는 토큰 사이에 공백이 없습니다. 전송 시 더 작습니다:

{"status":"ok","count":42}

경험 법칙:

  • 사람 대상 (설정 파일, 로그, 디버깅 중 API 응답) → 예쁘게.
  • 기계 대상 (프로덕션 API 페이로드, 메시지 큐, 이벤트 스트림) → 컴팩트.
  • 저장소 (데이터베이스, 캐시) → 컴팩트, 디버깅 중 수동으로 읽을 필요가 없는 한.

컴팩트 JSON은 2공백 예쁘게 포맷된 JSON과 비교하여 약 20-30%의 크기를 절약합니다. 10KB 페이로드의 경우 2-3KB입니다. 수백만 요청을 통해它是 누적됩니다. 수동으로 편집하는 설정 파일의 경우 예쁘게 포맷된 JSON의 가독성은 추가 바이트 가치가 있습니다.

정렬된 키

객체 키는 알파벳순으로 정렬되어야 할까요?

찬성: diff가 결정론적입니다. 키를 추가하면 해당 줄만 git diff에 나타납니다. 정렬된 키가 없으면 중간에 키를 삽입하면 후속 모든 키가 이동하여 시끄러운 diff가 생성됩니다.

반대: 논리적 그룹화가 더 가독성이 좋습니다. "name"을 먼저, "id"를 두 번째로 하는 것이 직관적입니다. 알파벳 정렬은 의미론적 이유 없이 "address"를 "name" 앞에 둡니다.

실용적인 답변: 기계가 생성한 JSON(API, 설정, diff)에서는 키를 정렬하세요. 수동으로 작성한 JSON에서는 논리적 순서를 유지하세요. 대부분의 포맷터(Prettier, jq, python -m json.tool)에는 CI에서 활성화할 수 있는 --sort-keys 플래그가 있습니다.

키 명명 규칙

JSON 키는 문자열이며, 생태계는 두 가지 규칙으로 정착했습니다:

  • camelCase — JavaScript/Node.js 기본값. firstName, lastName, createdAt.
  • snake_case — Python/Ruby/Rust 기본값. first_name, last_name, created_at.
  • kebab-case — JSON에서는 드물고, URL과 CSS에서는 더 흔함. API 키에는 피하세요.

하나를 선택하고 고수하세요. 대부분의 API는 camelCase를 사용합니다. JavaScript 소비자를 위한 REST API를 구축하는 경우 camelCase가 최소 저항의 경로입니다. Python 서비스와 인터페이스하는 경우 snake_case가 마찰을 줄입니다.

가장 나쁜 것은 혼합하는 것입니다: 한 엔드포인트에서는 firstName, 다른 곳에서는 last_name. 규칙을 선택하고, 린터로 강제하고, 진행하세요.

숫자 포맷팅

JSON은 정수와 실수를 구분하지 않습니다. 42와 42.0은 둘 다 유효하며, 대부분의 파서는它们을 동일하게 취급합니다. 하지만 가독성에는 포맷팅이 중요합니다:

  • 정수: 소수점 없음. 42, 42.0이 아님.
  • 실수: 필요한 만큼의 자릿수 사용. 3.14159, 3.14159000000000이 아님.
  • 큰 숫자: 숫자가 거대하면 과학적 표기법 사용. 1e10이 10000000000보다 명확함.

JSON은 Infinity, -Infinity, NaN을 지원하지 않습니다. 언어가这些을 직렬화하면 출력은 유효한 JSON이 아니며 파서는它을 거부합니다.

문자열: 따옴표 vs 쌍따옴표

JSON은 문자열에 쌍따옴표를 요구합니다. 이는 협상의 여지가 없습니다. 'hello'는 유효한 JSON이 아닙니다. "hello'는 유효합니다.

린터나 에디터가 JSON 파일에서 따옴표를 허용하는 경우, JSONC 또는 상위 집합을 파싱하는 것이지 표준 JSON이 아닙니다. 엄격한 JSON을 기대하는 API와 파서는 따옴표로 감싼 문자열을 거부합니다.

주석: 아직 허용되지 않음

JSON에는 주석 구문이 없습니다. 이는 설계에 의한 것입니다(사양은 JSON을 “데이터 교환 포맷”이라고 정의하며, 설정 언어가 아닙니다),但它은 YAML를 사용하는 개발자들의 가장 흔한 불만입니다.

해결책:

  • "comment" 또는 "_comment" 키를 사용하세요. 보기 흉하지만 유효합니다.
  • 도구가 지원하는 경우 JSONC(VS Code 포맷)를 사용하세요.
  • 주석이 중요한 설정 파일에는 YAML 또는 TOML로 전환하세요.

포맷터 워크플로

JSON 포맷팅의 최상의 워크플로:

  1. 원하는 방식으로 JSON을 작성하세요. 수동 들여쓰기에 시간을 낭비하지 마세요.
  2. 저장 시 포맷터를 실행 Prettier, jq 또는 에디터의 내장 포맷터.
  3. 포맷된 출력을 커밋 일관된 diff, 스타일 토론 없음.
  4. CI에서 검증 JSON lint 단계가 프로덕션에 도달하기 전에 쉼표와 구문 에러를 잡습니다.

이렇게 하면 모든 포맷팅 토론이 사라집니다. 포맷터가 결정하고, 다른 모든 사람이 코드를 작성합니다.

일반적인 실수

  • 쉼표 — 수동으로 편집된 JSON에서 가장 빈번한 파싱 에러.
  • 따옴표 — JavaScript 객체 리터럴에서는 유효, JSON에서는 무효.
  • 따옴표 없는 키 — { name: "Alice" }는 JavaScript이며, JSON이 아닙니다.
  • 주석 — // 이것은 JSON이 아니다나 /* 이것도 아니다 */.
  • 혼합된 들여쓰기 — 같은 파일에서 탭과 공백을 혼합.

배포 전에 JSON을 검증기에 붙여넣으세요. 1초밖에 걸리지 않으며, 신비로운 400 에러를 30분 디버깅하는 것을 절약합니다.