JSON
1. JSON 이란?
JSON(JavaScript Object Notation)은 데이터를 저장하고 전송하는 데 사용되는 가벼운 텍스트 기반의 데이터 교환 형식입니다. 자바스크립트 객체 표기법을 기반으로 하지만 언어에 독립적이어서 다양한 프로그래밍 언어에서 사용됩니다. 다른 방식에 비해 가볍고 읽기 쉬워 널리 사용되고 있으니 개발자라면 JSON을 잘 이해하고 사용할 수 있어야 합니다.
1.1. JSON 의 기본적인 형태
JSON은 이름과 값의 쌍으로 이루어진 데이터 객체를 표현합니다. 이름과 값은 콜론(:
)으로 구분하고, 데이터 객체는 쉼표(,
)로 구분합니다. 데이터 객체는 중괄호({}
)로 묶어서 표현하고, 배열은 대괄호([]
)로 묶어서 표현합니다.
{
"squadName": "슈퍼히어로",
"members": [
{
"name": "아이언맨",
"age": 29,
"본명": "토니 스타크"
},
{
"name": "헐크",
"age": 39,
"본명": "부르스 배너"
}
]
}
{
"squadName": "슈퍼히어로",
"members": [
{
"name": "아이언맨",
"age": 29,
"본명": "토니 스타크"
},
{
"name": "헐크",
"age": 39,
"본명": "부르스 배너"
}
]
}
2. JSON의 탄생 배경
프로그래머들은 서로 다른 프로그래밍 언어 간에 데이터를 전달할 때 어려움을 겪었습니다. 예를 들어 배열 데이터의 표현방식은 자바스크립트와 C는 다릅니다. 따라서 서로 다른 언어 간에 데이터를 전달하기 위해서는 데이터를 표현하는 방식을 통일해야 했습니다.
int arr[5] = {1, 2, 3, 4, 5};
int arr[5] = {1, 2, 3, 4, 5};
let arr = [1, 2, 3, 4, 5];
let arr = [1, 2, 3, 4, 5];
숫자와 문자열은 언어마다 표현방식이 같은 점을 이용해서 만든 대표적인 데이터 포멧이 XML입니다. 이후 XML의 복잡한 구조를 더 단순히 하고자 탄생한 것이 JSON 입니다. 주로 데이터 통신을 위해 사용되며, 데이터를 표현하는데 가장 간단하고 가볍습니다.
2.1. XML
앞에서 사용했던 JSON 데이터를 XML로 변환하면 다음과 같습니다. XML은 데이터를 계층적으로 표현하기 때문에 데이터를 표현하는데 용이합니다. 하지만 XML은 데이터를 표현하는데 많은 양의 태그를 사용하므로 가독성이 떨어집니다.
<?xml version="1.0" encoding="UTF-8" ?>
<root>
<squadName>슈퍼히어로</squadName>
<members>
<name>아이언맨</name>
<age>29</age>
<본명>토니 스타크</본명>
</members>
<members>
<name>헐크</name>
<age>39</age>
<본명>부르스 배너</본명>
</members>
</root>
<?xml version="1.0" encoding="UTF-8" ?>
<root>
<squadName>슈퍼히어로</squadName>
<members>
<name>아이언맨</name>
<age>29</age>
<본명>토니 스타크</본명>
</members>
<members>
<name>헐크</name>
<age>39</age>
<본명>부르스 배너</본명>
</members>
</root>
데이터를 표현하는 방식으로 JSON과 XML뿐만 아니라 다양한 방식이 있습니다. JSON은 데이터를 표현하는데 가장 간단하고 가볍기 때문에 많이 사용됩니다.
XML은 아직도 많이 사용되고 있습니다.
JSON이 등장하면서 XML보다 가볍고 읽기 쉬운 데이터 포멧으로 많이 사용되고 있습니다. 하지만 XML은 여전히 많은 곳에서 사용되고 있습니다.
아래 링크를 통해 제주도청 뉴스페이지와 RSS 링크를 확인해보세요. 2024년 6월 기준으로 제주도청 뉴스페이지는 XML로 표현되어 있습니다. 연도를 표기한 이유는 서비스가 변경되어 추후 XML을 제공하지 않을 수도 있기 때문입니다.
제주도청 뉴스페이지제주도청 RSS 링크3. JSON 메서드
JSON은 자바스크립트 객체와 JSON 문자열을 변환하는 메서드를 제공합니다. 실무에서 데이터를 다루기 위해 자주 사용되는 메서드들 입니다.
3.1. JSON.parse()
JSON 문자열을 자바스크립트 객체로 변환합니다. 유효하지 않은 JSON 문자열을 파싱하려고 하면 오류가 발생합니다. 객체, 배열, 원시값(문자열, 숫자, 불리언, null)을 반환할 수 있습니다.
다중으로 중첩된 문자열도 객체로 변환할 수 있습니다. 복잡항 형태의 JSON 데이터를 객체로 변환하여 사용할 수 있습니다.
이렇게 객체로 변환한 데이터를 순회하거나 특정 데이터를 처리하는 것이 JSON을 다루는 기본입니다. JSON을 다루는데 익숙해지면 데이터를 다루는 능력이 향상됩니다.
3.2. JSON.stringify()
자바스크립트 객체를 JSON 문자열로 변환합니다.
순환 참조가 있는 객체를 JSON 문자열로 변환하려고 하면 오류가 발생하므로 주의해야 합니다.
3.2. 깊은 복사
JSON.parse
와 JSON.stringify
를 이용하면 깊은 복사를 할 수 있습니다. origin 객체를 문자열화 했다가 다시 객체로 변환하기 때문에 새로운 객체를 생성하는 것과 동일합니다. 하지만 함수는 복사가 되지 않습니다.
4. JSON Generator
아래와 같은 서비스에서 JSON 형태를 받아 테이블 제작, 정렬 등 여러 실습을 해볼 수 있습니다. 이러한 가짜 데이터를 mock라고 합니다. 생성된 데이터의 형태를 보며 특정한 값에 통계를 내거나, 특정한 값에 대한 평균 등을 구해보세요. JSON 데이터를 다루는데 익숙해질 수 있습니다.
JSON Generator5. 실무에서 사용하는 여러 JSON 형태
5.1. JSON 서비스 사용 예제
실무에서 사용했던 여러 JSON 형태를 소개합니다. 실제 서비스로 들어가 네트워크 탭에서 데이터를 확인해볼 수 있습니다. 아래 JSON 형태를 보고 어떤 데이터를 담고 있는지 생각해보세요.
실무에서는 실제 데이터 정보를 가져오거나, 통신에 필요한 정보를 JSON 형태로 주고 받습니다.
스터디인 위니북스5.2. JSON 실습 문제
5.2.1 데이터 파싱
다음 JSON 데이터를 파싱하여, 현재 대출 가능한 책들의 제목을 배열로 반환하세요.
const 도서목록 =
'[{"id":1,"title":"The Great Gatsby","author":"F. Scott Fitzgerald","year":1925,"genre":"Novel","available":true},{"id":2,"title":"To Kill a Mockingbird","author":"Harper Lee","year":1960,"genre":"Novel","available":false},{"id":3,"title":"1984","author":"George Orwell","year":1949,"genre":"Dystopian","available":true},{"id":4,"title":"Pride and Prejudice","author":"Jane Austen","year":1813,"genre":"Romance","available":true},{"id":5,"title":"The Catcher in the Rye","author":"J.D. Salinger","year":1951,"genre":"Novel","available":false}]';
const 도서목록 =
'[{"id":1,"title":"The Great Gatsby","author":"F. Scott Fitzgerald","year":1925,"genre":"Novel","available":true},{"id":2,"title":"To Kill a Mockingbird","author":"Harper Lee","year":1960,"genre":"Novel","available":false},{"id":3,"title":"1984","author":"George Orwell","year":1949,"genre":"Dystopian","available":true},{"id":4,"title":"Pride and Prejudice","author":"Jane Austen","year":1813,"genre":"Romance","available":true},{"id":5,"title":"The Catcher in the Rye","author":"J.D. Salinger","year":1951,"genre":"Novel","available":false}]';
5.2.2 데이터 정렬
다음 코드에서 JSON 데이터를 정렬하는 방법을 작성해주세요. 항목을 눌렀을 때 오름차순, 내림차순으로 정렬되도록 구현합니다. 메서드를 이용하여 정렬된 데이터를 구합니다.
<button onclick="renderTable(JSON.parse(json))">데이터 호출!</button>
<table id="renderingDataTable">
<thead>
<tr>
<th onclick="sort('_id')">_id</th>
<th onclick="sort('age')">age</th>
<th onclick="sort('eyeColor')">eyeColor</th>
<th onclick="sort('name')">name</th>
<th onclick="sort('gender')">gender</th>
<th onclick="sort('email')">email</th>
<th onclick="sort('phone')">phone</th>
</tr>
</thead>
<tbody></tbody>
</table>
<button onclick="renderTable(JSON.parse(json))">데이터 호출!</button>
<table id="renderingDataTable">
<thead>
<tr>
<th onclick="sort('_id')">_id</th>
<th onclick="sort('age')">age</th>
<th onclick="sort('eyeColor')">eyeColor</th>
<th onclick="sort('name')">name</th>
<th onclick="sort('gender')">gender</th>
<th onclick="sort('email')">email</th>
<th onclick="sort('phone')">phone</th>
</tr>
</thead>
<tbody></tbody>
</table>
const json =
'[{"_id":"5e80777f673acf89c007ff91","age":27,"eyeColor":"green","name":"Angelina Chang","gender":"female","email":"angelinachang@kangle.com","phone":"+1 (938) 477-2821"},{"_id":"5e80777feee717674b817fd2","age":25,"eyeColor":"green","name":"Deidre Cobb","gender":"female","email":"deidrecobb@kangle.com","phone":"+1 (938) 477-2824"},{"_id":"5e80777fac368a4578dda85d","age":25,"eyeColor":"blue","name":"Jolene Franks","gender":"female","email":"jolenefranks@kangle.com","phone":"+1 (985) 536-3981"},{"_id":"5e80777ff3717874cbc78e44","age":31,"eyeColor":"brown","name":"Waters Hardin","gender":"male","email":"watershardin@kangle.com","phone":"+1 (938) 559-2224"},{"_id":"5e80777fe36842ea9e024fcd","age":34,"eyeColor":"green","name":"Jody Chaney","gender":"female","email":"jodychaney@kangle.com","phone":"+1 (878) 587-2602"},{"_id":"5e80777fafd591f57344eb33","age":31,"eyeColor":"green","name":"Ortiz Maldonado","gender":"male","email":"ortizmaldonado@kangle.com","phone":"+1 (986) 509-2753"},{"_id":"5e80777f20e48e9ada226862","age":25,"eyeColor":"brown","name":"Stacy Burris","gender":"female","email":"stacyburris@kangle.com","phone":"+1 (864) 577-3500"},{"_id":"5e80777faf334f84a2c90595","age":33,"eyeColor":"brown","name":"Davenport Levy","gender":"male","email":"davenportlevy@kangle.com","phone":"+1 (990) 600-2700"}]';
let click = true;
function sort(key) {
if (click) {
click = false;
let sortedData =
/* key 값의 오름차순으로 정렬합니다 */
renderTable(sortedData);
} else {
click = true;
let sortedData =
/* key 값의 내림차순으로 정렬합니다 */
renderTable(sortedData);
}
}
function renderTable(data) {
let tableBodyData = [];
for (var variable of data) {
tableBodyData.push(`
<tr>
<td>${variable._id}</td>
<td>${variable.age}</td>
<td>${variable.eyeColor}</td>
<td>${variable.name}</td>
<td>${variable.gender}</td>
<td>${variable.email}</td>
<td>${variable.phone}</td>
</tr>
`);
}
document.querySelector('#renderingDataTable > tbody').innerHTML =
tableBodyData.join('');
}
const json =
'[{"_id":"5e80777f673acf89c007ff91","age":27,"eyeColor":"green","name":"Angelina Chang","gender":"female","email":"angelinachang@kangle.com","phone":"+1 (938) 477-2821"},{"_id":"5e80777feee717674b817fd2","age":25,"eyeColor":"green","name":"Deidre Cobb","gender":"female","email":"deidrecobb@kangle.com","phone":"+1 (938) 477-2824"},{"_id":"5e80777fac368a4578dda85d","age":25,"eyeColor":"blue","name":"Jolene Franks","gender":"female","email":"jolenefranks@kangle.com","phone":"+1 (985) 536-3981"},{"_id":"5e80777ff3717874cbc78e44","age":31,"eyeColor":"brown","name":"Waters Hardin","gender":"male","email":"watershardin@kangle.com","phone":"+1 (938) 559-2224"},{"_id":"5e80777fe36842ea9e024fcd","age":34,"eyeColor":"green","name":"Jody Chaney","gender":"female","email":"jodychaney@kangle.com","phone":"+1 (878) 587-2602"},{"_id":"5e80777fafd591f57344eb33","age":31,"eyeColor":"green","name":"Ortiz Maldonado","gender":"male","email":"ortizmaldonado@kangle.com","phone":"+1 (986) 509-2753"},{"_id":"5e80777f20e48e9ada226862","age":25,"eyeColor":"brown","name":"Stacy Burris","gender":"female","email":"stacyburris@kangle.com","phone":"+1 (864) 577-3500"},{"_id":"5e80777faf334f84a2c90595","age":33,"eyeColor":"brown","name":"Davenport Levy","gender":"male","email":"davenportlevy@kangle.com","phone":"+1 (990) 600-2700"}]';
let click = true;
function sort(key) {
if (click) {
click = false;
let sortedData =
/* key 값의 오름차순으로 정렬합니다 */
renderTable(sortedData);
} else {
click = true;
let sortedData =
/* key 값의 내림차순으로 정렬합니다 */
renderTable(sortedData);
}
}
function renderTable(data) {
let tableBodyData = [];
for (var variable of data) {
tableBodyData.push(`
<tr>
<td>${variable._id}</td>
<td>${variable.age}</td>
<td>${variable.eyeColor}</td>
<td>${variable.name}</td>
<td>${variable.gender}</td>
<td>${variable.email}</td>
<td>${variable.phone}</td>
</tr>
`);
}
document.querySelector('#renderingDataTable > tbody').innerHTML =
tableBodyData.join('');
}