콘텐츠 대표 이미지 - JSON 데이터 교환과 API 통신을 위한경량 데이터 포맷 실전 가이드
📡 프로그램개발 · 기타프로그램개발

JSON 데이터 교환과 API 통신을 위한
경량 데이터 포맷 실전 가이드

개발자라면 반드시 알아야 할 JSON의 모든 것 🚀

야 솔직히 말해봐ㅋㅋ 개발 처음 시작했을 때 JSON 보고 "이게 뭐야 괄호 잔치야?" 했던 사람 손 들어봐 🙋

근데 지금은? API 통신할 때 JSON 없으면 진짜 아무것도 못 하잖아ㅋㅋㅋ 그만큼 JSON은 현대 웹 개발의 핵심 중의 핵심이야. 프론트엔드, 백엔드, 모바일 앱, IoT까지 안 쓰이는 데가 없음.

이 글에서는 JSON이 뭔지부터 시작해서 API 통신에서 어떻게 쓰이는지, 실무에서 자주 쓰는 패턴까지 팩트 기반으로 빡세게 다뤄볼 거야. 채팅하듯 편하게 읽어봐! 😎


📦 1. JSON이 뭔데? 기초부터 제대로 알자

JSON은 JavaScript Object Notation의 약자야. 직역하면 "자바스크립트 객체 표기법"인데, 이름에 JavaScript가 들어가 있다고 해서 JS 전용이냐? 절대 아님!

JSON은 언어 독립적인 데이터 포맷이야. Python, Java, C#, Go, Ruby, PHP... 어떤 언어에서도 파싱하고 생성할 수 있어. 그냥 텍스트 기반의 데이터 표현 방식이거든.

📌 JSON 공식 정의 JSON은 RFC 8259와 ECMA-404로 표준화된 경량 데이터 교환 포맷이야.
더글라스 크록포드(Douglas Crockford)가 2001년에 처음 제안했고, 2013년에 ECMA 표준으로 공식 채택됐어.
사람이 읽기 쉽고(human-readable), 기계가 파싱하기도 쉬운(machine-parseable) 게 핵심 장점이야.

🤔 왜 JSON이 이렇게 대세가 됐냐고?

예전에는 XML이 데이터 교환의 왕이었어. 근데 XML은 태그가 너무 많아서 데이터 크기가 커지고, 파싱도 복잡했거든. JSON은 그 문제를 싹 해결했지.

XML vs JSON 비교 ❌ XML 방식 (구식) <user> <name>홍길동</name> <age>25</age> <skills> <skill>Python</skill> <skill>JavaScript</skill> </skills> </user> 😩 태그 중복 → 용량 낭비 😩 파싱 복잡 → 속도 저하 😩 가독성 낮음 ✅ JSON 방식 (현대적) { "name" : "홍길동", "age" : 25, "skills" : [ "Python", "JavaScript" ] } 😊 간결한 구조 → 용량 절약 😊 파싱 간단 → 빠른 처리 😊 가독성 높음 VS

보이지? 같은 데이터인데 JSON이 훨씬 간결하잖아ㅋㅋ 이게 바로 JSON이 XML을 밀어낸 이유야.


📝 2. JSON 문법 - 이것만 알면 끝

JSON 문법은 진짜 단순해. 6가지 데이터 타입만 지원하거든. 근데 이 6가지 조합으로 세상 모든 데이터를 표현할 수 있음ㅋㅋ

🔢 JSON이 지원하는 데이터 타입

타입 예시 설명
문자열 (String) "안녕하세요" 반드시 큰따옴표(" ") 사용
숫자 (Number) 42, 3.14, -7 정수, 실수, 음수 모두 가능
불리언 (Boolean) true, false 소문자로만 작성
null null 값이 없음을 표현
배열 (Array) [1, 2, 3] 대괄호로 감싸는 순서 있는 목록
객체 (Object) {"key": "value"} 중괄호로 감싸는 키-값 쌍
💡 꿀팁! JSON에서 undefined는 지원 안 해! JavaScript에서 undefined를 JSON으로 변환하면 그냥 사라지거나 null로 처리돼. 이거 모르면 나중에 버그 잡다가 머리 뜯게 됨ㅋㅋ

📋 JSON 문법 규칙 - 이거 틀리면 파싱 에러남

