공간정보/표준

JSON 위키

하늘이푸른오늘 2020. 12. 19. 13:56

JSON(JavaScript Object Notation)은 속성-값 쌍과 속성 데이터 유형(혹은 다른 직렬화 값)으로 구성되는 데이터 객체를 저장하고 전송하는, 인간이 읽을 수 있는 텍스트를 사용하는 개방형 표준 파일 포맷이자 데이터 교환 포맷이다. JSON은 매우 흔한 데이터 포맷으로 AJAX 에서 XML 을 대체하는데 사용되는 등, 다양한 종류의 응용에서 사용된다.

JSON은 언어 독립적 데이터 포맷이다. JSON은 JavaScript로부터 파생되었지만, 많은 현대 프로그래밍 언어는 JSON 포맷 데이터를 생성하고 파싱하는 코드를 포함한다. JSON의 공식 인터넷 매체 유형(media type)은 application/json 이다. JSON 파일명은 확장자가 .json 이다.

2000년대 초, 더글라스 크록포드가 JSON 포맷을 공식적으로 규정하였다. 2006년이래로 RFC 4627이 "정보" 사양으로사 사용가능해진 후, 2013년에 ECMA-404로 최초로 표준화되었다. 2017년 발행된 RFC 8259는 인터넷 표준 STD 90의 현재 버전이며, ECMA-404와 일관성을 유지하고 있다. 같은 해에 JSON은 ISO/IEC 21778:2017로서 표준화되었다. ECMA와 ISO 표준은 허용되는 문법만 기술하는 반면, RFC는 보안 및 상호운영성 고려사항도 다룬다.

명명

두문자 JSON는 2001년 3월 더글라스 크록포드가 공동설립한 회사인 State Software에서 유래되었다. 

2017년 국제표준(ECMA-404와 ISO/IEC 21778:2017)은 "Jason and Argonauts"와 같이 /ˈdʒeɪ·sən/ 으로 발음하기로 규정하였다. ECMA-404의 최초 버전(2013)에서는 발음을 지정하지 않았다. "UNIX and Linux System Administration Handbook"에서는 JSON 포맷의 이름을 짓고 홍보한 더글라스 크록포드가 Jason이라는 이름처럼 발음한다고 하였다. 하지만 어쩐일인지 기술 분야에서는 "JAY-sawn"이 훨씬 널리사용되는 것 같다. 2011년 크록포드는 "어떻게 발음하는지에 대해 많은 논의가 있지만, 솔직히 나는 아무 관심없다"고 하였다.

역사

JSON은 2000년대 초에 널리 사용되던 방법인 플래시나 Java 애플릿과 같은 브라우저 플러그인 없이, 상태가 없는(stateless) 실시간 서버-브라우저 통신 프로토콜을 위한 요구로 인하여 성장하였다.

JSON 라이브러리의 선구자가 Cartoon Network을 위한 Communities.com(State Software 공동설립자가 모두 여기에서 근무하였음)에서 Cartoon Orbit이라는 어린이 디지털 자원 교환 게임 프로젝트에서 사용되었다. Cartoon Orbit은 동적 HTML 요소를 처리하기 위한 독점적 메시징 포맷을 가진 브라우즈측 플러그인을 사용하였다(이 시스템도 3DO소유이었다). 초기 Ajax 기능의 발견후, digiGroups, Noosh,  기타 여러 곳에서 frame을 사용하여, 웹 응용의 시각적 문맥을 리프레시하지 않고 브라우저의 필드에 정보를 전달하였고, Netscape 4.0.5+ 및 IE 5+의 표준 HTTP, HTML 및 JavaScript 기능만을 이용해 실시간 리치 웹 응용을 실현하였다.

