JSON Schema 검증기

JSON, YAML, JSON Lines를 JSON Schema(draft-04~2020-12)로 검증하는 유효성 검사 도구. 오류에서 데이터 행과 스키마 키워드로 이동하고, NFD 한글과 큰 정수도 짚어 줍니다.

  • 브라우저에서 처리
  • 데이터가 브라우저 밖으로 나가지 않습니다
  • 무료 · 회원가입 불필요
자동은 $schema를 읽고, 없으면 Draft 2020-12를 사용합니다. 메뉴 선택이 $schema보다 우선합니다. 이 메뉴와 “format 검사” 설정만 저장하며 스키마와 데이터는 저장하지 않습니다.
“format 검사”는 email, date, uuid 등 지원하는 형식을 검증합니다. 끄면 format을 주석으로 취급합니다. 인식하지 못하는 형식은 안내에 표시합니다.
입력 후 300밀리초 뒤에 검증합니다. 세 입력의 합계가 UTF-16 코드 단위로 1,000,000을 넘으면 “검증” 또는 Ctrl/⌘+Enter를 누르세요. “취소”로 실행 중인 검증을 멈출 수 있습니다.

스키마와 데이터를 붙여넣으세요. 입력할 때마다 결과가 바뀝니다.

JSON이나 YAML을 붙여넣거나 파일을 열거나 이 칸에 놓으세요. 파일은 20 MiB까지 받습니다. 예제를 선택하면 두 입력과 참조되는 스키마를 바꾼 뒤 검증합니다.
JSON, YAML, JSON Lines 또는 ---만 있는 줄로 구분한 여러 YAML 문서를 붙여넣으세요. 각 문서를 따로 검증합니다. 파일을 열거나 놓을 수도 있으며 한도는 20 MiB입니다.
참조되는 스키마를 각각 $id와 함께 붙여넣으세요. 여러 스키마는 ---만 있는 줄로 구분합니다. $ref URL은 내려받지 않습니다.
참조되는 스키마($ref 대상)

$ref가 가리키는 스키마를 붙여넣으세요. 각각 "$id"가 있어야 합니다. 여러 개는 --- 만 있는 줄로 구분합니다. URL은 내려받지 않습니다.

검증 오류와 안내가 여기에 표시됩니다.

자세한 가이드 읽기 JSON Schema 검증기: 스키마로 JSON 데이터를 검증하는 완전 가이드
예시·자세한 설명·자주 묻는 질문 실제 출력이 있는 예시, 다른 도구와의 차이, 자주 묻는 질문.

예: 회원 가입 데이터의 NFD 한글

macOS의 HFS+ 파일 시스템은 파일 이름을 분해된 형태(NFD)로 저장합니다(Apple Technical Q&A QA1173). 그런 텍스트가 섞여 들어오면 화면에는 ‘홍길동’으로 보여도 길이 검사에서 걸립니다. 아래 데이터의 name은 JSON 이스케이프로 쓴 NFD ‘홍길동’입니다.

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "required": ["name", "bizNo"],
  "properties": {
    "name": { "type": "string", "minLength": 2, "maxLength": 5 },
    "bizNo": { "type": "string", "pattern": "^[0-9]{3}-[0-9]{2}-[0-9]{5}$" },
    "phone": { "type": "string", "pattern": "^01[016789]-[0-9]{3,4}-[0-9]{4}$" }
  }
}
{
  "name": "\u1112\u1169\u11bc\u1100\u1175\u11af\u1103\u1169\u11bc",
  "bizNo": "123-45-6789",
  "phone": "010-1234-5678"
}
오류 2개, 위치 2곳(Draft 2020-12).
/name (2행 11열): 5자 이하여야 합니다. 9자입니다  스키마 #/properties/name/maxLength
/bizNo (3행 12열): 패턴 ^[0-9]{3}-[0-9]{2}-[0-9]{5}$과(와) 맞지 않습니다  스키마 #/properties/bizNo/pattern

maxLength는 유니코드 문자(코드 포인트) 수를 셉니다. NFC ‘홍길동’은 3자라 통과하고, NFD는 초성·중성·종성이 각각 1자라 9자가 됩니다. 사업자등록번호는 마지막 묶음이 다섯 자리여야 하는데 네 자리라서 pattern에 걸렸습니다.

예: $schema 없이 붙여넣은 draft-07 스키마

$schema가 없으면 2020-12로 검증합니다. draft-07 스타일로 items를 배열로 쓴 스키마는 2020-12에서는 스키마 자체가 잘못된 것이 됩니다.

{
  "type": "array",
  "items": [{ "type": "string" }, { "type": "integer" }],
  "additionalItems": false
}
["서울", 3, "추가"]
스키마 자체가 규격에 맞지 않습니다(Draft 2020-12):
#/items: object | boolean여야 하는데 array입니다 — Draft 2020-12의 "items"는 스키마 하나만 받습니다. 배열 형식은 draft-07 문법입니다. 위치별 스키마는 "prefixItems"를 쓰세요.
* $schema가 없어 Draft 2020-12로 검증했습니다. "$schema"를 쓰거나 메뉴에서 드래프트를 고르세요.
* Draft 2020-12에서는 #의 "additionalItems"가 무시됩니다. "prefixItems"와 "items"를 쓰세요.
* 스키마에 draft-07 문법 "items" (array), "additionalItems"가 있습니다. Draft 7을 고르거나 "$schema"를 쓰세요.