✅ 올바른 JSON 작성 규칙 1️⃣ 키(key)는 반드시 큰따옴표로 감싸야 해 (작은따옴표 ❌)
2️⃣ 마지막 항목에 쉼표(trailing comma) 금지
3️⃣ 주석(comment) 사용 불가 (// 이런 거 ❌)
4️⃣ 문자열 내 특수문자는 이스케이프 처리 필요 (\n, \t, \" 등)
5️⃣ 숫자는 8진수, 16진수 표현 불가 (0x1F 이런 거 ❌)
// ❌ 잘못된 JSON (이렇게 쓰면 파싱 에러!)
{
  'name': '홍길동',     // 작은따옴표 사용 금지
  "age": 25,           // 마지막 쉼표 금지
  // 주석도 금지       // 주석 사용 금지
}

// ✅ 올바른 JSON
{
  "name": "홍길동",
  "age": 25,
  "isActive": true,
  "score": null,
  "skills": ["Python", "JavaScript"],
  "address": {
    "city": "서울",
    "district": "강남구"
  }
}

🔤 이스케이프 문자 - 이것도 알아야 해

이스케이프 시퀀스 의미
\" 큰따옴표
\\ 백슬래시
\/ 슬래시
\n 줄바꿈
\r 캐리지 리턴
\t 탭
\uXXXX 유니코드 문자 (예: \uD55C = 한)

🌐 3. API 통신에서 JSON이 어떻게 쓰이냐고?

자 이제 진짜 핵심으로 들어가보자. JSON이 API 통신에서 어떻게 활용되는지 실제로 뜯어볼 거야.

🔄 REST API와 JSON의 관계

REST API는 HTTP 프로토콜을 기반으로 클라이언트와 서버가 데이터를 주고받는 방식이야. 그리고 그 데이터를 담는 그릇이 바로 JSON이지.

REST API 통신 흐름 클라이언트 (브라우저/앱) 💻 React / Vue 요청 JSON {"query": "검색어"} 응답 JSON 수신 {"data": [...]} HTTP POST /api/search Content-Type: application/json HTTP 200 OK + JSON 응답 API 서버 (백엔드) 🖥️ Node / Django JSON 파싱 처리 req.body → DB 조회 JSON 직렬화 응답 res.json(data) 데이터베이스 🗄️ MySQL / MongoDB HTTP 메서드: GET(조회) · POST(생성) · PUT(수정) · PATCH(부분수정) · DELETE(삭제)

📨 HTTP 헤더에서 JSON 설정하기

API 통신할 때 JSON을 주고받으려면 HTTP 헤더에 Content-Type을 제대로 설정해야 해. 이거 빠뜨리면 서버가 데이터를 못 읽는 경우가 생김ㅋㅋ

// 요청 헤더 설정
Content-Type: application/json    // 내가 보내는 데이터가 JSON이야
Accept: application/json          // 나는 JSON으로 응답받고 싶어

// JavaScript fetch API 예시
fetch('https://api.example.com/users', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Accept': 'application/json',
    'Authorization': 'Bearer your-token-here'
  },
  body: JSON.stringify({
    name: '홍길동',
    email: 'hong@example.com',
    age: 25
  })
})
.then(response => response.json())  // 응답을 JSON으로 파싱
.then(data => console.log(data))
.catch(error => console.error('에러:', error));

🔁 JSON 직렬화(Serialization)와 역직렬화(Deserialization)

이 개념 모르면 API 개발할 때 진짜 헷갈려. 간단하게 설명할게.

📤 직렬화 (Serialization)

프로그램의 객체/데이터를 JSON 문자열로 변환하는 것

JSON.stringify(obj) → JavaScript
json.dumps(obj) → Python
ObjectMapper.writeValueAsString() → Java
📥 역직렬화 (Deserialization)

JSON 문자열을 프로그램의 객체/데이터로 변환하는 것

JSON.parse(str) → JavaScript
json.loads(str) → Python
ObjectMapper.readValue() → Java
// JavaScript에서 직렬화/역직렬화

// 객체 → JSON 문자열 (직렬화)
const user = { name: "홍길동", age: 25, skills: ["Python", "JS"] };
const jsonString = JSON.stringify(user);
// 결과: '{"name":"홍길동","age":25,"skills":["Python","JS"]}'

// 예쁘게 출력하고 싶을 때 (들여쓰기 2칸)
const prettyJson = JSON.stringify(user, null, 2);

// JSON 문자열 → 객체 (역직렬화)
const parsed = JSON.parse(jsonString);
console.log(parsed.name); // "홍길동"

// Python에서
import json

# 직렬화
data = {"name": "홍길동", "age": 25}
json_str = json.dumps(data, ensure_ascii=False)  # 한글 깨짐 방지

# 역직렬화
parsed = json.loads(json_str)
print(parsed["name"])  # 홍길동

📐 4. JSON Schema - 데이터 유효성 검사의 핵심

API 개발하다 보면 "이 JSON 데이터가 올바른 형식인지 어떻게 검증하지?" 라는 고민이 생겨. 그때 쓰는 게 바로 JSON Schema야!

JSON Schema는 JSON 데이터의 구조와 유효성을 정의하는 메타 스키마야. 쉽게 말하면 "이 JSON은 이런 형식이어야 해"를 명세하는 문서라고 보면 돼.