크록폴드는 JSON 포맷을 최초로 규정하고 보급하였다. State Software 공동 설립자는 표준 브라우저 기능을 사용하는 시스템을 만들기로합의하고, 두개의 HTTP 연결을 개방상태로 유지하고 추가 데이터 교환이 없으면 표준 브라우저 타임아웃 까지 재활용함으로써 함으로써, 웹서버에 영구적인 양방향 연결을 하는, 상태인지(stateful) 웹 응용을 생성하는 웹 개발자를 위한 추상레이어를 제공하였다. 공동설집자들은 원탁회의를 열고 데이터 포맷을 JSML 또는 JSON으로 부를지, 라이선스 유형을 어떻게 가져갈지에 대해 투표하였다. 칩 모닝스타는 State Software에서 상태있는 응용 프레임워크를 위한 아이디어를 개발하였다.

이 시스템은 선 마이크로시스템스, 아마존닷컴 및 EDS에 판매되었다. 2002년 JSON.org 웹사이트가 만들어졌다. 2005년 12월, 야후에서는 몇몇 웹서비스를 JSON으로 제공하기 시작하였다.

JSON은 JavaScript 스크립트 언어(특히 1999년 표준 ECMA-262 3rd 에디션)의 부분집합에 기반하였으며, JavaScript에서 널리 사용되었지만, 언어 독립적인 데이터 포맷이다. 많은 프로그래밍 언어에서 JSON 데이터를 파싱하고 생성하는 코드를 사용할 수 있다. JSON의 웹사이트에는 언어별 JSON 라이브러리 목록이 있다.

2013년 10월, Ecma International에서는 JSON 표준 1차 에디션 ECMA-404를 발행하였다. 같은 해, RFC 7148은 ECMA-404를 참조로 사용하였다. 2014년에 FRC 7159는 JSON의 인터넷 이용이 주요 참조가 되었으며 RFC 4627 및 RGC 7158을 초과하였다. (ECMA-262와 ECMA-404를 주요 참조로 보존하였음) 2017년 11월, ISO/IEC JTC 1/SC 22에서는 ISO/IEC 21778:2017을 국제표준으로 발행하였다. 2017년 12월 13일, 인터넷 공학 태스크포스(Internet Engineering Task Force)는 국제표준 STD 90의 현 버전인 RFC 8259를 발행하면서 RFC 7159를 퇴출하였다.

크록포드는  JSON 라이브를 오픈소스화 하기 위해 JSON 라이선스에 한 절을 추가하면서 "소프트웨어는 선을 위해 사용어야지, 악을 위해 사용되어서는 안된다"고 하여 회사 변호사들과 과도하게 현학적인 사람들을 비웃었다. 반면 이 절은 다른 오픈소스 라이브러리와 JSON 라이선스의 라이선스 호환성 문제를 야기하였다.

문법(Syntax)

다음 예는 인간을 기술하는 JSON 표현을 보인것이다.

{
   "firstName": "John",
   "lastName": "Smith",
   "isAlive": true,
   "age": 27,
   "address": {
      "streetAddress": "21 2nd Street",
      "city": "New York",
      "state": "NY",
      "postalCode": "10021-3100"
   },
   "phoneNumbers": [
      {
         "type": "home",
         "number": "212 555-1234"
      },
      {
         "type": "office",
         "number": "646 555-4567"
      }
   ],
   "children": [],
   "spouse": null
}

문자 인코딩(Character encoding)

