개발자

거의 모든 SW 개발의 필수⋯JSON 데이터 포맷의 이해

Matthew Tyson | InfoWorld 2022.08.31
JSON은 JavaScript Object Notation의 약어로, 데이터를 표현하는 데 사용되는 형식이다. 2000년대 초반 자바스크립트의 일부로 등장했고 점점 확장돼 텍스트 기반 데이터를 기술하고 교환하는 가장 보편적인 매체로 발전했다. 현재 JSON은 데이터 교환의 범용 표준이며 프론트 엔드와 서비스 측 개발, 시스템, 미들웨어, 데이터베이스를 포함해 프로그래밍의 모든 영역에 사용된다. 여기서는 JSON 기술의 개요를 알아보고 XML, YAML, CSV와 같은 비슷한 표준과 비교한다. 다양한 프로그램과 사용 사례에서 JSON이 어떻게 쓰이는지도 살펴본다.
 
ⓒ Getty Images Bank
 

JSON의 역사

처음에 JSON은 자바스크립트 클라이언트와 백엔드 서버 간의 통신을 위한 형식으로 개발됐다. 이후 프론트 엔드 프로그래머가 간결한 표준화된 형식을 사용해 백엔드와 통신하는 데 사용할 수 있는, 사람이 읽을 수 있는 형식으로 빠르게 인기를 끌었다. 개발자 관점에서 JSON의 또 다른 장점은 유연성이다. 높은 유연성 덕분에 즉석에서 필드를 추가, 제거, 업데이트할 수 있다(단, 이 유연성의 대가는 안전성이다. 이 부분에 관해서는 JSON 스키마를 다루면서 한 번 더 설명한다.)

흥미롭게도 JSON의 인기를 촉발한 것은 AJAX 혁명이다. XML에 중점을 뒀다는 사실을 감안하면 이상한 일이지만, AJAX가 제대로 빛을 발하게 해준 것은 사실 JSON이었다. API를 위한 규약으로 REST를 사용하고 교환 매체로 JSON을 사용하는 방법이 간소함과 유연함, 일관성의 적절한 조합이라는 것이 입증된 것이다.

이후 JSON은 프론트 엔드 자바스크립트에서 클라이언트-서버 통신으로 확산했고, 거기서 다시 시스템 구성 파일, 백엔드 언어에 이어 데이터베이스에까지 이르렀다. JSON은 데이터 저장 분야에서 혁신을 일으킨 노SQL 운동에 박차를 가한 역할도 했다. 데이터베이스 관리자 역시 JSON의 유연함과 손쉬운 프로그래밍을 반겼다.

현재 몽고DB와 같은 문서 지향 데이터 스토어는 JSON과 유사한 데이터 구조에서 작동하는 API를 제공한다. 몽고DB CTO 마크 포터는 최근 인터뷰에서 JSON이 여전히 새로운 데이터 영역을 개척하고 있다고 했다. 중괄호와 콜론으로 소소하게 시작한 데이터 형식으로서는 나쁘지 않은 성과다.
 

개발자가 JSON을 사용하는 이유

소프트웨어 개발자는 어떤 유형의 프로그램 또는 사용 사례를 다루든 데이터를 기술하고 교환할 방법이 필요하다. 이 필요성은 데이터베이스, 비즈니스 로직, 사용자 인터페이스, 그리고 모든 시스템 통신에 존재한다. 교환을 위해 데이터를 구조화하는 방법은 많은데 크게 바이너리와 텍스트 기반 데이터, 두 진영으로 나뉜다. JSON은 텍스트 기반 형식이므로 사람과 기계가 모두 읽을 수 있다.

JSON은 여러 이유로 매우 성공적인 데이터 형식 지정 방법이다. 첫째, 자바스크립트에 네이티브이며 자바스크립트 프로그램 내부에서 JSON 리터럴로 사용된다. 또한 다른 프로그래밍 언어와 함께 JSON을 사용할 수 있으므로 이종 시스템 간의 데이터 교환에 유용하다. 마지막으로 JSON은 사람이 읽을 수 있다. 언어 데이터 구조로서 JSON은 매우 다재다능한 툴이며 특히 다른 형식과 비교할 때 사용상에 불편한 점이 거의 없다.
 