🔍 JSON Schema 기본 구조 JSON Schema 자체도 JSON 형식으로 작성돼. 현재 최신 버전은 Draft 2020-12야.
// 사용자 데이터 JSON Schema 예시
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://example.com/user.schema.json",
  "title": "User",
  "description": "사용자 정보 스키마",
  "type": "object",
  "required": ["name", "email", "age"],
  "properties": {
    "name": {
      "type": "string",
      "minLength": 2,
      "maxLength": 50,
      "description": "사용자 이름"
    },
    "email": {
      "type": "string",
      "format": "email",
      "description": "이메일 주소"
    },
    "age": {
      "type": "integer",
      "minimum": 0,
      "maximum": 150,
      "description": "나이"
    },
    "skills": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "uniqueItems": true,
      "description": "보유 기술 목록"
    },
    "isActive": {
      "type": "boolean",
      "default": true
    }
  },
  "additionalProperties": false
}

🛡️ JSON Schema 주요 키워드

키워드 설명 예시
type 데이터 타입 지정 "type": "string"
required 필수 필드 목록 "required": ["name", "email"]
minimum/maximum 숫자 범위 제한 "minimum": 0, "maximum": 100
minLength/maxLength 문자열 길이 제한 "minLength": 2
pattern 정규식 패턴 검증 "pattern": "^[0-9]{10,11}$"
enum 허용 값 목록 "enum": ["admin", "user", "guest"]
format 특정 형식 검증 "format": "date-time"
$ref 다른 스키마 참조 "$ref": "#/$defs/Address"
💡 실무 꿀팁! JSON Schema는 API 문서화 도구인 OpenAPI(Swagger)에서도 핵심으로 사용돼. API 스펙 문서 작성할 때 JSON Schema 알면 진짜 편함ㅋㅋ

⚡ 5. 실무에서 자주 쓰는 JSON API 응답 패턴

실제 프로젝트에서 API 응답 JSON을 어떻게 설계하느냐에 따라 프론트엔드 개발 편의성이 완전 달라져. 업계에서 많이 쓰는 패턴들 알려줄게.

📦 패턴 1: 표준 응답 래퍼 (Standard Response Wrapper)

가장 많이 쓰는 패턴이야. 성공/실패 여부, 메시지, 실제 데이터를 일관된 구조로 감싸는 방식.

// ✅ 성공 응답
{
  "success": true,
  "status": 200,
  "message": "사용자 정보를 성공적으로 조회했습니다.",
  "data": {
    "id": 1,
    "name": "홍길동",
    "email": "hong@example.com"
  },
  "timestamp": "2024-01-15T10:30:00Z"
}

// ❌ 실패 응답
{
  "success": false,
  "status": 404,
  "message": "사용자를 찾을 수 없습니다.",
  "error": {
    "code": "USER_NOT_FOUND",
    "details": "ID 999에 해당하는 사용자가 존재하지 않습니다."
  },
  "timestamp": "2024-01-15T10:30:00Z"
}

📋 패턴 2: 페이지네이션 응답 (Pagination Response)

목록 데이터를 가져올 때 한 번에 다 가져오면 서버 터짐ㅋㅋ 그래서 페이지 단위로 나눠서 가져오는 패턴이야.

// 페이지네이션 응답 구조
{
  "success": true,
  "data": {
    "items": [
      { "id": 1, "name": "홍길동" },
      { "id": 2, "name": "김철수" }
    ],
    "pagination": {
      "currentPage": 1,
      "totalPages": 10,
      "totalItems": 98,
      "itemsPerPage": 10,
      "hasNextPage": true,
      "hasPrevPage": false
    }
  }
}

// 커서 기반 페이지네이션 (SNS에서 많이 씀)
{
  "data": [...],
  "cursor": {
    "next": "eyJpZCI6MTAwfQ==",  // Base64 인코딩된 커서
    "hasMore": true
  }
}

🚨 패턴 3: 에러 응답 표준화 (RFC 7807 Problem Details)

에러 응답도 표준이 있어! RFC 7807에서 정의한 "Problem Details for HTTP APIs" 형식이야. 대형 서비스들이 많이 채택하고 있음.

// RFC 7807 Problem Details 형식
{
  "type": "https://example.com/errors/validation-error",
  "title": "유효성 검사 실패",
  "status": 422,
  "detail": "요청 데이터가 올바르지 않습니다.",
  "instance": "/api/users/create",
  "errors": [
    {
      "field": "email",
      "message": "올바른 이메일 형식이 아닙니다.",
      "rejectedValue": "not-an-email"
    },
    {
      "field": "age",
      "message": "나이는 0 이상이어야 합니다.",
      "rejectedValue": -5
    }
  ]
}

🔗 패턴 4: HATEOAS (Hypermedia as the Engine of Application State)