크록포드는 원래 JSON은 JavaScript와 ECMAScript의 엄격한 하위집합이라고 주장하고 믿었으나, 그의 사양은 실제로는 유효하지 않은 JavaScript인 JSON 문서를 허용한다. 즉, JSON은 유니코드 라인 종결자 U+2028 LINE SEPARATER와 U+2029 PARAGRAPH SEPARATOR가 따옴표로 묶은 문자열내에 이스케이프 처리를 하지 않고 나타날 수 있다. (ECMAScript 2018 및 이전 버전에서는 불가능하다. 이는 JSON이 "제어문자"만을 불허한 결과이다. 최대 이식성을 위해서는 이들 문자를 백슬래시로 이스케이프 처리를 하는 것이 좋다. 이는 JSONP를 생성할 때 중요하다.

개방 생태계에서 JSON 교환은 UTF-8로 인코딩해야 한다. 이 인코딩은 기본 다국적언어 평면(U+10000 에서 U+10FFFF)를 벗어나는 문자를 포함한 유니코드 문자셋 전체를 지원한다. 그러나 이스케이프처리하면 이들 글자는 UTF-16 surrogate pair를 사용하여 써야 하며, 일부 JSON 파서는 이런 상세함을 놓친다. 예를 들어 JSON에서 이모지 문자 U+1F610 😐 NEUTRAL FACE를 포함하려면 다음과 같이 해야 한다.

{ "face": "😐" }
// 또는 
{ "face": "\uD83D\uDE10" }

JSON은 ESMAScript 2019 리비전 이후 부터 해당 언어의 엄격한 하위집합이 되었다.

데이터 유형

JSON의 기본 데이터 유형은 다음과 같다.

  • Number(수) : 분수 부분이나 지수표현 E를 포함할수 있는 부호있는 십진 수. 하지만, NaN과 같이 숫자가 아닌것은 포함하지 않는다. 정수와 소수를 구분하지 않는다. JavaScript는 모든 숫자값에 배밀도 부동소숫점 포맷을 사용한다. 나중에는 BigInt도 지원한다.) 하지만, JSON을 구현하는 다른 언어에서는 수를 다르게 인코딩할 수도 있다.
  • String(문자열) : 0개 이상의 유니코드 문자 시퀀스. 문자열은 겹따옴표로 분리되며, 백슬래시 이스케이프 문법을 지원한다.
  • Boolean(부울) : true 또는 false 값 중의 하나.
  • Array(배열) : 0개 이상 값의 순서있는 목록. 각각의 값은 어느 유형이든 관계없다. 배열은 대괄호 표현을 사용하며, 요소는 쉼표로 구분한다.
  • Object(객체) : 이름-값 쌍의 콜렉션으로서, 이때 이름(키)은 문자열이다. 객체는 사전(dictionary)를 표현하기 위한 의도로서, 각각의 키는 객체 내에서 유일하다. 객체는 중괄호로 구분되며, 각각의 쌍은 쉼표로 구분하고, 각각의 쌍내에서는 ':'을 사용하여 키와 값을 구분한다.
  • null(널) : 단어 null을 사용하는, 비어있는 값

구문 요소(값 및 구두점) 주변의 화이트스페이스는 허용되고 무시된다(단, 문자열 값 내의 화이트스페이스는 그대로 사용된다).  이러한 목적의 화이트 스페이스는 공백(space), 수평탭(horizontal tab), 라인피드(line feed), 캐리지리턴(carriage return) 등 4가지 특정 문자가 고려된다. 특히 byte order mask가 적합한 구현에 의하여 생성되지 않아야 한다(JSON을 파싱할 때는 허용될 수 있다). JSON은 코멘트를 위한 문법은 제공하지 않는다.

(RFC 4627과 같은) 초기버전의 JSON의 경우, 유효한 JSON 텍스트가 객체 또는 배열유형만을 포함해야 했다(객체나 배열 내에 다른 유형이 들어갈 수 있다). 이 제한은 JSON 텍스트를 직렬화 값으로 재정의한 RFC 7158에서 제거되었다.