JSON의 작동 원리

웹 페이지의 양식에 사용자 이름과 암호를 입력하면 사용자 이름과 암호, 두 개의 필드가 있는 하나의 객체와 상호작용하는 것이다. 예를 들어 <화면 1>의 로그인 페이지를 보자. <예시 1>은 JSON을 사용해 이 페이지를 기술한 것이다.
 
<화면 1> 간단한 로그인 페이지

<예시 1> 로그인 페이지의 JSON
{
   username: “Bilbo Baggins”,
   password: “fkj3442jv9dwwf”
}

중괄호({...}) 내에 포함된 것은 모두 같은 객체에 속한다. 여기서 객체는 일반적인 맥락에서 '하나의 사물'을 나타낸다. 중괄호 안에는 이 사물에 속하는 속성이 있다. 각 속성에는 이름과 값, 두 부분이 콜론으로 구분돼 포함된다. 이것을 키와 값이라고 한다. <예시 1>에서 “username”이 키, “Bilbo Baggins”가 값이다. 참고로 속성, 필드, 특성 등의 요소는 JSON 개체의 부분을 나타내는 데 사용된다. 기술적으로 보면 객체 지향 프로그래밍 언어 맥락에서 이와 같은 요소를 멤버(member)라고 한다. 각 속성과 필드 또는 특성은 객체의 멤버다.

<예시 1>에서 핵심은 JSON이 많은 부가 정보 없이 필요한 모든 작업(이 예의 경우 정보를 양식에 저장하는 것)을 수행한다는 것이다. 이 JSON 파일은 한눈에 이해할 수 있다. 그래서 JSON을 두고 간결하다고 말하는 것이다. 간결함은 네트워크 전송을 위한 형식으로도 적합한 특성이다.
 

JSON vs. XML

JSON은 한때 데이터 교환의 지배적 형식이었던 XML의 대안으로 만들어졌다. <예시 2>의 로그인 양식은 XML을 사용해 기술한 것이다.

<예시 2> XML로 된 로그인 양식
<UserLogin>
  <Username>Samwise Gamgee</Username>
  <Password>ghB5fK5</Password>
</UserLogin>

<예시 1>과 비교하면 보기만 해도 피곤하다. 이를 코드에서 만들어 파싱해야 한다고 상상해 보라. 반면 자바스크립트에서 JSON을 사용하면 극히 간단하다. 직접 해보면 안다. 브라우저에서 F12를 눌러 자바스크립트 콘솔을 연 다음 <예시 3>의 JSON을 붙여 넣어 보자.

<예시 3> 자바스크립트에서 JSON 사용하기
let hobbitJson = {
    name: "Pippin",
    hometown: "Shire"
}
console.log(hobbitJson.name);  // outputs “Pippin”
hobbitJson.bestFriend = "Merry";  // modify the object
console.log(JSON.stringify(hobbitJson)); //output entire object

// {"name":"Pippin","hometown":"Shire","bestFriend":"Merry"}

이처럼 XML은 읽기가 어렵고 코딩 민첩성 측면에서도 아쉬운 점이 많은데, JSON은 이러한 문제를 해결하도록 만들어졌다. JSON이 XML을 거의 대체했다는 것은 별로 놀라운 일은 아니다.
 

JSON vs. YAML vs. CSV

JSON과 종종 비교되는 두 데이터 형식은 YAML과 CSV다. 이 두 형식은 시간 스펙트럼의 양극단에 위치한다. CSV는 디지털 시대 이전의 옛 기술이지만 어떻게 하다 보니 컴퓨터에까지 도입됐으며 YAML은 JSON의 영향을 받아 탄생했고 개념적으로 JSON의 후손이라고 할 수 있다.

CSV는 단순한 값 목록이며 각 항목은 쉼표 또는 다른 구분 문자로 나타내고 첫 번째 헤더 필드 행은 선택적이다. 교환 매체 및 프로그래밍 구조로 제한되지만, 대량의 데이터를 디스크로 출력하는 데는 여전히 유용하다. 물론 CSV의 테이블 형식 데이터 구조는 스프레드시트와 완벽하게 어울린다.

