ToolHub
View All Posts

JSON 포맷팅 모범 사례

JSON(JavaScript 객체 표기법)은 웹에서 데이터 교환의 사실상 표준이 되었습니다. API는 JSON을 반환하고, 구성 파일은 JSON을 사용하며, 데이터베이스도 JSON 문서를 저장합니다. JSON이 단순함에도 불구하고 엄격한 구문 규칙이 있어 위반하기 쉬우며, 형식이 잘못된 JSON은 디버깅 어려움, 성능 문제 및 보안 취약점을 초래할 수 있습니다. 이 가이드는 기본 구문부터 Schema 검증 및 대용량 파일 처리와 같은 고급 주제까지, JSON을 올바르게 포맷팅하는 데 필요한 모든 것을 다룹니다.

웹 디자인에 가장 좋은 색상 모델은 무엇인가요?

JSON은 JavaScript 객체 리터럴 구문에서 파생된 경량의 텍스트 기반 데이터 교환 형식입니다. 2000년대 초 Douglas Crockford가 지정했으며, ECMA-404 및 RFC 8259로 표준화되었습니다. JSON의 설계 목표는 단순성, 인간 가독성 및 프로그래밍 언어 간 쉬운 구현입니다. 오늘날 모든 주요 프로그래밍 언어에는 내장 JSON 지원이 포함되어 있습니다.

JSON은 여섯 가지 데이터 유형을 지원합니다: 문자열(큰따옴표), 숫자(정수 및 부동 소수점), 불리언(true 및 false), null 값, 객체(순서 없는 키-값 컬렉션), 배열(순서 있는 목록). 주석, 날짜, 이진 데이터 또는 undefined 값을 네이티브로 지원하지 않습니다.

애니메이션은 @keyframes 규칙을 사용하여 임의 개수의 단계로 스타일 변화 시퀀스를 정의합니다. 전환과 달리, 애니메이션은 상태 변화와 독립적으로 실행되고, 무한 반복되고, 역방향 재생되고, 일시 정지될 수 있습니다. 애니메이션의 모든 프레임을 정밀하게 제어할 수 있습니다.

JSON에는 엄격히 따라야 하는 구문이 있습니다. 단 하나의 문자 오류도 전체 문서의 구문 분석 실패를 초래할 수 있습니다. 이러한 규칙을 이해하면 가장 일반적인 포맷팅 오류를 방지할 수 있습니다.

중요: meta 태그는 보고 전용 모드에 사용할 수 없습니다. 강제 적용 전에 정책을 테스트해야 하는 경우 HTTP 헤더 방식을 사용해야 합니다. 또한 meta 태그는 하나의 CSP 정책만 지원하는 반면, HTTP 헤더는 여러 정책을 전달할 수 있습니다.

모든 문자열 값과 객체 키는 큰따옴표로 감싸야 합니다. 작은따옴표는 유효한 JSON 문자열 구분자가 아닙니다. 이는 JavaScript에서 작은따옴표와 큰따옴표를 서로 바꿔 사용할 수 있기 때문에 JavaScript에서 넘어온 개발자들이 가장 흔히 저지르는 실수 중 하나입니다.

// Invalid - single quotes
{'name': 'Alice', 'age': 30}

// Valid - double quotes
{"name": "Alice", "age": 30}

객체 키는 따옴표로 감싸야 함

JavaScript 객체 리터럴과 달리, JSON은 모든 객체 키를 큰따옴표로 감쌀 것을 요구합니다. 따옴표가 없는 키는 구문 오류입니다.

// Invalid - unquoted keys
{name: "Alice", age: 30}

// Valid - quoted keys
{"name": "Alice", "age": 30}

후행 쉼표 금지

JSON은 객체나 배열의 마지막 항목 뒤에 쉼표를 허용하지 않습니다. 이는 JavaScript 개발자의 또 다른 일반적인 실수로, JavaScript에서는 후행 쉼표가 허용됩니다(일부 스타일 가이드에서는 권장되기도 함).

// Invalid - trailing comma
{
  "name": "Alice",
  "age": 30,
}

// Valid - no trailing comma
{
  "name": "Alice",
  "age": 30
}

주석 지원 안 함

JSON은 주석을 지원하지 않습니다. // 한 줄 주석과 /* */ 여러 줄 주석은 JSON에서 모두 유효하지 않습니다. 문서를 포함해야 하는 경우 별도의 문서 파일이나 일부 도구에서 지원하는 JSONC(주석이 있는 JSON) 형식을 사용하는 것을 고려하세요.