JSON에서 Number는 프로그래밍 언어내에서의 표현에 대하여 불가지하다. 이때문에 숫자를 임의의 정밀도로 직렬화할 수 있지만, 이는 이식성 문제를 야기할 수 있다. 예를 들어, 정수와 부동소수 값간의 차이가 없으므로, 어떤 구현에서는 42, 42.0, 4.2E+1을 동일한 수로 취급하고, 다른 시스템에서는 달리 처리할 수 있다. JSON 표준에서는 오버플로, 언더플로, 정밀도 상실, 반올림, 부호있는 0 과 같은 구현 상세에 관해 아무런 요구사항이 없지만, "좋은 상호운영성"을 위하여 IEEE 754 binary54 이상은 기대하지 않는 것을 추천한다. (binary64와 같은) 부동소수의 기계수준의 이진 표현을 인간이 읽을 수 있는 (JSON의 Number와 같은) 10진 표현으로 직렬화하거나 그 반대방향에서 내재적인 정밀도 상실은 없다. 이를 정확하게, 최적으로 수행하는, 발행된 알고리듬이 존재하기 때문이다.

코멘트는 JSON에서 의도적으로 배제되었다. 2012년에 더글라스 크록보드는 설계 결정에서 "사람들이 코멘트를 사용하여 파싱 지침을 넣거나하여 상호운영성을 파괴하는 사례를 보아서 JSON에서 코멘트를 제거했다"고 하였다.

JSON은 "뒤에 있는 쉼표", 즉 데이터 구조 내에서 마지막 값 뒤에 있는 쉼표를 허용하지 않는다. 이는 JSON 탄생 시점부터 ECMA 표준과 일치하기 위해서이다. 이후의 ECMA 표준에서는 뒤에있는 쉼표를 허용하기도 했지만, JSON 사양은 호환성 이유로 이를 계속 불허하였다. 뒤에 있는 쉼표는 JSON 파생체에서는 사용 용이성을 향상시키기 위한 일반적인 기능이다.

의미론(Semantics)

JSON은 데이터 교환을 위한 구문적 프레임워크를 제공하지만, 모호하지 않은 데이터 교환을 위해서는 JSON 문법의 특정한 사용을 위한 의미론에 생산자와 소비자간 합의도 필요하다. 이러한 합의가 필요한 예중 하나가 JSON 표준이 아닌 JavaScript 문접에서 정의된 데이터 유형(Date, Function, Regular Expression, undefined 등)의 직렬화이다.

메타데이터와 스키마

JSON 텍스트의 공식 MIME type은 "application/json" 으로서, 대부분의 현대 구현은 이를 수용하고 있다. 많은 서비스 제공자, 브라우저, 서버, 웹 응용, 라이브러리, 프레임워크 및 API에서는 예전 시스템과의 호환성을 이유로 비공식적 MIME type "text/json" 또는 콘텐트 타입 "text/javascript"도 지원하고 있다. 중요한 사례로는 구글 검색 API, 야후, 플리커, 페이스북 API, Lift framework, Dojo Toolkit 0.4 등이 있다.

JSON 스키마는 유효성검증, 문서화, 상호작용 제어 등에 사용되는 JSON 데이터 구조를 정의하기 위한 JSON 기반의 포맷을 명시한다. JSON 스키마는 주어진 응용에서 요구하는 JSON 데이터를 위한 계약과 데이터를 어떻게 수정할 수 있는지를 제공한다. JSON 스키마는 XML 스키마(XSD) 개념에 기반하지만, JSON 기반이다. XSD에서와 마찬가지로, 스키마와 데이터 모두 동일한 직렬화/역직렬화 도구를 사용할 수 있다. 즉, 자기기술적(self-describing)이다. JSON 스키마는 Internet Draft(IETF에서 2019-09 초안)에서 규정되었고, 2019년 9월 19일 공개되었다. 여러 프로그램 언어를 위한 여러가지 유효성 검증기가 존재하며, 각각 부합성 수준이 다르다. 표준 파일명 확장자는 없지만, 일부는 .schema.json을 제안하였다.