YAML은 사실상 JSON의 확대 집합으로, JSON이 지원하는 것은 모두 지원한다. 그러나 YAML은 그 외에 JSON보다 더 간결하게 만들어진 더 간소화된 구문도 지원한다. 예를 들어 YAML은 계층구조에 중괄호를 버리고 들여쓰기를 사용한다. YAML은 데이터 교환 형식으로 종종 사용되기도 하지만 가장 유명한 사용 사례는 구성 파일이다.
 

복잡한 JSON : 중첩, 객체, 배열

지금까지는 얕은(간단한) 객체에 사용된 JSON 예제를 살펴봤다. 즉, 객체의 모든 필드가 프리미티브 값을 가진 예제였다. 그런데 JSON은 객체 그래프, 순환 그래프와 같이 임의의 복잡한 데이터 구조, 즉 순환 참조가 있는 구조도 모델링할 수 있다. 여기서는 중첩, 객체 참조, 배열을 통한 복잡한 모델링의 예제를 살펴보자.

중첩된 객체와 JSON
<예시 4>에서 중첩된 JSON 객체를 정의하는 방법을 볼 수 있다. 여기서 bestfriend 속성은 JSON 리터럴로 인라인 정의된 다른 객체를 가리킨다.

<예시 4> 중첩된 JSON
let merry = { name: "Merry",
  bestfriend: {
    name: "Pippin"
  }
}

객체 참조와 JSON
이제 <예시 5>를 보면 bestfriend     속성에 이름을 저장하는 대신 실제 객체에 대한 참조를 저장한다. <예시 5>에서는 bestfriend 속성에 merry 객체에 대한 핸들을 넣는다. 그러면 bestfriend 속성을 통해 pippin 객체에서 실제 merry 객체를 얻을 수 있다. name 속성으로 merry 객체에서 이름을 구한다. 이것을 객체 그래프 횡단이라고 하며, 점 연산자를 사용해 수행한다.

<예시 5> 객체 참조
let merry = { race: "hobbit", name: “Merry Brandybuck” }
let pippin = {race: "hobbit", name: “Pippin Took”, bestfriend: merry }
console.log(JSON.stringify(pippin.bestfriend.name)); // outputs “Merry Brandybuck”

배열과 JSON
JSON 속성이 가질 수 있는 또 다른 형식의 구조는 배열이다. 자바스크립트 배열과 비슷하며, <예시 6>에서 볼 수 있듯이 대괄호로 나타낸다. 물론 배열도 다른 객체에 대한 참조를 가질 수 있다. JSON은 이 두 가지 구조를 통해 복잡한 객체 관계를 다양하게 모델링할 수 있다. 참고로 지금까지 살펴본 문자열, 객체, 배열의 값 유형은 문자열, 숫자, 객체, 배열, 참, 거짓, 널 등이다.

<예시 6> 배열 속성
{
  towns: [ “The Shire”, “Rivendale”, “Gondor” ]
}
 

JSON 파싱 및 생성

JSON을 파싱하고 생성한다는 것은 각각 JSON 읽기와 만들기를 의미한다. JSON.stringify()의 예시는 이미 살펴본 것처럼 메모리 내 객체 표현을 취해 JSON 문자열로 변환하기 위한 자바스크립트 프로그램의 내장 메커니즘이다. 반대로, 즉 JSON 문자열을 받아 메모리 내 객체로 변환하려면 JSON.parse()를 사용한다.

다른 대부분의 언어에서는 파싱과 생성을 위해 서드파티 라이브러리를 사용해야 한다. 예를 들어 자바에는 수많은 라이브러리가 있지만 가장 많이 사용되는 라이브러리는 잭슨(Jackson)GSON이다. 이 두 라이브러리는 자바스크립트의 stringify 및 parse보다 더 복잡하지만 맞춤 형식과의 매핑, 다른 데이터 형식 처리와 같은 고급 기능을 제공한다. 자바스크립트에서는 JSON을 서버로 보내고 받는 것이 일반적이다. 예를 들어 내장된 fetch() API를 사용한다. 이 경우 <예시 7>과 같이 응답을 자동으로 파싱할 수 있다.

