코드를 작성한 지 일주일이 넘었다면, 거의 틀림없이 JSON을 만나보셨을 겁니다. REST API 응답, 설정 파일, 데이터베이스 문서, 브라우저 스토리지, 로그 등 어디에나 등장합니다. 하지만 JSON이란 정확히 무엇이고, 어떻게 웹을 집어삼킨 포맷이 되었을까요?

JSON은 JavaScript Object Notation의 약자입니다. 이름과는 달리 언어에 완전히 독립적이며, 모든 주요 프로그래밍 언어에 라이브러리가 존재합니다. 더글라스 크록포드(Douglas Crockford)가 2000년대 초 브라우저-서버 통신에서 XML을 대체할 더 단순한 대안으로 형식화했습니다. 이 명세는 ECMA-404로도 표준화되어 있으며, 명함 한 장에 다 들어갈 정도로 작습니다 — JSON이 승리한 이유 중 하나이기도 합니다.

JSON은 실제로 어떻게 생겼을까?

다음은 사용자 객체를 나타내는 JSON 예제입니다. 이 단 하나의 예제가 JSON이 지원하는 6가지 데이터 타입을 모두 커버합니다:

json
{
  "name": "Alice",
  "age": 30,
  "score": 98.5,
  "active": true,
  "nickname": null,
  "tags": ["developer", "blogger"],
  "address": {
    "city": "Berlin",
    "country": "Germany"
  }
}

JSON의 여섯 가지 데이터 타입

JSON이 지원하는 값의 타입은 정확히 여섯 개입니다. 그게 전부예요. 이 단순함이 곧 장점입니다 — 오후 한나절이면 전체 포맷을 익힐 수 있습니다.

json
{
  "string":  "Hello, world",
  "integer": 42,
  "float":   3.14159,
  "boolean": true,
  "nothing": null,
  "array":   [1, "two", false, null],
  "object":  { "nested": true }
}
  • 문자열(String) — 큰따옴표로 감싼 모든 텍스트. "hello", "2024-01-01", ""는 모두 유효한 문자열입니다.
  • 숫자(Number) — 정수 또는 부동소수점. int와 float의 구분이 없습니다. 참고: NaNInfinity는 유효한 JSON 숫자가 아닙니다.
  • 불리언(Boolean)true 또는 false. 소문자만 허용됩니다.
  • Null — "값 없음"을 나타냅니다. 아직 설정되지 않은 선택적 필드에 유용합니다.
  • 배열(Array) — 순서가 있는 값의 목록. 타입을 섞어 쓸 수 있습니다: [1, "two", true, null]는 완벽히 합법입니다.
  • 객체(Object) — 키-값 쌍의 집합. 키는 반드시 큰따옴표로 감싼 문자열이어야 합니다.

실제 API 응답 예제

GET /api/users/42를 호출했을 때 실제 REST API 응답이 어떻게 생겼을지 보여드립니다. 풍부한 데이터를 표현하기 위해 객체와 배열을 어떻게 중첩하는지 주목해 보세요:

json
{
  "id": 42,
  "username": "alice_dev",
  "email": "[email protected]",
  "createdAt": "2023-06-15T09:30:00Z",
  "preferences": {
    "theme": "dark",
    "notifications": true,
    "language": "en"
  },
  "roles": ["user", "editor"],
  "lastLogin": "2024-01-10T14:22:00Z",
  "stats": {
    "postsPublished": 27,
    "commentsWritten": 154,
    "likesReceived": 489
  }
}

자바스크립트에서는 user.preferences.themealice_dev의 테마 설정에 접근할 수 있고, user.roles[0]로 첫 번째 역할을 가져올 수 있습니다. 언어의 기본 자료형과 이렇게 자연스럽게 매핑되는 것이 JSON을 이토록 편하게 쓸 수 있게 해주는 이유입니다.

JSON 문법 규칙 — 누구나 한 번씩 당하는 함정