JSON 표준은 객체 참조를 지원하지 않지만, JSON 기반 객체 참조를 위한 IETF 표준 초안은 존재한다. Dojo Toolkit은 표준 JSON을 사용하여 객체 참조를 지원한다. 특별히 dojox.json.ref 모듈을 사용하면 순환참조, 다중참조, inter message, lay referencing 등을 포함한 여러가지 형태의 참조를 사용할 수 있다. 내부적으로는 두가지 모두 이러한 참조에 "$ref" 키를 부여하고 파싱시 이를 해결한다. IETF 초안은 URL 문법만 명시하지만, Dojo에서는 더 많은 형태를 허용한다. 다른 방법으로는 모질라 JavaScript Sharp 변수를 사용하는 등의 비 표준 해결책도 존재한다. 하지만, 이러한 기능은 JavaScript 1.8.5 이후로 막혔고, Firefox 12 버전에서 제거되었다.

용도

JSON-RPC는 JSON을 기반으로 만들어진 원격 프로시저 호출 (RPC: remote procedure call)로서, XML-RPC 또는 SOAP 를 대체한다. JSON-RPC는 약간의 데이터 유형과 명령만을 정의하는 간단한 프로토콜이다. JSON-RPC는 시스템에서 전송 통지를 시키고(응답이 필요하지 않는 서버에 대한 정보), 응답할 수 있는 서버에 다중호출을 보낸다.

비동기 자바스크립트 및 JSON (AJAJ, Asynchronous JavaScript and JSON)은 Ajax와 동일한 동적 웹페이지 방법론이지만, XML 대신 JSON을 데이터포맷으로 사용한다. AJAJ 는 웹브라우저가 데이터를 불러들인 후, 새로운 데이터를 요청할 수 있는 능력을 제공하는 웹 개발 기술이다. 전형적으로 웹페이지에 대한 사용자 반응에 대응하여, 서버로부터 새로운 데이터를 표시한다. 예를 들어, 사용자가 검색상자 등에 문자를 치면 이를 서버에 보내어 즉시 해당되는 데이터베이스 항목의 드롭다운 목록을 표시한다.

JSON은 데이터 직렬화 포맷이지만, 임시로(ad-hoc) 설정언어로서 사용되어 왔다. 이러한 사용에서는 코멘트와 기타 유용하다고 생각되는 기능을 지원함으로써, 비표준 JSON 상위집합이 생성되었다. 이중에는 HJSON, HOCON, JSON5(JSON 버전 5가 아님) 등이 있다. YAML 버전 1.2의 주요 목적은 엄격한 JSON 상위집합 비표준 포맷을 만드는 것이었다.

2012년, 더글라스 크록포드는 설정 언어로서 사용될 때 JSON에서 코멘트를 사용하는 데에 대해 말한 적이 있다. "일부 사람들이 코멘트 기능이 없어서 슬퍼한다는 것을 알지만, 그럴 필요가 없다. 당신이 JSON을 사용하고 주석을 달고 싶은 설정 파일을 유지한다고 생각해보자. 그러면 원하는 대로 코멘트를 삽입하고 JSMin 파이프를 통과시킨 후 JSON 파서에 넘기면 된다."

JSON은 데이터 직렬화 포맷으로서 의도되었다. 그러나, JavaScript의 하위집합으로 설계되었다는 사실에서, JSON 텍스트를 JavaScript eval() 함수에 넘겨도 안전하다는 잘못된 생각이 만들어졌다. 어떤 유효환 JSON 텍스트, 특히 U+2028 LINE SEPARATOR 또는 U+2029 PARAGRAPH SEPARATOR 를 포함하는 JSON 텍스트의 경우, 2019년에 JavaScript 사양이 갱신되기전 까지는 유효한 JavaScript 코드가 아니었기 때문에 일부 예전 엔진은 지원하지 않기 때문이다. 인터넷 혹은 새로운 함수에서 유래된 임의의 코드를 수행하는 데 따른 많은 함정을 피하기 위하여, ECMAScript의 5 판에는 JSON.parse()가 처음 추가되었고, 2017년에는 모든 주요 브라우저에서 지원되었다. 지원하지 않는 브라우저의 경우, 더글러스 크록포드가 API-호환 자바스크립트 라이브러리를 제공하고 있다. 아울러 TC39 제안 "Subsume JSON"은 ECMAScript를 2019년 버전부터 엄격한 JSON 상위집합으로 만들었다.

