JSON 응답이 파싱된다고 해서 화면에서 바로 쓸 수 있는 것은 아닙니다. 문법이 맞는지, 필요한 필드가 있는지, 숫자와 문자열을 제대로 구분했는지는 각각 확인해야 합니다. 이 글에서는 win-j의 관리자 도구 검색 응답 구조를 예로 들어 세 단계를 나눠 봅니다.
검색 결과 하나를 JSON으로 읽기
아래는 현재 도구 검색 코드의 필드 구성에 맞춰 만든 설명용 데이터입니다. 운영 서버에서 수집한 응답은 아닙니다.
{
"results": [
{
"name": "글자수 계산기",
"description": "입력한 텍스트의 길이를 확인합니다.",
"url": "/utility/text-counter/",
"icon": "bi bi-tools",
"category": "텍스트"
}
]
}
바깥쪽 {}는 객체, results의 []는 배열입니다. 첫 결과의 이름은 JavaScript에서 data.results[0].name으로 읽습니다. 검색 결과가 없으면 {"results": []}가 될 수 있으므로 첫 원소가 항상 있다고 가정하면 안 됩니다.
JSON은 문자열·숫자·불리언·null·객체·배열을 표현합니다. 키와 문자열은 큰따옴표로 감싸고, 불리언은 true와 false를 씁니다. 주석, 마지막 항목 뒤의 쉼표, undefined, NaN, Infinity는 표준 JSON 값이 아닙니다. 최상위 값이 반드시 객체여야 하는 것은 아니지만, 이 검색 API의 계약은 객체 안에 results 배열을 두는 것입니다. JSON 표준 RFC 8259
문법 검사 다음에 구조 검사하기
다음 코드는 외부 요청 없이 브라우저 개발자 도구 콘솔에서 실행할 수 있습니다.
const text = '{"results":[{"name":"글자수 계산기"}]}';
const data = JSON.parse(text);
if (!data || !Array.isArray(data.results)) {
throw new Error("results 배열이 필요합니다.");
}
console.log(data.results[0]?.name ?? "검색 결과 없음");
결과는 글자수 계산기입니다. 입력을 {"results":[]}로 바꾸면 검색 결과 없음이 나옵니다. {"results":"없음"}은 문법적으로 올바른 JSON이지만 위 구조 검사에는 실패합니다. 이 구분이 있어야 데이터 형식 변경을 빈 검색 결과로 잘못 숨기지 않습니다.
| 입력 문제 | 확인할 지점 | 수정 방향 |
|---|---|---|
{'name':'도구'} |
작은따옴표 | 키와 문자열에 큰따옴표 사용 |
{"count":1,} |
마지막 쉼표 | 마지막 쉼표 제거 |
{"results":null} |
값의 자료형 | 응답 계약이 배열이면 배열로 전달 |
| 동일한 키가 두 번 등장 | 원본 작성 과정 | 중복을 제거하고 어느 값이 맞는지 결정 |
중복 키는 파서마다 처리 결과가 다를 수 있습니다. 들여쓰기 정리로 마지막 값만 남았다면 원본의 문제를 놓칠 수 있으므로, 비교용 원문을 먼저 보관합니다.
큰 숫자와 식별자는 별도로 다루기
JavaScript의 일반 숫자는 모든 크기의 정수를 정확하게 표현하지 못합니다. 아래 예제는 계산 결과보다 파싱 과정에서 값이 바뀔 수 있다는 사실을 확인하기 위한 것입니다.
const numeric = JSON.parse('{"id":9007199254740993}');
const textual = JSON.parse('{"id":"9007199254740993"}');
console.log(numeric.id); // 9007199254740992
console.log(textual.id); // 9007199254740993
주문번호·전화번호·앞자리 0이 있는 코드는 계산용 숫자가 아니라 식별자입니다. API 양쪽에서 문자열로 전달하기로 정하면 자릿수를 유지하기 쉽습니다. 금액도 소수 정밀도가 중요하다면 정수 최소 단위 또는 십진 문자열 같은 계약을 먼저 정해야 합니다. 이미 손실된 숫자를 나중에 문자열로 바꿔도 복구되지는 않습니다.
Python의 한글 출력과 파일 인코딩 구분
import json
item = {"name": "글자수", "enabled": True}
escaped = json.dumps(item)
readable = json.dumps(item, ensure_ascii=False, indent=2)
assert json.loads(escaped) == json.loads(readable) == item
print(readable)
ensure_ascii=False는 한글을 \uXXXX 형태로 이스케이프하지 않고 보여주는 옵션입니다. 기본값으로 만든 문자열도 정상적으로 복원됩니다. 이 옵션이 파일·터미널의 인코딩 문제를 고치는 것은 아닙니다. 파일로 저장할 때는 open(..., encoding="utf-8")처럼 인코딩도 지정합니다. Python 기본 인코더는 비표준 NaN을 허용하므로 엄격한 JSON을 생성하려면 allow_nan=False도 검토합니다. Python json 문서
실제 API에서는 먼저 HTTP 상태와 응답 형식을 확인한 뒤 이 구조 검사를 적용합니다. 그 순서는 Python Requests로 JSON 응답을 확인하는 글에서 이어집니다.
첫 댓글을 남겨보세요.