JSON 모범 사례: 포맷팅, 검증 및 파싱
· 12분 읽기
목차
JSON 기초
JSON(JavaScript Object Notation)은 웹에서 가장 널리 사용되는 데이터 교환 형식입니다. 사람이 읽을 수 있고, 언어 독립적이며, 거의 모든 프로그래밍 언어에서 지원됩니다. JSON 모범 사례를 이해하는 것은 신뢰할 수 있는 API, 구성 파일 및 데이터 파이프라인을 구축하는 데 필수적입니다.
JSON은 원래 JavaScript에서 파생되었지만 범용 표준이 되었습니다. 단순성과 유연성 덕분에 서버와 웹 애플리케이션 간 데이터 전송, 구성 설정 저장 및 API 응답 문서화에 이상적입니다.
핵심 데이터 타입
JSON은 정확히 6가지 데이터 타입을 지원합니다. 이러한 제한 사항을 이해하는 것은 적절한 JSON 설계에 매우 중요합니다:
{
"string": "Hello, World!",
"number": 42,
"decimal": 3.14,
"boolean": true,
"null_value": null,
"array": [1, 2, 3],
"object": {"nested": "value"}
}
| 데이터 타입 | 설명 | 예시 |
|---|---|---|
string |
큰따옴표로 묶인 텍스트 | "Hello" |
number |
정수 또는 부동소수점 | 42, 3.14 |
boolean |
참 또는 거짓 값 | true, false |
null |
값의 부재를 나타냄 | null |
array |
순서가 있는 값의 목록 | [1, 2, 3] |
object |
순서가 없는 키-값 쌍 | {"key": "value"} |
중요: JSON은 주석, 후행 쉼표, 작은따옴표, undefined, 함수 또는 네이티브 날짜 객체를 지원하지 않습니다. 날짜는 일반적으로 ISO 8601 형식의 문자열로 표현해야 합니다.
JSON을 사용해야 하는 경우
JSON은 특정 시나리오에서 탁월합니다:
- REST API: API 요청 및 응답 페이로드의 사실상 표준
- 구성 파일: 애플리케이션 설정, 환경 변수 및 기능 플래그
- 데이터 저장: MongoDB와 같은 NoSQL 데이터베이스는 JSON과 유사한 문서 구조를 사용
- 웹 애플리케이션: 클라이언트-서버 통신 및 상태 관리
- 로그 파일: 더 쉬운 파싱 및 분석을 위한 구조화된 로깅
복잡한 데이터 검증이 필요한 경우 배포 전에 데이터 구조가 유효한지 확인하기 위해 JSON 포맷터를 사용하는 것을 고려하세요.
포맷팅 표준
일관된 포맷팅은 JSON을 읽기 쉽고 유지 관리하기 쉽게 만들며 디버깅을 더 쉽게 합니다. 확립된 규칙을 따르면 오류가 줄어들고 팀 간 협업이 개선됩니다.
2칸 들여쓰기 사용
2칸 들여쓰기는 JSON의 업계 표준입니다. 과도한 공백 없이 명확한 시각적 계층 구조를 제공합니다.
// ✅ 좋음: 2칸 들여쓰기
{
"user": {
"name": "Jane",
"email": "[email protected]",
"preferences": {
"theme": "dark",
"notifications": true
}
}
}
// ❌ 나쁨: 들여쓰기 없음 (축소됨)
{"user":{"name":"Jane","email":"[email protected]"}}
축소된 JSON은 대역폭을 줄이기 위해 프로덕션 API에 적합하지만 개발 및 문서화를 위해서는 항상 포맷된 버전을 유지하세요.
키에 camelCase 사용
일관된 키 명명은 혼란을 방지하고 JSON을 더 예측 가능하게 만듭니다. camelCase는 JSON API에서 가장 일반적인 규칙입니다.
// ✅ 좋음: camelCase
{
"firstName": "Jane",
"lastName": "Smith",
"emailAddress": "[email protected]",
"createdAt": "2026-03-15T10:30:00Z",
"isActive": true
}
// ❌ 스타일 혼합 피하기
{
"first_name": "Jane", // snake_case
"LastName": "Smith", // PascalCase
"email-address": "...", // kebab-case
"CREATED_AT": "..." // SCREAMING_SNAKE_CASE
}
전문가 팁: Python 백엔드로 작업하는 경우 snake_case를 접할 수 있습니다. 하나의 규칙을 선택하고 전체 API에서 일관되게 사용하세요. 필요한 경우 변환 레이어를 사용하여 규칙 간 변환을 수행하세요.
날짜에 ISO 8601 사용
JSON에는 네이티브 날짜 타입이 없으므로 항상 ISO 8601 형식 문자열을 사용하세요. 이렇게 하면 다양한 프로그래밍 언어와 시간대에서 일관된 파싱이 보장됩니다.
{
"createdAt": "2026-03-15T10:30:00Z", // UTC 시간
"updatedAt": "2026-03-15T14:45:00+08:00", // 시간대 오프셋 포함
"date": "2026-03-15", // 날짜만
"time": "10:30:00" // 시간만
}
의미 있는 키 이름 사용
설명적인 키는 JSON을 자체 문서화하고 외부 문서의 필요성을 줄입니다.
// ✅ 좋음: 설명적인 키
{
"totalItemCount": 42,
"isActive": true,
"errorMessage": "Invalid email format",
"maxRetryAttempts": 3
}
// ❌ 나쁨: 암호 같은 약어
{
"cnt": 42,
"act": true,
"err": "Invalid email format",
"mra": 3
}
깊은 중첩 피하기
깊게 중첩된 구조는 읽고 파싱하기 어렵습니다. 최대 3-4 레벨의 중첩을 목표로 하세요.
// ✅ 좋음: 평평한 구조
{
"userId": "123",
"userName": "Jane",
"userEmail": "[email protected]",
"addressStreet": "123 Main St",
"addressCity": "Boston"
}
// ❌ 나쁨: 과도한 중첩
{
"user": {
"details": {
"personal": {
"name": {
"first": "Jane"
}
}
}
}
}
검증 기법
JSON 검증은 데이터 무결성을 보장하고 런타임 오류를 방지합니다. 각각 다른 사용 사례에 적합한 여러 검증 접근 방식이 있습니다.
JSON 스키마 검증
JSON 스키마는 JSON 문서에 주석을 달고 검증하기 위한 강력한 어휘입니다. JSON 데이터 구조에 대한 계약을 제공합니다.
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 100
},
"email": {
"type": "string",
"format": "email"
},
"age": {
"type": "integer",
"minimum": 0,
"maximum": 150
}
},
"required": ["name", "email"]
}
인기 있는 JSON 스키마 검증기는 다음과 같습니다:
- JavaScript: Ajv (가장 빠름), joi, yup
- Python: jsonschema, pydantic
- Java: everit-org/json-schema, networknt/json-schema-validator
- Go: gojsonschema, jsonschema
런타임 검증
특히 외부 소스나 사용자 입력에서 데이터를 받을 때는 항상 런타임에 JSON 데이터를 검증하세요.
// try-catch를 사용한 JavaScript 예제
function validateJSON(jsonString) {
try {
const data = JSON.parse(jsonString);
// 추가 검증
if (!data.email || !data.email.includes('@')) {
throw new Error('Invalid email format');
}
return { valid: true, data };
} catch (error) {
return { valid: false, error: error.message };
}
}
온라인 검증 도구
개발 중 빠른 검증을 위해 즉각적인 구문 검사 및 포맷팅을 제공하는 JSON 포맷터와 같은 온라인 도구를 사용하세요. JSON 구조를 비교하고 불일치를 식별하기 위해 Diff Checker를 사용할 수도 있습니다.
빠른 팁: 버전 관리에 커밋되기 전에 JSON 파일을 자동으로 검증하도록 pre-commit 훅을 설정하세요. 이렇게 하면 개발 프로세스 초기에 포맷팅 오류를 잡을 수 있습니다.
JavaScript에서 JSON 파싱
JavaScript는 JSON 작업을 위한 네이티브 메서드를 제공합니다. 이러한 메서드와 엣지 케이스를 이해하는 것은 견고한 애플리케이션에 필수적입니다.
JSON.parse() 메서드
JSON.parse() 메서드는 JSON 문자열을 JavaScript 객체로 변환합니다.
const jsonString = '{"name":"Jane","age":30}';
const obj = JSON.parse(jsonString);
console.log(obj.name); // "Jane"
console.log(obj.age); // 30
파싱 오류 처리
잘못된 형식의 JSON을 우아하게 처리하기 위해 항상 JSON.parse()를 try-catch 블록으로 감싸세요.
function safeJSONParse(jsonString, fallback = null) {
try {
return JSON.parse(jsonString);
} catch (error) {
console.error('JSON parse error:', error.message);
return fallback;
}
}
// 사용법
const data = safeJSONParse(userInput, { error: 'Invalid JSON' });
JSON.stringify() 메서드
JSON.stringify() 메서드는 JavaScript 객체를 JSON 문자열로 변환합니다.
const obj = {
name: "Jane",
age: 30,
hobbies: ["reading", "coding"]
};
// 기본 사용법
const jsonString = JSON.stringify(obj);
// 들여쓰기로 예쁘게 출력
const formatted = JSON.stringify(obj, null, 2);
// 사용자 정의 replacer 함수
const filtered = JSON.stringify(obj, ['name', 'age']); // 특정 키만 포함
Reviver 함수를 사용한 고급 파싱
reviver 함수를 사용하면 파싱 중에 값을 변환할 수 있으며, 날짜 문자열을 Date 객체로 변환하는 데 유용합니다.
const jsonString = '{"name":"Jane","createdAt":"2026-03-15T10:30:00Z"}';
const obj = JSON.parse(jsonString, (key, value) => {
if (key === 'createdAt') {
return new Date(value);
}
return value;
});
console.log(obj.createdAt instanceof Date); // true
특수 값 처리
JSON 직렬화 중 JavaScript가 특수 값을 처리하는 방법을 알아두세요:
const obj = {
func: function() {}, // 함수는 생략됨
undef: undefined, // undefined는 생략됨
symbol: Symbol('test'), // 심볼은 생략됨
date: new Date(), // 날짜는 문자열이 됨
nan: NaN, // NaN은 null이 됨
infinity: Infinity // Infinity는 null이 됨
};
console.log(JSON.stringify(obj));
// {"date":"2026-03-31T10:30:00.000Z","nan":null,"infinity":null}
전문가 팁: 개발 중에는 읽기 쉬운 출력을 위해 세 번째 매개변수를 2로 설정하여 JSON.stringify()를 사용하되, 프로덕션에서는 페이로드 크기를 최소화하기 위해 생략하세요.
Python에서 JSON 파싱
Python의 내장 json 모듈은 JSON 작업에 대한 포괄적인 지원을 제공합니다. 빠르고 신뢰할 수 있으며 외부 종속성 없이 대부분의 사용 사례를 처리합니다.
JSON 데이터 로드
Python은 JSON 로드를 위한 두 가지 주요 메서드를 제공합니다: 문자열용 json.loads()와 파일 객체용 json.load().
import json
# JSON 문자열 파싱
json_string = '{"name": "Jane", "age": 30}'
data = json.loads(json_string)
# 파일에서 JSON 로드
with open('data.json', 'r') as file:
data = json.load(file)
print(data['name']) # "Jane"
JSON 데이터 덤프
마찬가지로 Python은 문자열용 json.dumps()와 파일용 json.dump()를 제공합니다.
import json
data = {
"name": "Jane",
"age": 30,
"hobbies": ["reading", "coding"]
}
# JSON 문자열로 변환
json_string = json.dumps(data, indent=2)
# 파일에 쓰기
with open('output.json', 'w') as file:
json.dump(data, file, indent=2)
사용자 정의 객체 처리
Python 객체는 JSON으로 직접 직렬화할 수 없습니다. 복잡한 타입에는 사용자 정의 인코더를 사용하세요.
import json
from datetime import datetime
from decimal import Decimal
class