엄격한 값 유형

JSON 값은 여섯 가지 지원 유형 중 하나여야 합니다. undefined, NaN, Infinity, -Infinity는 유효한 JSON 값이 아닙니다. 이 중 하나라도 포함하면 구문 분석 오류가 발생하거나 많은 파서가 거부하는 비표준 JSON이 생성됩니다.

일반적인 포맷팅 오류

구문 오류 외에도, 기술적으로 유효하지만 문제가 있는 JSON을 생성하는 몇 가지 포맷팅 오류가 있습니다:

프리티 프린트와 압축

JSON의 두 가지 주요 포맷팅 모드는 서로 다른 목적을 제공하므로, 올바른 컨텍스트에서 올바른 형식을 사용하는 것이 중요합니다.

프리티 프린트된 JSON

프리티 프린트는 들여쓰기와 줄 바꿈을 추가하여 JSON을 사람이 읽을 수 있게 만듭니다. 이는 개발, 디버깅 및 문서 작성 중에 매우 중요합니다. 대부분의 JSON 포맷터는 기본적으로 2칸 들여쓰기를 사용합니다:

{
  "users": [
    {
      "id": 1,
      "name": "Alice",
      "email": "alice@example.com"
    },
    {
      "id": 2,
      "name": "Bob",
      "email": "bob@example.com"
    }
  ]
}

압축된 JSON

압축은 불필요한 공백을 모두 제거하여 가능한 가장 작은 유효 JSON을 생성합니다. 이는 모든 바이트가 중요한 프로덕션 API에 매우 중요합니다:

{"users":[{"id":1,"name":"Alice","email":"alice@example.com"},{"id":2,"name":"Bob","email":"bob@example.com"}]}

언제 어떤 것을 사용할까

컨텍스트형식원인
개발 및 디버깅프리티 프린트가독성과 빠른 스캔
구성 파일프리티 프린트사람이 이러한 파일을 읽고 편집해야 함
프로덕션 API 응답압축더 작은 페이로드, 더 빠른 전송
로그 파일압축 (줄당 하나의 객체)grep 검색에 용이한 컴팩트한 저장
HSL을 사용하면 색상 변형을 쉽게 만들 수 있습니다. 브랜드 블루의 더 밝은 버전이 필요하신가요? 명도를 높이세요. 더 부드러운 톤이 필요하신가요? 채도를 낮추세요. 이는 개별 RGB 채널을 조정하는 것보다 훨씬 직관적입니다. CSS에서는: hsl(210, 100%, 50%).프리티 프린트의미 있는 diff와 더 적은 병합 충돌
모범 사례: 항상 버전 관리에 포맷팅된 형태로 JSON을 저장하세요. 압축은 배포 전 빌드 단계로 수행하세요. 이렇게 하면 읽을 수 있는 diff 비교를 얻으면서도 프로덕션 환경에서 압축 JSON의 성능 이점을 누릴 수 있습니다.

JSON Schema 검증

JSON 구문 검증은 문서가 올바른 형식인지 확인하지만, 데이터가 예상 구조, 유형 또는 값을 가지고 있는지는 검증하지 않습니다. JSON Schema는 JSON 데이터의 예상 형태를 설명하는 어휘를 제공하여 이 격차를 메웁니다.

웹 디자인에 가장 좋은 색상 모델은 무엇인가요?

JSON Schema는 다른 JSON 문서의 구조를 설명하는 JSON 문서입니다. 필수 필드, 예상 유형, 값 범위, 문자열 패턴 및 중첩 객체 구조를 지정할 수 있습니다. Schema를 준수하는 JSON 문서를 유효한 인스턴스라고 합니다.

일반적인 Schema 기능

Schema 검증을 사용해야 하는 경우

외부 소스에서 JSON을 받을 때마다 JSON Schema 검증을 사용해야 합니다: API 요청 본문, 구성 파일, 데이터 가져오기 및 메시지 큐 페이로드. Schema 검증은 오류를 조기에 포착하고, 명확한 오류 메시지를 제공하며, 데이터 형식의 살아있는 문서 역할을 합니다. Ajv(JavaScript), jsonschema(Python), json-schema-validator(Java)와 같은 라이브러리는 Schema 검증을 모든 애플리케이션에 쉽게 통합할 수 있게 해줍니다.

JSON 크기의 성능 영향