REST API의 성숙도 레벨 3에 해당하는 패턴이야. 응답에 관련 링크를 포함시켜서 클라이언트가 다음에 뭘 할 수 있는지 알려주는 방식.

// HATEOAS 응답 예시
{
  "id": 1,
  "name": "홍길동",
  "email": "hong@example.com",
  "_links": {
    "self": { "href": "/api/users/1" },
    "update": { "href": "/api/users/1", "method": "PUT" },
    "delete": { "href": "/api/users/1", "method": "DELETE" },
    "orders": { "href": "/api/users/1/orders" },
    "profile": { "href": "/api/users/1/profile" }
  }
}

🚀 6. JSON 성능 최적화 - 이거 모르면 느린 API 만듦

JSON 쓰는 건 알겠는데 성능까지 신경 쓰는 개발자가 진짜 고수야ㅋㅋ 실무에서 쓸 수 있는 최적화 기법들 알려줄게.

JSON 성능 최적화 전략 🎯 필드 선택적 반환 필요한 필드만 응답에 포함 ?fields=id,name → 데이터 크기 ↓ → 전송 속도 ↑ 🗜️ Gzip 압축 HTTP 응답에 Gzip 압축 적용 Accept-Encoding: gzip, deflate → 크기 70~80% ↓ ⚡ 응답 캐싱 ETag / Last-Modified Cache-Control 헤더 Redis 캐시 활용 → DB 부하 ↓ → 응답 속도 ↑ 🌊 JSON 스트리밍 대용량 데이터를 청크 단위로 전송 NDJSON 형식 활용 → 메모리 효율 ↑ → TTFB 개선 최적화 전/후 응답 크기 비교 (예시) 최적화 전 500KB 필드 선택 후 200KB (-60%) Gzip 압축 후 75KB (-85%)

🔧 실무 최적화 기법 상세

1️⃣ 불필요한 데이터 제거 API 응답에서 클라이언트가 실제로 사용하지 않는 필드는 빼는 게 좋아.
GraphQL이 이 문제를 해결하기 위해 나온 기술이기도 해.
REST API에서는 ?fields=id,name,email 같은 쿼리 파라미터로 구현할 수 있어.
2️⃣ JSON 파싱 최적화 대용량 JSON을 한 번에 파싱하면 메모리 폭발함ㅋㅋ
Node.js에서는 stream-json 라이브러리로 스트리밍 파싱 가능.
Python에서는 ijson 라이브러리 사용하면 메모리 효율적으로 처리 가능.
3️⃣ JSON 대안 포맷 고려 성능이 극도로 중요한 경우 JSON 대신 다른 포맷을 고려해볼 수 있어:

• MessagePack: JSON과 호환되는 바이너리 포맷, 크기 20~30% 절약
• Protocol Buffers (Protobuf): Google이 만든 바이너리 직렬화, 매우 빠름
• CBOR: Concise Binary Object Representation, IoT에서 많이 씀
• BSON: MongoDB가 사용하는 바이너리 JSON
// NDJSON (Newline Delimited JSON) - 스트리밍에 최적화
// 각 줄이 독립적인 JSON 객체 (대용량 데이터 처리에 유리)
{"id":1,"name":"홍길동","score":95}
{"id":2,"name":"김철수","score":87}
{"id":3,"name":"이영희","score":92}

// Node.js에서 NDJSON 스트리밍 처리
const { createReadStream } = require('fs');
const readline = require('readline');

const rl = readline.createInterface({
  input: createReadStream('large-data.ndjson')
});

rl.on('line', (line) => {
  const obj = JSON.parse(line);
  // 한 줄씩 처리 → 메모리 효율적!
  processData(obj);
});

🔒 7. JSON 보안 - 이거 모르면 해킹당함

JSON 쓸 때 보안도 진짜 중요해. 모르고 쓰다가 보안 취약점 생기면 진짜 큰일남ㅋㅋ 주요 보안 이슈들 알아보자.

⚠️ JSON Injection 공격 사용자 입력을 그대로 JSON에 넣으면 JSON 구조를 깨뜨리는 공격이 가능해.

위험한 코드:
const json = '{"name":"' + userInput + '"}';

만약 userInput이 ","admin":true,"x":" 라면?
→ {"name":"","admin":true,"x":""} 이 되어버림! 😱

해결책: 반드시 JSON.stringify() 사용해서 직렬화할 것!
⚠️ JSON Hijacking (구형 브라우저) 구형 브라우저에서 JSON 배열을 직접 반환하면 크로스 사이트에서 탈취 가능했어.
현재는 대부분 해결됐지만, 여전히 JSON 응답은 객체로 감싸는 게 좋은 관행이야.

// ❌ 위험 (구형 환경)
[{"id":1,"secret":"xxx"}]

// ✅ 안전
{"data": [{"id":1,"secret":"xxx"}]}
⚠️ 민감 정보 노출 API 응답에 불필요한 민감 정보가 포함되지 않도록 주의해야 해.

