1. JSON 복습
JSON은 원래 JavaScript Object Notation의 약자야. 이름에 JavaScript가 들어가지만, 이 포맷은 특정 언어에 종속되지 않고 대부분의 프로그래밍 언어 — 특히 C# — 에 친화적이야. 데이터를(객체, 배열, 리스트, 맵 등) 사람이 읽을 수 있는 텍스트로 깔끔하게 표현하려고 만든 형식이지.
지금은 거의 모든 프로그램이 다른 프로그램과 통신하는 시대라 JSON은 사실상 de-facto 표준이 되었어. REST API부터 사용자 설정 저장, 마이크로서비스 간 내부 통신까지 두루 사용돼. 이유는 명확해 — 사람이 읽기 쉽고(중괄호를 무서워하지 않는다면), 파싱이 간단하고 모든 주요 언어와 라이브러리가 지원해.
왜 XML이 아니야?
JSON이 더 단순하고 짧고 읽기 쉬워. 불필요한 태그 소음이 없고 대부분의 데이터 구조에 더 자연스럽게 맞아떨어져. 닫는 태그나 괴상한 XML 규약들에 골머리 앓을 필요도 없지. 요약하면 — JSON은 더 빠르고, 더 간단하고, 더 편리해.
2. JSON 문법의 기본 요소
JSON을 트리(또는 마트료시카)로 생각하면 편해 — 객체, 배열, 원시값들이 레고 블록처럼 쌓여 있어. 기본 블록은 다음과 같아:
객체 (Objects)
JSON 객체는 중괄호 { }로 둘러싸인 "키: 값" 쌍들의 집합이야.
예시:
{
"name": "Alice",
"age": 23
}
C#에서는 이런 구조를 클래스나 Dictionary로 표현할 수 있어.
배열 (Arrays)
JSON 배열은 대괄호 [ ]로 감싼, 순서가 있는 값들의 리스트야. 값은 어떤 타입이어도 돼.
예시:
[1, 2, 3, 42]
또는 이렇게:
[
{"name": "Ivan"},
{"name": "Olga"}
]
C#에서는 보통 List<T>, T[] 같은 컬렉션으로 표현돼.
키-값 쌍
키는 항상 문자열(쌍따옴표 필수)이고, 값은 JSON에서 허용하는 아무 타입이나 될 수 있어.
예시:
{
"id": 123,
"login": "student",
"isActive": true
}
JSON의 데이터 타입
| JSON 타입 | 예 | 설명 |
|---|---|---|
| 숫자 (Number) | |
정수 또는 실수 |
| 문자열 (String) | |
항상 쌍따옴표로 감싸야 함 |
| 불리언 (Boolean) | |
논리값 |
| null | |
값이 없음 |
| 객체 (Object) | |
맵 또는 필드를 가진 엔티티 |
| 배열 (Array) | |
값들의 시퀀스 |
예시 — 전부 합쳐서:
{
"id": 1,
"name": "Bob",
"scores": [10, 20, 30],
"profile": {
"email": "bob@mail.com",
"phone": null
},
"isAdmin": false
}
한 유저 객체를 꽤 깔끔하고 논리적으로 표현할 수 있다는 걸 보이지?
3. JSON 작성 규칙
문자열은 항상 쌍따옴표
작정하고 홑따옴표를 쓰고 싶어도 JSON은 용서하지 않아. 올바른 예:
{ "name": "Vera" }
아래는 잘못된 예:
{ 'name': 'Vera' }
키는 항상 문자열
C#에서는 Dictionary 키가 int든 enum이든 가능하지만, JSON에서는 키가 항상 문자열이어야 해:
{ "2025": "C#의 해", "favorite": true }
꼬리 쉼표 금지
C#의 컬렉션 초기화와 달리, 닫는 괄호 바로 앞에 불필요한 쉼표를 넣으면 JSON 문법 오류야!
// 에러! (마지막 쉼표는 허용되지 않음)
{
"id": 10,
"name": "Oleg",
}
올바른 형태:
{
"id": 10,
"name": "Oleg"
}
공백과 줄바꿈
공백과 줄바꿈은 가독성을 위해 넣을 수 있고, 대부분의 파서는 이를 무시해. 사람용 형식은 보통 pretty-printed JSON을 쓰고, 네트워크 전송용은 minified 버전을 사용해.
4. C# 객체가 JSON으로 어떻게 변환되는지
System.Text.Json.JsonSerializer.Serialize()로 객체를 직렬화하면, 객체의 필드와 프로퍼티가 "키: 값" 쌍으로 바뀌어.
C# 클래스와 직렬화 예제
public class Book
{
public string Title { get; set; }
public int Pages { get; set; }
}
var book = new Book { Title = "CLR via C#", Pages = 900 };
string json = JsonSerializer.Serialize(book);
Console.WriteLine(json); // {"Title":"CLR via C#","Pages":900}
컬렉션
- List<int>는 [1,2,3]처럼 직렬화돼
- string[]는 ["hi", "wow"]처럼 직렬화돼
- List<Person>는 객체들의 배열로 직렬화돼
딕셔너리
예를 들어 Dictionary<string, int>는 JSON 객체로 변환돼:
var dict = new Dictionary<string, int>
{
["apples"] = 5, ["bananas"] = 10
};
string json = JsonSerializer.Serialize(dict);
// {"apples":5,"bananas":10}
5. 시각적 구조: JSON은 어떻게 구성되는가
중첩은 마트료시카처럼
객체
│
├── 키-값 쌍: "name": "Alex"
├── 키-값 쌍: "hobbies": 배열
│ │
│ ├── "skiing"
│ └── "programming"
└── 키-값 쌍: "profile": 객체
│
├── "age": 42
└── "city": "바젤"
결과는:
{
"name": "Alex",
"hobbies": ["skiing", "programming"],
"profile": {
"age": 42,
"city": "바젤"
}
}
6. 흔한 실수와 문법 주의점
프로그래밍에 완벽한 세상은 없으니 JSON에도 함정이 있어. 잘못된 따옴표, 불필요한 쉼표, 따옴표로 묶지 않은 키 같은 걸 보내면 파서가 에러를 뱉어.
또 하나 골칫덩어리는 선행 0이 붙은 숫자야. JSON에서는 허용되지 않아(예: 0123는 에러).
알아두면 좋음: 일부 파서(예: JavaScript의 JSON.parse)는 관대해서 작은 실수를 용서하기도 해. 하지만 대부분의 엄격한 파서(예: C#/.NET 쪽)는 문법 위반에 엄격하니 조심하자.
7. C# 데이터를 JSON으로 변환하는 실제 예
복잡한 구조를 직렬화해보자. 예제 앱에서 학생 목록을 파일로 저장한다고 해보자.
클래스 정의:
public class Student
{
public string Name { get; set; }
public int Age { get; set; }
}
리스트 채우기:
var students = new List<Student>
{
new Student { Name = "안나", Age = 20 },
new Student { Name = "니키타", Age = 22 }
};
직렬화:
using System.Text.Json;
// 학생 리스트를 JSON 문자열로 직렬화
string json = JsonSerializer.Serialize(students, new JsonSerializerOptions { WriteIndented = true });
Console.WriteLine(json);
/*
[
{
"Name": "안나",
"Age": 20
},
{
"Name": "니키타",
"Age": 22
}
]
*/
보이지? 각 학생이 JSON 배열 안의 개별 객체로 깔끔하게 들어가 있어.
8. 미니 제너레이터: 손으로 JSON 작성하기
테스트 데이터를 직접 만들 때 유용한 체크리스트:
- 객체라면 바깥은 중괄호, 배열이면 바깥은 대괄호.
- 키는 항상 쌍따옴표로 감싼 문자열.
- 값은 문자열(쌍따옴표), 숫자, true, false, null, 객체({}), 배열([]) 중 하나.
- 요소들 사이에는 쉼표만, 마지막 요소 뒤에는 쉼표 금지!
- 가독성을 위한 들여쓰기와 공백은 권장(필수 아님).
GO TO FULL VERSION