JSON은 단순해 보이지만 몇 가지 엄격한 규칙이 있습니다. 하나라도 어기면 전체 페이로드의 파싱이 실패합니다. 제가 가장 자주 보는 실수들은 다음과 같습니다:

  • 키는 반드시 큰따옴표로 감싸야 합니다. {"name": "Alice"}는 유효합니다. {name: "Alice"}는 유효하지 않습니다. 따옴표 없는 객체 키가 허용되는 자바스크립트에서 넘어온 개발자들이 자주 걸려 넘어지는 부분이에요.
  • 후행 쉼표 금지. {"a": 1, "b": 2,}는 파싱 에러를 던집니다. 자바스크립트는 여기서 관대하지만 JSON 명세는 그렇지 않습니다.
  • 주석 금지. ///* */ 주석은 JSON에 존재하지 않습니다. 주석이 들어간 설정 파일이 필요하다면 YAML이나 TOML을 고려해 보세요.
  • undefined 없음. 자바스크립트의 undefined는 JSON에 존재하지 않습니다. 누락된 값에는 null을 사용하세요.
  • 문자열은 큰따옴표를 사용해야 합니다. {'key': 'value'}처럼 작은따옴표로 묶인 문자열은 유효하지 않은 JSON입니다.
  • 앞자리 0 금지. 042는 유효하지 않습니다. 420.42는 괜찮습니다.
팁: JSON을 어딘가에 붙여넣고 파싱 에러가 났다면, 범인은 거의 항상 다음 중 하나입니다: 후행 쉼표, 작은따옴표로 묶인 키, 또는 잘못 들어간 주석. JSON 검증기에 붙여넣으면 문제를 일으키는 정확한 줄을 짚어낼 수 있습니다.

JSON이 웹을 제패한 이유

JSON 이전에는 XML이 왕이었습니다. 전형적인 XML API 응답은 장황했고, 제대로 된 XML 파서가 필요했으며, 언어와 싸우는 느낌이었습니다. JSON은 자바스크립트 내장 JSON.parse()로 파싱할 수 있었고 — 라이브러리도 필요 없었습니다. 전송 크기가 더 작고, 한눈에 읽히며, 개발자들이 매일 사용하던 객체와 배열에 곧바로 매핑되었습니다.

2000년대 후반에 이르러 대부분의 공개 API들은 XML과 함께 JSON을 제공하기 시작했습니다. 2010년대 초에는 많은 곳이 XML 지원을 완전히 폐기했습니다. 오늘날 모든 REST API의 기본 전제는 JSON입니다. 많은 맥락에서 REST를 대체한 GraphQL조차 여전히 응답 포맷으로 JSON을 사용합니다.

JSON은 지원하지 않는 것으로도 정의된다

JSON의 제약 중 일부는 단순함과 상호운용성을 유지하기 위한 의도적인 설계 결정입니다:

  • 날짜 타입이 없습니다. 날짜는 그냥 문자열입니다. 관례적으로 ISO 8601 형식을 사용합니다: "2024-01-15T09:30:00Z".
  • 바이너리 데이터가 없습니다. 파일과 이미지는 보통 Base64로 인코딩해서 문자열에 넣습니다.
  • 함수 값이 없습니다. {"fn": function(){} }는 유효하지 않습니다. JSON은 순수한 데이터이지, 코드가 아닙니다.
  • 중복 키 금지. 기술적으로는 명세상 허용되지만 동작은 정의되지 않았습니다. 실제로는 파서가 마지막 값을 채택합니다.

JSON 작업에 유용한 도구들

JSON을 다룰 때 계속 찾게 될 몇 가지 도구를 소개합니다: 축소된 응답을 예쁘게 출력해주는 JSON Formatter, 문법 오류를 찾아주는 JSON Validator, 프로덕션용으로 JSON을 압축하는 JSON Minifier, 그리고 반복문 없이 깊이 중첩된 데이터를 조회할 수 있는 JSON Path.

공식 명세는 json.org에 있고, 실제로 읽어볼 만한 가치가 있습니다 — 10분 정도면 포맷을 완전히 이해할 수 있습니다. IETF의 공식 명세는 RFC 8259이며, 논쟁을 매듭지어야 할 때 유용합니다.

마무리

JSON은 문자열, 숫자, 불리언, null, 배열, 객체라는 여섯 가지 값 타입 위에 세워진 가볍고 사람이 읽기 쉬운 데이터 포맷입니다. 엄격한 문법 규칙이 있지만 일단 익히고 나면 놀랄 일은 없습니다. JSON이 어디에나 쓰이게 된 이유는 가장 강력한 포맷이어서가 아니라, 현실 데이터 요구의 95%를 커버하는 가장 단순한 포맷이기 때문입니다. 웹 관련된 무언가를 만들고 있다면, JSON을 이해하는 건 선택이 아니라 기본입니다.