• 비밀번호 해시값 절대 응답에 포함 금지
• 내부 시스템 정보 (서버 경로, DB 구조 등) 노출 금지
• 개인정보는 마스킹 처리 (예: 전화번호 010-****-5678)
// ✅ 안전한 JSON API 처리 패턴

// 1. 입력 검증 (JSON Schema 활용)
const Ajv = require('ajv');
const ajv = new Ajv();

const schema = {
  type: 'object',
  required: ['name', 'email'],
  properties: {
    name: { type: 'string', maxLength: 100 },
    email: { type: 'string', format: 'email' }
  },
  additionalProperties: false  // 정의되지 않은 필드 거부
};

const validate = ajv.compile(schema);
const valid = validate(requestBody);
if (!valid) {
  throw new Error('유효하지 않은 입력 데이터');
}

// 2. 응답 시 민감 정보 제거
function sanitizeUser(user) {
  const { password, internalId, ...safeUser } = user;
  return safeUser;  // 비밀번호, 내부ID 제외하고 반환
}

// 3. JSON 파싱 에러 처리
try {
  const data = JSON.parse(requestBody);
} catch (e) {
  return res.status(400).json({
    error: '잘못된 JSON 형식입니다.'
  });
}
🚨 주의! JSON.parse()는 __proto__ 오염(Prototype Pollution) 공격에 취약할 수 있어. 신뢰할 수 없는 소스의 JSON을 파싱할 때는 JSON.parse() 전에 반드시 입력 검증을 해야 해!

💻 8. 언어별 JSON 처리 - 실전 코드 모음

각 언어마다 JSON 처리하는 방법이 조금씩 달라. 자주 쓰는 언어들 기준으로 핵심만 정리해줄게!

🟨 JavaScript / Node.js

// 기본 파싱/직렬화
const obj = JSON.parse('{"name":"홍길동"}');
const str = JSON.stringify(obj, null, 2);

// fetch API로 JSON 받기
const response = await fetch('/api/users');
const data = await response.json();

// axios로 JSON 통신
const { data } = await axios.post('/api/users', {
  name: '홍길동',
  email: 'hong@example.com'
});

// JSON 깊은 복사 (간단한 방법)
const deepCopy = JSON.parse(JSON.stringify(original));
// ⚠️ 단, undefined, 함수, Symbol은 복사 안 됨!

🐍 Python

import json
import requests

# 기본 파싱/직렬화
data = json.loads('{"name": "홍길동", "age": 25}')
json_str = json.dumps(data, ensure_ascii=False, indent=2)

# 파일에서 JSON 읽기/쓰기
with open('data.json', 'r', encoding='utf-8') as f:
    data = json.load(f)

with open('output.json', 'w', encoding='utf-8') as f:
    json.dump(data, f, ensure_ascii=False, indent=2)

# requests로 API 통신
response = requests.post(
    'https://api.example.com/users',
    json={'name': '홍길동', 'email': 'hong@example.com'},  # json= 파라미터 사용
    headers={'Authorization': 'Bearer token'}
)
result = response.json()  # 자동으로 JSON 파싱

# dataclass와 JSON 연동
from dataclasses import dataclass, asdict
import json

@dataclass
class User:
    name: str
    age: int
    email: str

user = User(name="홍길동", age=25, email="hong@example.com")
json_str = json.dumps(asdict(user), ensure_ascii=False)

☕ Java (Jackson 라이브러리)

// Maven 의존성
// <dependency>
//   <groupId>com.fasterxml.jackson.core</groupId>
//   <artifactId>jackson-databind</artifactId>
//   <version>2.16.0</version>
// </dependency>

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.annotation.JsonProperty;

// POJO 클래스
public class User {
    @JsonProperty("name")
    private String name;
    
    @JsonProperty("age")
    private int age;
    
    // getter, setter 생략
}

// 직렬화/역직렬화
ObjectMapper mapper = new ObjectMapper();

// 객체 → JSON 문자열
User user = new User("홍길동", 25);
String jsonStr = mapper.writeValueAsString(user);

// JSON 문자열 → 객체
User parsed = mapper.readValue(jsonStr, User.class);

// JSON 문자열 → Map
Map<String, Object> map = mapper.readValue(jsonStr, 
    new TypeReference<Map<String, Object>>() {});

// Spring Boot에서는 @RestController 사용하면 자동으로 JSON 변환
@RestController
@RequestMapping("/api")
public class UserController {
    @PostMapping("/users")
    public ResponseEntity<User> createUser(@RequestBody User user) {
        // @RequestBody가 자동으로 JSON → User 변환
        return ResponseEntity.ok(userService.save(user));
    }
}

🦫 Go

package main

import (
    "encoding/json"
    "fmt"
)