다른 포맷과의 비교

JSON은 XML에 대한 오버헤드가 적은 대체품으로 홍보되었다. 이들 포맷은 실세계 상황에서 생성, 읽기, 디코딩을 지원하기위해 널리 사용되고 있다. XML을 제외하고라도 CSV, YAML(JSON의 상위집합)을 포함할 수 있다. 또한, 데이터 교환 언어는 아니지만, Google Protocol Buffers가 이러한 역할을 채워줄 수 있다.

YAML

YAML 버전 1.2는 JSON의 상위집합이다. 이전 버전은 엄격하게 호환되지 않았다. 예를 들어, JSON에서는 백슬래시(\)를 사용하여 슬래시(/)를 이스케이프처리가 가능하지만, YAML에서는 유효하지 않았다. 이러한 이스케이프 처리는 JSON을 HTML에 넣어 cross-site scripting 공격을 보호할 때 널리 사용되는 방법이다. 

YAML은 코멘트를 지원하지만, JSON은 지원하지 않는다.

XML

XML은 구조화된 데이터를 설명하고 객체를 직렬화하는데 사용되어 왔다. 동일한 종류의 데이터 교환을 목적으로, JSON과 동일한 데이터 구조를 표현하는 여러가지 XML 기반의 프로토콜이 지원된다. 데이터를 XML 로 인코딩하는 방법은 여러가지가 있다. 두개의 태그를 사용한 가장 값비싼 형태를 사용하면, JSON보다 훨씬 크게 만들어지지만, 데이터를 속성에 저장하고 짧은 태그와 닫는 태그를 />로 대체하면, 표현이 JSON과 거의 비슷해지거나 약간 커지는 정도가 된다. 그러나, XML 속성은 단일 값만 사용할 수 있고, 각 속성은 각각의 요소에 많아야 한번 나올 수 있다.

XML은 (요소와 속성을 사용하여) "데이터"를 "메타데이터"와 분리하지만, JSON에는 그러한 개념이 없다.

다른 중요 차이는 값에 대한 주소지정 방법이다. JSON은 단순한 "키"와 "값" 매핑만 있는 객체를 사용하지만, XML은 "노드"단에서 주소지정이 발생하여, 모든 노드가 XML 프로세서에서 고유 ID를 부여받는다. 추가적으로 XML 표준은 공통 속성 xml:id 를 정의하여, 사용자가 사용할 수 있고 ID를 명시적으로 지정할 수 있다.

XML 태그 명은 !"#$%&'()*+,/;<=>?@[\]^`{|}~ 및 화이트 스페이스를 포함할 수 없고, 마이너스(-), 마침표(.) 및 숫자로 시작할 수 있지만, JSON 키는 가능하다(단, 따옴표와 역슬래시는 반드시 이스케이프 처리해야 한다). 

XML 값은 문자(character)의 문자열이며, 내장 유형 에러방지가 없다. XML은 스키마의 개념이 있어서, 강력한 유형지정, 사용자 정의 유형, 선 정의한 태그, 형식적 구조, XML 스트림에 대한 정식 유효성 검증 등이 가능하다. JSON의 경우 강한 유형지정이 내장되어 있고, JSON 스키마에서 비슷한 스키마 개념이 있다.

XML은 코멘트를 지원하지만, JSON은 지원하지 않는다.

파생

JSON 사양을 기초로 여러가지 직렬화 포맷이 만들어졌다. GeoJSON, JSON-LD, Smile (데이터 교환 포맷), UBJSON, JSON-RPC, JsonML 등이 그러한 예이다.

함께 보기

  • 데이터 직렬화 포맷 비교
  • Jacson(API)
  • JSON 스트리밍
  • S-expression

==

원문 : JSON - Wikipedia