메뉴에서 Draft 7을 고르면 같은 스키마가 draft-07 규칙으로 검증되고, 세 번째 항목이 additionalItems에 걸립니다.

오류 1개(Draft 7).
(루트) (1행 1열): 항목은 2개까지입니다. 3개 있습니다  스키마 #/additionalItems

예: JSON Lines로 내보낸 로그

한 줄에 JSON 하나씩 붙여넣으면 줄마다 따로 검증하고, 오류가 있는 줄을 알려 줍니다.

{ "type": "object", "required": ["userId", "action"], "properties": { "userId": { "type": "integer" }, "action": { "enum": ["로그인", "로그아웃", "결제"] } } }
{"userId": 101, "action": "로그인"}
{"userId": "102", "action": "결제"}
{"userId": 103, "action": "환불"}
문서 3개 중 2개에 오류가 있습니다(Draft 2020-12).
문서 1(1행): 유효
문서 2(2행)
  /userId (2행 12열): integer여야 하는데 string입니다  스키마 #/properties/userId/type
문서 3(3행)
  /action (3행 27열): "로그인", "로그아웃", "결제" 중 하나여야 합니다  스키마 #/properties/action/enum
* 데이터를 JSON Lines로 읽었습니다. 3줄을 한 줄씩 검증합니다.
* $schema가 없어 Draft 2020-12로 검증했습니다. "$schema"를 쓰거나 메뉴에서 드래프트를 고르세요.

”판정할 수 없음”이 표시되는 경우

Ajv가 틀린 결과를 내는 것으로 알려진 입력에서는 유효·무효를 표시하지 않고 “판정할 수 없음”과 이유를 표시합니다. 복사한 텍스트와 JSON도 같습니다("state": "unknown", "valid": null). 회원 유형에 따라 필드를 받는 스키마에서 else를 빠뜨리면 이 경우에 해당합니다:

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": { "memberType": { "enum": ["개인", "법인"] } },
  "if": { "properties": { "memberType": { "const": "법인" } } },
  "then": { "properties": { "bizRegNo": { "type": "string", "pattern": "^[0-9]{3}-[0-9]{2}-[0-9]{5}$" } } },
  "unevaluatedProperties": false
}
{ "memberType": "법인", "bizRegNo": "123-45-67890" }
판정할 수 없습니다(Draft 2020-12): 검증기가 정확히 검사할 수 없는 경우에 해당해 유효·무효 결과를 내지 않습니다. 이유는 아래에 있습니다.
판정할 수 없음. 이유:
- #/unevaluatedProperties의 "unevaluatedProperties"가 #/if의 "then"이나 "else"가 없는 "if"와 함께 쓰였습니다. Ajv는 이 조합을 잘못 판정합니다.

unevaluatedProperties와 then이나 else가 없는 if를 함께 쓰면 Ajv가 공식 테스트에서 틀립니다. 아무 제약이 없는 "else": true를 더하면 의미는 같고 검증할 수 있습니다:

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": { "memberType": { "enum": ["개인", "법인"] } },
  "if": { "properties": { "memberType": { "const": "법인" } } },
  "then": { "properties": { "bizRegNo": { "type": "string", "pattern": "^[0-9]{3}-[0-9]{2}-[0-9]{5}$" } } },
  "else": true,
  "unevaluatedProperties": false
}
{ "memberType": "법인", "bizRegNo": "123-45-67890" }
유효: 데이터가 스키마에 맞습니다(Draft 2020-12).

이 밖에 $dynamicRef, unevaluatedItems와 contains 또는 anyOf / oneOf 안의 items 조합, 상대 참조와 중첩된 $id(Ajv의 스택이 넘침), $vocabulary를 바꾼 메타 스키마, 데이터에도 있는 __proto__ 속성, JavaScript가 정확히 담을 수 없는 숫자(9007199254740993 등)도 같은 방식으로 처리합니다.

오류를 묶는 방식

Ajv는 oneOf / anyOf에서 실패한 모든 분기의 오류를 나열합니다. “카드”와 “계좌” 두 가지 결제 수단 중 카드 번호 자릿수가 틀리면 Ajv는 오류 5개를 내고, 그중 3개는 상관없는 계좌 분기에서 나옵니다. 이 도구는 /payment에 오류 1개만 보여 주고 가장 가까운 분기(오류가 가장 적은 분기, const 판별 필드가 맞지 않는 분기는 뒤로)를 펼치며 나머지는 접어 둡니다. 분기가 $ref여도 같습니다. if / then 조건에서 실패하면 then에서 나온 오류를 바로 보여 주고 “then” 경유라고 표시하므로, 어떤 조건 때문에 필수가 되었는지 알 수 있습니다.

다른 온라인 도구와 비교