// 구조체 정의 (json 태그로 필드명 매핑)
type User struct {
    Name  string `json:"name"`
    Age   int    `json:"age"`
    Email string `json:"email,omitempty"` // 빈 값이면 JSON에서 제외
}

func main() {
    // 직렬화 (Marshal)
    user := User{Name: "홍길동", Age: 25, Email: "hong@example.com"}
    jsonBytes, err := json.Marshal(user)
    if err != nil {
        panic(err)
    }
    fmt.Println(string(jsonBytes))

    // 역직렬화 (Unmarshal)
    jsonStr := `{"name":"김철수","age":30}`
    var parsed User
    err = json.Unmarshal([]byte(jsonStr), &parsed)
    if err != nil {
        panic(err)
    }
    fmt.Println(parsed.Name) // 김철수
}

🛠️ 9. JSON 개발에 유용한 도구들

개발할 때 JSON 관련 도구 잘 쓰면 생산성이 진짜 올라가ㅋㅋ 꼭 알아야 할 도구들 소개할게.

JSON 개발 도구 생태계 JSON 데이터 포맷 JSONLint 유효성 검사 jq CLI 처리 도구 Postman API 테스트 Swagger API 문서화 JSON Schema
도구 용도 특징
JSONLint JSON 유효성 검사 웹 기반, 무료, jsonlint.com
jq CLI JSON 처리 터미널에서 JSON 필터링/변환
Postman API 테스트 GUI 기반 API 요청/응답 테스트
Swagger/OpenAPI API 문서화 JSON Schema 기반 API 스펙 정의
JSON Formatter JSON 포맷팅 가독성 있게 들여쓰기 정렬
quicktype 타입 생성 JSON에서 TypeScript/Java 타입 자동 생성
JSON Diff JSON 비교 두 JSON 파일의 차이점 시각화

🔍 jq 실전 사용법 - 터미널 JSON 처리의 신

# jq 기본 사용법 (터미널에서)

# JSON 파일 예쁘게 출력
jq '.' data.json

# 특정 필드만 추출
jq '.name' data.json

# 배열에서 특정 필드만 추출
jq '.[].name' users.json

# 조건 필터링 (age가 25 이상인 사용자)
jq '.[] | select(.age >= 25)' users.json

# 필드 변환
jq '{fullName: .name, userAge: .age}' data.json

# API 응답을 jq로 바로 처리
curl -s 'https://api.example.com/users' | jq '.[0].name'

# 배열 길이 확인
jq '. | length' users.json

# 특정 키만 선택해서 새 JSON 생성
jq '{id, name, email}' user.json

⚖️ 10. JSON vs 다른 데이터 포맷 - 언제 뭘 써야 해?

JSON이 최고긴 한데, 모든 상황에서 JSON이 최선은 아니야. 상황에 따라 다른 포맷이 더 나을 수도 있어.

포맷 장점 단점 적합한 상황
JSON 가독성 높음, 범용성, 생태계 풍부 바이너리 대비 크기 큼 웹 API, 설정 파일
XML 스키마 검증, 네임스페이스 장황함, 파싱 복잡 엔터프라이즈, SOAP API
YAML 가독성 최고, 주석 가능 파싱 느림, 들여쓰기 민감 설정 파일 (Docker, K8s)
Protobuf 매우 빠름, 크기 작음 사람이 읽기 어려움 마이크로서비스, gRPC
MessagePack JSON 호환, 바이너리 효율 디버깅 어려움 실시간 통신, 게임
CSV 단순함, 엑셀 호환 중첩 구조 불가 테이블형 데이터 내보내기
💡 결론! 일반적인 웹 API에서는 JSON이 정답이야. 근데 내부 마이크로서비스 간 통신이나 성능이 극도로 중요한 경우엔 Protobuf 고려해봐. 설정 파일은 YAML이 편하고. 상황에 맞게 선택하는 게 진짜 실력이야ㅋㅋ

🆕 11. JSON5와 JSONC - JSON의 진화형

JSON이 너무 엄격해서 불편하다는 개발자들의 요구로 나온 확장 포맷들이야. 특히 설정 파일에서 많이 쓰여.

📄 JSON5 (JSON for Humans) JSON5는 JSON의 상위 집합으로, 개발자 친화적인 기능들을 추가했어:

✅ 주석 허용 (// 한 줄, /* 여러 줄 */)
✅ 마지막 쉼표(trailing comma) 허용
✅ 작은따옴표 문자열 허용
✅ 16진수 숫자 허용 (0xFF)
✅ 키에 따옴표 없이 사용 가능 (식별자인 경우)
✅ 여러 줄 문자열 허용

사용처: Babel 설정, 일부 Node.js 프로젝트
📄 JSONC (JSON with Comments) 주석만 추가된 JSON 변형이야. VS Code의 설정 파일(settings.json, tsconfig.json)에서 사용해.

✅ 주석 허용 (// 한 줄, /* 여러 줄 */)
✅ 마지막 쉼표 허용 (일부 구현체)

사용처: VS Code 설정, TypeScript 설정 파일
// JSON5 예시 (tsconfig.json 같은 설정 파일에서 자주 봄)
{
  // 이건 JSON5 형식이야
  name: 'MyProject',  // 키에 따옴표 없어도 됨
  version: '1.0.0',
  
  /* 
    여러 줄 주석도 가능!
    설정 파일에서 진짜 유용함
  */
  settings: {
    debug: true,
    maxRetries: 3,
    timeout: 0xFF,  // 16진수 = 255
    tags: [
      'production',
      'stable',  // trailing comma OK!
    ],
  },
}

🏗️ 12. 실전 프로젝트에서 JSON API 설계하기

자 이제 진짜 실무 레벨로 가보자. 재능넷 같은 플랫폼에서 API를 설계한다면 어떻게 할까? 실제 프로젝트 시나리오로 설명할게.

📋 API 설계 원칙

1
일관성 유지
모든 API 응답이 동일한 구조를 가져야 해. 어떤 엔드포인트는 data 키에 담고, 어떤 건 result 키에 담으면 프론트엔드 개발자가 멘붕옴ㅋㅋ
2
명확한 에러 코드
HTTP 상태 코드 + 커스텀 에러 코드 조합으로 에러를 명확하게 전달해야 해. "에러가 났어요"만으로는 부족함.
3
버전 관리
API URL에 버전을 포함시켜 (/api/v1/, /api/v2/). 나중에 API 구조 바꿀 때 기존 클라이언트 안 깨짐.
4
날짜/시간 형식 통일
날짜는 반드시 ISO 8601 형식 사용 (2024-01-15T10:30:00Z). 타임존 명시 필수!
// 실전 API 응답 설계 예시 (재능 거래 플랫폼 기준)

// GET /api/v1/talents/123 - 재능 상세 조회
{
  "success": true,
  "data": {
    "id": 123,
    "title": "React 웹 개발 도와드립니다",
    "category": {
      "id": 5,
      "name": "프로그래밍",
      "slug": "programming"
    },
    "seller": {
      "id": 456,
      "nickname": "개발왕",
      "profileImage": "https://cdn.example.com/profiles/456.jpg",
      "rating": 4.8,
      "reviewCount": 127
    },
    "pricing": {
      "basic": {
        "price": 50000,
        "description": "기본 패키지",
        "deliveryDays": 3
      },
      "standard": {
        "price": 100000,
        "description": "스탠다드 패키지",
        "deliveryDays": 5
      }
    },
    "tags": ["React", "JavaScript", "프론트엔드"],
    "stats": {
      "viewCount": 1523,
      "orderCount": 89,
      "favoriteCount": 234
    },
    "createdAt": "2024-01-10T09:00:00+09:00",
    "updatedAt": "2024-01-15T14:30:00+09:00"
  },
  "meta": {
    "requestId": "req_abc123",
    "timestamp": "2024-01-15T15:00:00Z"
  }
}

// POST /api/v1/orders - 주문 생성
// 요청 Body
{
  "talentId": 123,
  "packageType": "standard",
  "requirements": "React로 쇼핑몰 메인 페이지 만들어주세요",
  "attachments": [
    {
      "type": "image",
      "url": "https://cdn.example.com/uploads/ref1.jpg"
    }
  ]
}

// 응답
{
  "success": true,
  "data": {
    "orderId": "ORD-2024-001234",
    "status": "pending_payment",
    "amount": 100000,
    "paymentDeadline": "2024-01-15T16:00:00+09:00"
  },
  "message": "주문이 생성되었습니다. 결제를 완료해주세요."
}

이런 식으로 재능넷처럼 다양한 재능을 거래하는 플랫폼에서도 JSON API 설계가 핵심이야. 일관된 구조와 명확한 데이터 타입이 개발 생산성을 엄청 높여줘.


🔮 13. GraphQL과 JSON - REST API의 대안

요즘 GraphQL 많이 들어봤지? GraphQL도 JSON을 기반으로 동작해. REST API의 over-fetching, under-fetching 문제를 해결하기 위해 Facebook이 만든 쿼리 언어야.

🔄 REST vs GraphQL 핵심 차이 REST API: 서버가 응답 구조를 결정 → 클라이언트가 받아야 함
GraphQL: 클라이언트가 필요한 데이터 구조를 직접 요청 → 딱 필요한 것만 받음
// GraphQL 쿼리 예시
query GetUser($id: ID!) {
  user(id: $id) {
    name
    email
    posts {
      title
      createdAt
    }
  }
}

// GraphQL 응답 (JSON 형식)
{
  "data": {
    "user": {
      "name": "홍길동",
      "email": "hong@example.com",
      "posts": [
        {
          "title": "첫 번째 포스트",
          "createdAt": "2024-01-10T09:00:00Z"
        }
      ]
    }
  }
}

// GraphQL 에러 응답
{
  "errors": [
    {
      "message": "사용자를 찾을 수 없습니다.",
      "locations": [{"line": 2, "column": 3}],
      "path": ["user"],
      "extensions": {
        "code": "USER_NOT_FOUND"
      }
    }
  ],
  "data": null
}
💡 GraphQL도 결국 JSON으로 데이터를 주고받아. HTTP POST 요청으로 쿼리를 보내고, JSON으로 응답받는 구조야. JSON을 잘 이해하면 GraphQL도 쉽게 이해할 수 있어!

🐛 14. JSON 트러블슈팅 - 자주 만나는 에러들

개발하다 보면 JSON 관련 에러 진짜 많이 만나ㅋㅋ 자주 나오는 에러들과 해결법 정리해줄게.

❌ SyntaxError: Unexpected token 원인: JSON 형식이 잘못됨 (작은따옴표, 주석, trailing comma 등)
해결: JSONLint로 유효성 검사 → 문제 위치 확인 → 수정
❌ 한글이 \uXXXX로 인코딩되어 나옴 원인: ensure_ascii=True (Python 기본값)
해결: json.dumps(data, ensure_ascii=False)
❌ 날짜 객체가 JSON으로 변환 안 됨 원인: JSON은 Date 타입을 지원 안 함
해결: ISO 8601 문자열로 변환 후 직렬화
JSON.stringify(date.toISOString())
❌ 순환 참조 에러 (Circular reference) 원인: 객체가 자기 자신을 참조하는 구조
해결: JSON.stringify()의 replacer 함수로 순환 참조 제거
또는 flatted, circular-json 라이브러리 사용
❌ 큰 숫자 정밀도 손실 원인: JSON Number는 IEEE 754 double precision → 2^53 이상 정수 정밀도 손실
해결: 큰 숫자는 문자열로 전송 ("id": "9007199254740993")
또는 BigInt 처리 라이브러리 사용
// 순환 참조 해결 예시
const obj = { name: "홍길동" };
obj.self = obj;  // 순환 참조!

// ❌ 에러 발생
JSON.stringify(obj);  // TypeError: Converting circular structure to JSON

// ✅ replacer 함수로 해결
const seen = new WeakSet();
const safe = JSON.stringify(obj, (key, value) => {
  if (typeof value === 'object' && value !== null) {
    if (seen.has(value)) return '[Circular]';
    seen.add(value);
  }
  return value;
});

// 큰 숫자 처리
const bigId = 9007199254740993n;  // BigInt
const json = JSON.stringify({
  id: bigId.toString()  // 문자열로 변환
});
// {"id":"9007199254740993"}

🎯 마무리 - JSON 마스터가 되는 길

자 여기까지 JSON의 기초부터 실무 패턴, 보안, 성능 최적화까지 다 다뤘어! 진짜 길었지?ㅋㅋ 근데 이 정도는 알아야 진짜 API 개발자라고 할 수 있어.

✅ JSON 마스터 체크리스트 □ JSON 6가지 데이터 타입 완벽 이해
□ 직렬화/역직렬화 개념 및 각 언어별 구현
□ JSON Schema로 데이터 유효성 검증
□ REST API 응답 패턴 (래퍼, 페이지네이션, 에러)
□ HTTP 헤더 Content-Type 설정
□ JSON 보안 취약점 인지 및 방어
□ 성능 최적화 기법 (압축, 캐싱, 스트리밍)
□ jq 등 JSON 도구 활용
□ 트러블슈팅 능력 (순환 참조, 큰 숫자, 인코딩)

개발 공부하면서 JSON 관련 실습이 필요하다면, 재능넷에서 API 개발 전문가를 찾아서 1:1 멘토링을 받아보는 것도 좋은 방법이야. 이론만큼 실전 경험이 중요하거든!

JSON은 단순해 보이지만 깊이 파면 팔수록 알아야 할 게 많아. 오늘 배운 내용들을 실제 프로젝트에 적용해보면서 감을 익혀봐. 처음엔 어색해도 하다 보면 자연스럽게 손에 익을 거야 💪

그리고 JSON 관련 최신 트렌드도 계속 팔로우해봐. JSON-LD, JSON:API 스펙, OpenAPI 3.1 같은 것들도 알면 알수록 개발 레벨이 올라가거든ㅋㅋ 화이팅! 🚀

JSON REST API 데이터 포맷 JSON Schema 직렬화 API 설계 HTTP 통신 GraphQL 웹 개발 백엔드
댓글 작성

이 글에 대한 여러분의 생각을 들려주세요

댓글 0
댓글을 불러오는 중입니다.

아직 댓글이 없습니다.