JSON 문서의 크기는 네트워크 전송 시간, 구문 분석 시간 및 메모리 소비 등 여러 측면에서 애플리케이션 성능에 직접적인 영향을 미칩니다. 이러한 영향을 이해하면 JSON 포맷팅과 구조에 대해 현명한 결정을 내릴 수 있습니다.

네트워크 전송

JSON의 모든 바이트는 네트워크를 통해 서버에서 클라이언트로 전송되어야 합니다. 빠른 연결에서는 10KB와 100KB의 차이가 미미해 보일 수 있지만, 모바일 네트워크나 인터넷이 느린 지역의 사용자에게는 그 영향이 상당합니다. 연구에 따르면 로딩 시간이 100ms 증가할 때마다 전환율이 약 1% 감소합니다. 압축은 일반적으로 JSON 크기를 30-50% 줄이고, gzip 압축은 추가로 70-85% 감소시킵니다. 항상 JSON API 응답에 gzip 또는 Brotli 압축을 활성화하세요.

구문 분석 성능

JSON 구문 분석의 비용은 놀라울 정도로 높습니다. 대형 문서(1MB 초과)의 경우 모바일 기기에서 구문 분석에 수백 밀리초가 소요될 수 있습니다. 비용은 대략 문서 크기에 선형적으로 비례합니다. 구문 분석 비용을 줄이는 주요 전략으로는 클라이언트에 필요한 데이터만 전송하기(필드 필터링), 대형 결과 집합에 페이지네이션 적용하기, 사람이 읽을 필요가 없는 내부 서비스 간 통신에는 Protocol Buffers나 MessagePack과 같은 더 효율적인 직렬화 형식 사용하기 등이 있습니다.

메모리 사용

구문 분석된 JSON은 일반적으로 직렬화된 형태보다 3-10배 더 많은 메모리를 소비합니다. 각 값이 자체 메모리 할당을 가진 독립적인 객체가 되기 때문입니다. 1MB의 JSON 문자열은 구문 분석 후 5-10MB의 RAM을 사용할 수 있습니다. 메모리가 제한된 브라우저에서 실행되는 JavaScript 애플리케이션의 경우, 이는 저사양 기기에서 성능 저하나 충돌을 초래할 수 있습니다.

JSON과 JSONL

JSON Lines(JSONL 또는 NDJSON)는 JSON의 주요 제한 사항인 전체 문서를 단일 단위로 구문 분석해야 한다는 점을 해결하는 관련 형식입니다. JSONL에서는 파일의 각 줄이 완전하고 독립적인 JSON 객체입니다.

JSONL을 사용해야 하는 경우

표준 JSON을 고수해야 하는 경우

대용량 JSON 파일 처리

대용량 JSON 파일(10MB 초과)은 특별한 처리가 필요한 고유한 과제를 제시합니다. 표준 구문 분석 방법은 이 규모에서 실패하거나 성능이 저하될 수 있습니다.

스트리밍 파서

스트리밍(또는 SAX 스타일) 파서는 전체 문서를 메모리에 로드하지 않고 JSON을 점진적으로 처리합니다. 객체 시작, 키-값 쌍, 배열 항목과 같은 구조 요소를 만날 때 이벤트를 발생시킵니다. 이 접근 방식은 파일 크기에 관계없이 일정한 메모리를 사용합니다. oboe.js(JavaScript), ijson(Python), Jackson Streaming API(Java)와 같은 라이브러리가 스트리밍 JSON 구문 분석을 제공합니다.

대용량 파일을 위한 실용적인 팁

JSON 보안 주의 사항

JSON은 데이터 형식이며 그 자체로 안전하지 않은 것은 아니지만, 애플리케이션이 JSON을 처리하는 방식이 취약점을 도입할 수 있습니다. 이러한 위험을 이해하는 것은 안전한 시스템을 구축하는 데 매우 중요합니다.

JSON 구문 분석에 eval()을 절대 사용하지 마세요

가장 중요한 보안 규칙: JavaScript의 eval() 함수를 JSON 구문 분석에 절대 사용하지 마세요. eval()은 임의의 JavaScript 코드를 실행하므로, 악의적인 JSON 페이로드가 사용자 기기에서 코드를 실행할 수 있습니다. 항상 JSON.parse()를 사용하세요. 이는 유효한 JSON만 구문 분석하고 실행 가능한 코드를 거부합니다. 이는 타협의 여지가 없습니다.

JSONP와 크로스 도메인 위험