<예시 7> fetch()로 JSON 응답 파싱하기
fetch('https://the-one-api.dev/v2/character')
  .then((response) => response.json())
  .then((data) => console.log(data));

JSON을 자바스크립트든 다른 언어든 메모리 내 데이터 구조로 변환했다면 이 구조를 조작하기 위한 API를 사용할 수 있다. 예를 들어 자바스크립트에서 <예시 7>의 파싱된 JSON은 다른 자바스크립트 객체와 같은 방법으로 액세스된다(data.keys를 루프로 돌거나 데이터 객체의 알려진 속성에 액세스). 참고로 인증도 JSON이 사용되는 영역이다. 개발자 등은 JSON 웹 토큰(JWT)을 사용해 인증 클레임을 전달할 수 있다. JWT는 컴팩트한 표준 형식이 있으며 암호화 서명되어 변조를 방지한다. 기밀성을 위한 암호화도 가능하다.
 

JSON 스키마와 JSON 포맷터

자바스크립트와 JSON은 매우 유연하지만 가끔은 이 둘이 제공하는 것보다 더 많은 구조가 필요할 때가 있다. 이때는 자바와 같은 언어에서 강력한 형식 지정과 추상적 형식(인터페이스 등)이 대규모 프로그램 구조를 만드는 데 도움이 된다. SQL 스토어에서는 스키마가 이와 비슷한 구조를 제공한다. JSON 문서에서 더 많은 구조가 필요하다면 JSON 스키마를 사용해 JSON 객체의 특징을 명시적으로 정의하면 된다. 일단 정의하면 스키마를 사용해 객체 인스턴스를 검증하고 스키마에 부합하는지 확인할 수 있다.

또 다른 문제는 기계로 처리된, 축약되고 읽기 어려운 JSON을 다루는 일이다. 다행히 이 문제는 쉽게 해결할 수 있다. JSON 포맷터/밸리데이터(Formatter & Validator)로 가서(필자는 이 툴을 좋아하지만 다른 툴도 있음) JSON을 붙여 넣고 처리(Process) 버튼을 누르면 된다. 그러면 사람이 읽을 수 있는 버전이 된다. 대부분 IDE에도 JSON을 포맷하기 위한 자바스크립트 포맷터가 내장돼 있다.
 

타입스크립트와 JSON 사용하기

타입스크립트는 형식과 인터페이스를 정의하도록 허용하므로 타입스크립트와 JSON을 함께 사용하는 것이 유용할 때가 있다. 클래스는 스키마와 마찬가지로 주어진 형식의 인스턴스의 허용 가능한 속성을 기술한다. 일반 자바스크립트의 경우 속성과 그 유형을 제한할 방법이 없다. 자바스크립트 클래스는 일종의 제안이다. 즉, 프로그래머는 지금 설정해놓고 나중에 JSON을 수정할 수 있다. 그러나 타입스크립트 클래스는 JSON이 가질 수 있는 속성과 될 수 있는 형식을 강제한다.
 

현대 소프트웨어 개발의 필수 기술

JSON은 현대 소프트웨어 분야에 사용되는 가장 필수적인 기술 중 하나다. 자바스크립트에서 중대하지만 광범위한 기술 간의 공통 상호작용 모드로도 사용된다. JSON을 이처럼 유용하게 만든 이유는 명확하다. 텍스트 데이터 표현을 위한 간결하고 가독성 높은 형식이기 때문이다.
editor@itworld.co.kr
 Tags JSON
Sponsored

회사명 : 한국IDG | 제호: ITWorld | 주소 : 서울시 중구 세종대로 23, 4층 우)04512
| 등록번호 : 서울 아00743 등록발행일자 : 2009년 01월 19일

발행인 : 박형미 | 편집인 : 박재곤 | 청소년보호책임자 : 한정규
| 사업자 등록번호 : 214-87-22467 Tel : 02-558-6950

Copyright © 2024 International Data Group. All rights reserved.