2026-10-02에 Bing(한국)에서 “JSON Schema 검증” 결과에 나온 LiteDevTools의 JSON Schema 검증기로 같은 입력을 시험했습니다.

입력올바른 결과LiteDevTools이 도구
draft-07에서 $ref 옆의 maxLengthmaxLength 무시, 유효maxLength 오류유효(무시했다고 안내)
"required": ["constructor"]와 {}무효유효무효
"nullable": true인 문자열에 null무효무효무효(안내 표시)
2020-12 prefixItems와 "items": false, [1, "x"]무효유효무효
oneOf 결제 수단 오류—fails oneOf만 표시가장 가까운 분기의 오류 표시
YAML 데이터—미지원지원

두 도구 모두 브라우저 안에서 동작하며, 시험 중에 데이터를 담은 요청은 없었습니다.

제한

  • 검증 엔진은 Ajv 8.18(ajv-formats 3.0.1, ajv-draft-04 1.0.0)입니다. 공식 JSON Schema Test Suite의 필수 테스트에서 draft-07은 929개 중 927개, 2020-12는 1,301개 중 1,210개가 기대한 결과이고, 나머지(2개, 91개)는 “판정할 수 없음”입니다. 틀린 결과를 내는 테스트는 없습니다. 판정은 스키마와 데이터의 구조만 보고 정하므로 $dynamicRef가 있는 스키마는 모두 “판정할 수 없음”이 되며, Ajv가 맞게 처리하던 테스트도 일부 포함됩니다.
  • $ref의 URL은 내려받지 않습니다.
  • JavaScript가 정확히 담을 수 없는 숫자(9007199254740993, 1.0000000000000001, 1e400 등)는 행 번호와 함께 안내하고, 스키마가 숫자를 비교하면 그 문서를 “판정할 수 없음”으로 표시합니다. 스키마나 YAML 데이터에 있으면 항상 “판정할 수 없음”입니다. multipleOf는 십진수 값으로 판정하므로 19.99는 0.01의 배수, 0.3은 0.1의 배수입니다(Ajv처럼 부동소수점 수로 나누면 배수가 아니라고 판정합니다). 중복된 키는 마지막 값만 남고 안내를 표시합니다.
  • YAML 오류는 경로만 표시하고 행 번호는 표시하지 않습니다.
  • 1 MB를 넘는 입력은 “검증” 버튼으로 실행하고, 20 MB를 넘는 파일은 읽지 않습니다.

샘플 데이터에서 스키마를 만들려면 JSON → JSON Schema, YAML 문법만 확인하려면 YAML 유효성 검사기, API 명세 전체를 검증하려면 OpenAPI 유효성 검사기를 쓰세요.

FAQ

어떤 JSON Schema 드래프트를 지원하나요?

draft-04, draft-06, draft-07, 2019-09, 2020-12입니다. $schema로 드래프트를 판단하고, $schema가 없으면 2020-12로 검증합니다(Python jsonschema, Go santhosh-tekuri/jsonschema와 같은 기본값). 메뉴에서 드래프트를 지정할 수도 있으며, $schema와 다르면 안내를 표시합니다.

입력한 데이터가 서버로 전송되나요?

전송되지 않습니다. 스키마와 데이터는 브라우저 탭 안에서 Ajv가 검증하며, $ref가 가리키는 URL도 내려받지 않습니다. 참조되는 스키마는 "참조되는 스키마" 칸에 붙여넣으세요. 브라우저에는 드래프트 메뉴와 "format 검사" 설정만 저장됩니다.

세 글자 이름이 maxLength 5를 넘는다고 나오는 이유는 무엇인가요?

한글이 NFD(자모 분해) 형태로 들어 있기 때문입니다. maxLength는 유니코드 문자(코드 포인트) 수를 세는데, '홍길동'은 NFC로는 3자, NFD로는 초성·중성·종성으로 나뉘어 9자입니다. macOS 파일 이름에서 복사한 텍스트가 NFD인 경우가 많습니다. 서버에서 NFC로 정규화한 뒤 검증하세요.

format(email, date 등)도 검사하나요?

"format 검사"가 켜져 있으면(기본값) ajv-formats가 구현한 email, uri, date, date-time, time, duration, hostname, ipv4, ipv6, uuid 등 15가지를 검사합니다. idn-email, iri 같은 나머지는 그대로 통과하고 안내에 표시됩니다. 끄면 format은 주석으로만 쓰이며, 2020-12 규격과 Python jsonschema의 기본 동작과 같습니다.

다른 검증기와 결과가 다르면 어느 쪽이 맞나요?

결과 아래의 안내를 먼저 보세요. 흔한 원인은 드래프트 차이, draft-07에서 $ref 옆 키워드(규격상 무시), OpenAPI 3.0의 nullable(JSON Schema 키워드가 아님), format 검사 여부, 2^53을 넘는 정수입니다. 이 도구는 무시한 키워드와 바뀐 숫자를 안내하고, Ajv가 틀리는 것으로 알려진 경우에는 결과 대신 "판정할 수 없음"을 표시합니다.