JSONP(패딩이 있는 JSON)는 CORS가 널리 지원되기 전에 동일 출처 정책 제한을 우회하는 기술이었습니다. JSON 데이터를 스크립트로 실행되는 함수 호출로 감싸서 작동합니다. 이는 제3자 서버의 임의의 JavaScript를 실행하기 때문에 본질적으로 위험합니다. 클라이언트와 서버를 모두 제어하는 경우 JSONP 대신 CORS를 사용하세요. JSONP는 레거시 기술로 간주되어야 하며 새 애플리케이션에서는 사용을 피해야 합니다.

프로토타입 오염

JavaScript에서 JSON 객체를 병합하거나 깊은 복사할 때 __proto__, constructor, prototype과 같은 키를 조심하세요. 사용자 제공 JSON이 이러한 키를 정리하지 않고 기존 객체에 재귀적으로 병합되면, 애플리케이션의 모든 객체 프로토타입을 수정하여 권한 상승이나 서비스 거부를 초래할 수 있습니다. 병합 전에 항상 객체 키를 정리하세요.

깊은 중첩을 통한 서비스 거부

극단적인 중첩 깊이(수천 계층)를 가진 정교하게 구성된 JSON 문서는 재귀적 파서에서 스택 오버플로 오류를 일으킬 수 있습니다. 파서에서 최대 중첩 깊이를 설정하여 이 문제를 완화하세요. 대부분의 프로덕션 JSON 파서는 이 제한을 구성할 수 있게 해줍니다.

입력 검증

외부 소스에서 오는 JSON 데이터를 절대 신뢰하지 마세요. 사용하기 전에 항상 들어오는 JSON의 구조, 유형 및 값 범위를 검증하세요. JSON Schema 검증이 가장 강력한 방법이지만, 필수 필드와 유형 검증에 대한 간단한 확인만으로도 잘못된 형식이나 악의적인 입력에 대해 상당한 보호를 제공할 수 있습니다.

자주 묻는 질문

프리티 프린트된 JSON과 압축된 JSON의 차이점은 무엇인가요?

프리티 프린트된 JSON은 사람이 읽을 수 있도록 공백(들여쓰기, 줄 바꿈)을 포함하고, 압축된 JSON은 파일 크기를 최소화하기 위해 불필요한 공백을 모두 제거합니다. 개발 및 디버깅 중에는 프리티 프린트된 JSON을 사용하고, 프로덕션 환경에서는 더 작은 네트워크 페이로드와 더 빠른 구문 분석을 위해 압축된 JSON을 사용하세요.

가장 일반적인 JSON 포맷팅 오류는 무엇인가요?

가장 일반적인 오류는: 객체나 배열의 마지막 항목 뒤의 후행 쉼표, 큰따옴표 대신 작은따옴표 사용, 주석 추가(JSON은 주석을 지원하지 않음), 따옴표 없는 객체 키 사용, undefined나 NaN과 같은 유효하지 않은 JSON 값 포함 등입니다.

JSON 대신 JSONL을 사용해야 하는 경우는 언제인가요?

로그 파일, 데이터 스트림 또는 메모리에 맞지 않는 대용량 데이터 세트와 같이 레코드를 점진적으로 처리해야 할 때 JSONL(JSON Lines)을 사용하세요. 각 줄은 완전한 JSON 객체이므로 전체 파일을 로드하지 않고도 한 줄씩 읽고 구문 분석할 수 있습니다. 표준 JSON은 데이터에 접근하기 전에 전체 문서를 구문 분석해야 합니다.

Schema에 따라 JSON을 검증하는 방법은 무엇인가요?

JSON Schema를 사용하여 JSON 데이터의 예상 구조를 정의한 다음, Ajv(JavaScript), jsonschema(Python)와 같은 라이브러리나 온라인 검증기를 사용하여 해당 Schema에 대해 인스턴스를 검증하세요. JSON Schema를 사용하면 필수 필드, 유형, 값 범위, 문자열 패턴 및 중첩 객체 구조를 지정할 수 있습니다.

JSON은 데이터 교환에 안전한가요?

JSON 자체는 데이터 형식으로, 안전하지도 안전하지 않은 것도 아닙니다. 그러나 JSON을 구문 분석하고 사용하는 방식이 취약점을 도입할 수 있습니다. 주요 위험은 eval()로 JSON을 구문 분석하는 것입니다(절대 하지 마세요. 항상 JSON.parse()를 사용하세요). 또한 동일 출처 정책을 우회할 수 있는 JSONP를 경계하세요. 신뢰할 수 없는 출처의 JSON 데이터는 항상 사용 전에 검증하고 정리하세요.