MYMONDAY.ai
서비스스튜디오도구데이터·포맷73CSS 생성기19색상·이미지10인코딩·보안10웹·SEO11개발·데브옵스10파일·내보내기18계산기6가이드

JSON Schema 검증기

JSON 문서와 스키마를 붙여넣으면 모든 위반 사항을 경로와 함께 보여 주고, 항목을 누르면 문서의 해당 값으로 이동합니다.

  • 브라우저에서 처리
  • 가입 없음
  • 무료

도구 작업 공간

예제

JSON 문서

JSON 스키마

문제 6개

이 검증기는 JSON 문서를 JSON Schema로 검사해서 첫 번째 오류만이 아니라 모든 위반을 나열합니다. 각 항목에는 문제가 된 값의 JSON Pointer 경로, 실패한 키워드, 읽기 쉬운 설명이 들어 있고 항목을 누르면 문서 편집기가 그 값으로 이동합니다. 이미 가진 스키마로 API 페이로드, 설정 파일, 테스트 데이터를 디버깅하는 용도입니다.

draft 04부터 2020-12까지 자주 쓰는 키워드를 평가합니다. 타입, 열거값, 문자열·숫자·배열·객체 제약, allOf/anyOf/oneOf/not, if/then/else, dependentRequired, dependentSchemas, 붙여 넣은 스키마 안의 $ref가 포함됩니다. #/$defs/node 같은 JSON Pointer, $id 기반 URI와 $anchor 이름을 해결합니다. format은 11가지를 검사하고 multipleOf는 부동소수점에 안전해서 0.3은 0.1의 배수로 판정됩니다.

$anchor, $id, $dynamicRef, unevaluatedProperties, unevaluatedItems를 평가하며, 성공한 조합 분기에서 얻은 평가 정보도 반영합니다. 테스트 모음의 원격 스키마를 라이브러리에 사전 등록한 정확성 감사에서 공식 JSON-Schema-Test-Suite의 2020-12 사례 약 98.8%, draft7 사례 99.4%를 통과했지만 완전한 적합성을 뜻하지는 않습니다. 모르는 키워드와 검사하지 않는 format은 참고 메시지에 나오며 외부 스키마를 내려받지는 않습니다. 두 입력은 브라우저 안에만 머뭅니다.

사용 방법

  1. 문서와 스키마 붙여넣기

    JSON 문서 칸에 검사할 JSON을, JSON 스키마 칸에 스키마를 넣거나 예제를 불러옵니다. 각 편집기가 자체 문법 오류를 줄·열과 오류 위치로 이동 버튼과 함께 보여 주며, 메시지에 문서와 스키마 중 어느 쪽이 잘못되었는지 표시됩니다.

  2. 판정 확인

    초록색 유효함 배지는 이 검증기가 평가하는 모든 키워드를 문서가 만족한다는 뜻입니다. 그렇지 않으면 배지에 문제 개수가 표시되고 아래 목록에 항목이 나옵니다.

  3. 문제 항목 읽기

    각 행에는 JSON Pointer 경로((루트)일 수 있음), 실패한 키워드, integer이어야 하는데 string입니다. 같은 설명이 있습니다. 한 값에서 여러 키워드가 실패하면 각각 나열됩니다.

  4. 값으로 이동

    행을 누르면 문서 편집기가 그 경로의 값으로 이동합니다. required는 속성이 빠진 객체로 이동합니다.

  5. 참고 메시지 확인

    참고 메시지에는 평가하지 않은 키워드와 검사하지 않는 format이 나열됩니다. 이 부분은 결과를 더 엄격하게 만들지 않으므로 스키마에서 검증되지 않은 부분으로 취급하세요.

작동 원리

평가하는 키워드

$schema로 이전 draft를 구분합니다. draft-04부터 draft-07까지는 $ref의 형제 키워드를 무시하고 이후 draft에서는 함께 평가합니다. 불리언 exclusive 경계, 튜플 items와 additionalItems, dependencies도 지원합니다. $id는 참조 기준을 정하고 $anchor와 $dynamicAnchor는 대상을 이름으로 지정합니다. title, description, default 같은 주석은 값을 제한하지 않습니다.

분류키워드
모든 값type(타입 목록 포함), enum, const
문자열minLength, maxLength(글자 수 기준), pattern, format
숫자minimum, maximum, exclusiveMinimum, exclusiveMaximum, multipleOf
배열items, prefixItems, additionalItems, minItems, maxItems, uniqueItems, contains, minContains, maxContains, unevaluatedItems
객체required, properties, patternProperties, additionalProperties, minProperties, maxProperties, propertyNames, dependentRequired, dependentSchemas, dependencies, unevaluatedProperties
조합allOf, anyOf, oneOf, not, if, then, else
참조$ref, $id, $anchor, $dynamicAnchor, $dynamicRef, #, #/$defs/x, #/definitions/x

문제를 보고하는 방식

모든 문제를 수집하되 최대 500개까지 기록하고 처음 200개를 목록에 보여 줍니다. 경로는 문서 안의 JSON Pointer이며, required, minProperties 같은 객체 수준 키워드는 그 객체를, additionalProperties와 propertyNames는 문제가 된 속성을 가리킵니다. anyOf와 oneOf는 대안마다가 아니라 자기 경로에 개수와 함께 문제 하나만 만듭니다.

입력 스키마 안의 $id, $anchor, $dynamicAnchor 대상까지 참조를 해결합니다. 대상이 없으면 ref_unresolved 문제이며 다른 스키마를 가져오는 네트워크 요청은 하지 않습니다. $schema로 구분한 이전 draft에서는 $ref의 형제를 무시하고 그 외에는 평가합니다. 중첩 200단계 또는 평가 200,000단계를 넘으면 검사를 멈춥니다.

format과 정규식 방언

검사하는 format은 email, uri, uuid, date, time, date-time, ipv4, ipv6, hostname, regex, json-pointer이며 힌트가 아니라 검증 조건으로 적용됩니다. 검사는 실용적인 수준이며 완전하지는 않습니다. email은 글자, @, 점이 있는 도메인이 필요하고 uri는 스킴이 필요하며 date는 2023-02-29 같은 불가능한 날짜를 거부합니다.

pattern과 patternProperties는 유니코드 플래그를 켠 자바스크립트 정규식을 쓰고 앵커가 자동으로 붙지 않으므로 [0-9]+는 abc123과도 맞습니다. 전체가 일치해야 한다면 ^[0-9]+$로 쓰세요. 올바른 정규식이 아닌 패턴은 문제로 보고됩니다.

실제 예시

한 번에 여러 오류
입력
// data
{"id":"7","email":"x","extra":1,"tags":["a","a"],"age":-1}
// schema
{"type":"object","required":["id","name"],"properties":{"id":{"type":"integer"},"email":{"type":"string","format":"email"},"age":{"type":"integer","minimum":0},"tags":{"type":"array","uniqueItems":true}},"additionalProperties":false}
출력
문제 6개
(루트)  [required]  필수 속성 “name”이(가) 없습니다.
/id  [type]  integer이어야 하는데 string입니다.
/email  [format]  올바른 email 형식이 아닙니다.
/extra  [additionalProperties]  속성 “extra”은(는) 허용되지 않습니다.
/tags  [uniqueItems]  0번과 1번 항목이 같습니다. 항목은 서로 달라야 합니다.
/age  [minimum]  0 이상이어야 합니다.

모든 위반이 나열됩니다. required는 객체를, 나머지 문제는 문제가 된 값을 가리킵니다.

format, multipleOf, 검사하지 않는 format
입력
// data
{"price":0.35,"id":"123e4567-e89b-12d3-a456-42661417400","when":"2023-02-29","ttl":"P1D"}
// schema
{"type":"object","properties":{"price":{"type":"number","multipleOf":0.1},"id":{"type":"string","format":"uuid"},"when":{"type":"string","format":"date"},"ttl":{"type":"string","format":"duration"}}}
출력
문제 3개
/price  [multipleOf]  0.1의 배수여야 합니다.
/id  [format]  올바른 uuid 형식이 아닙니다.
/when  [format]  올바른 date 형식이 아닙니다.
참고: 여기서 검사하지 않는 format은 주석으로만 취급합니다: duration.

0.35는 0.1의 배수가 아니고, uuid는 한 자리가 모자라며, 2023-02-29는 존재하지 않는 날짜입니다. duration format은 검사 방법이 없어서 참고 메시지에만 나옵니다.

재귀하는 로컬 $ref
입력
// data
{"name":"root","children":[{"name":"a","children":[]},{"name":7,"children":[{"name":"c"}]}]}
// schema
{"$ref":"#/$defs/node","$defs":{"node":{"type":"object","required":["name"],"properties":{"name":{"type":"string"},"children":{"type":"array","items":{"$ref":"#/$defs/node"}}}}}}
출력
문제 1개
/children/1/name  [type]  string이어야 하는데 integer입니다.

node 정의가 자기 자신을 참조합니다. 문제는 /children/1/name에서 발견되고, 항목을 누르면 7로 이동합니다.

해결할 수 없는 외부 참조와 사용자 정의 키워드
입력
// data
{"a":1}
// schema
{"$ref":"https://example.com/s.json","customCheck":true}
출력
문제 1개
(루트)  [ref_unresolved]  참조 https://example.com/s.json을(를) 해석할 수 없습니다. 붙여 넣은 스키마 안의 참조(#/$defs/… 같은 JSON Pointer, $id 기반 URI, $anchor 이름, $dynamicRef)는 지원하지만 다른 URL의 스키마는 가져오지 않으므로 참조 대상 스키마를 같은 문서의 $defs 등에 붙여 넣으세요.
참고: 평가하지 않는 키워드(결과를 더 엄격하게 만들지 않습니다): customCheck.

외부 참조의 리소스가 입력에 없어 해결할 수 없습니다. 사용자 정의 키워드는 평가하지 않는 항목으로 나옵니다.

if / then / else
입력
// data
{"country":"US","state":"CA"}
// schema
{"if":{"properties":{"country":{"const":"US"}}},"then":{"required":["zip"]},"else":{"required":["postcode"]}}
출력
문제 1개
(루트)  [required]  필수 속성 “zip”이(가) 없습니다.

if 조건이 맞으므로 then이 적용되고 빠진 zip이 루트에서 보고됩니다.

튜플 items와 additionalItems
입력
// data
[1,"a",true]
// schema
{"items":[{"type":"integer"},{"type":"string"}],"additionalItems":false}
출력
문제 1개
/2  [false_schema]  여기에는 어떤 값도 허용되지 않습니다.

draft-07 방식입니다. 두 위치만 정의되어 있고 나머지는 허용되지 않으므로 인덱스 2가 /2에서 보고됩니다.

자주 하는 실수

  • 유효함이 모든 키워드를 검사했다는 뜻은 아님

    판정은 구현된 검증 키워드에 대한 것이며 unevaluatedProperties, unevaluatedItems, $dynamicRef도 포함됩니다. 모르는 사용자 정의 키워드는 참고 메시지에 나옵니다. contentEncoding, contentMediaType, contentSchema는 주석으로 취급하며 인코딩된 내용을 검증하지 않습니다. 메타스키마 검증, 사용자 정의 어휘와 일부 draft 간 사례는 지원하지 않습니다. 감사에서는 조회 URI가 $id와 다른 경우나 메타스키마가 필요한 참조 등 일부 원격 참조 사례도 통과하지 못했습니다. 테스트 모음은 일부 사례에서 format을 주석으로만 취급하지만 이 도구는 아래의 11가지 format을 검사합니다.

  • 붙여 넣은 스키마 안의 참조를 해결하며 다른 URL은 조회하지 않음

    $ref는 입력 스키마 안의 JSON Pointer, $anchor 이름, $id 리소스를 가리킬 수 있습니다. $dynamicRef는 동적 앵커를 해결합니다. 외부 리소스는 내려받지 않으므로 필요한 정의를 스키마 안에 넣으세요.

  • pattern에는 앵커가 없음

    "pattern": "[0-9]+"는 abc123도 통과시킵니다. 전체가 맞아야 하면 ^와 $를 붙이세요.

  • format은 실용적인 검사

    email은 a@b.co를 받아들이고 a@b를 거부하며, uri는 /path 같은 상대 참조를 거부합니다. 엄격한 RFC 기준 검증기와는 경계 사례에서 다를 수 있고, 검사 방법이 없는 format(duration 등)은 참고 메시지에만 나열됩니다.

  • additionalProperties는 형제 하위 스키마를 보지 않음

    additionalProperties: false는 자기 스키마 객체의 properties와 patternProperties만 압니다. allOf나 $ref 대상 안에서 선언한 속성은 거기서는 추가 속성으로 취급되며 표준이 그렇게 정의합니다.

  • 숫자 자릿수를 잃지 않고 검사

    정밀도를 잃을 숫자는 원문을 보존하므로 2^53을 넘는 정수도 비교나 숫자 제약 검사 전에 반올림하지 않습니다. 1.0은 소수 부분의 값이 없으므로 정수 타입을 만족합니다. 반복된 키는 마지막 값만 남습니다.

자주 묻는 질문

어떤 JSON Schema draft를 지원하나요?

draft-04부터 2020-12까지 지원하는 키워드를 평가하며 앵커, 동적 참조, 미평가 값 제약도 포함됩니다. $schema가 이전 draft의 $ref 형제 처리 방식을 정합니다. 테스트 모음의 원격 스키마를 라이브러리에 사전 등록한 감사에서 공식 2020-12 사례 약 98.8%, draft7 사례 99.4%를 통과했으며 미지원 사례는 남아 있습니다.

평가하지 않는 키워드는 무엇인가요?

모르는 사용자 정의 키워드는 참고 메시지에 나옵니다. contentEncoding, contentMediaType, contentSchema는 내용 검사 없이 주석으로 취급합니다. unevaluatedProperties, unevaluatedItems, $dynamicRef는 평가합니다.

format도 검사하나요?

email, uri, uuid, date, time, date-time, ipv4, ipv6, hostname, regex, json-pointer는 검사합니다. 다른 format은 참고 메시지에 나열되고 주석으로만 취급됩니다.

$ref를 해결하나요?

네. 입력 스키마 안의 JSON Pointer, $anchor 이름, $id 리소스를 해결하며 재귀 참조도 됩니다. $dynamicRef는 동적 앵커를 지원합니다. 외부 스키마는 가져오지 않으며 없는 대상은 해결할 수 없다고 보고합니다.

문서에서 실패한 값을 어떻게 찾나요?

문제 항목을 누르세요. 문서 편집기가 해당 JSON Pointer 경로의 값으로 이동합니다.

오류를 몇 개까지 보여 주나요?

문제는 최대 500개를 기록하고 처음 200개를 목록에 보여 줍니다. 더 있다는 안내는 기록된 문제 중 200개 이후의 개수이며 500개 한도를 넘는 실패는 포함하지 않습니다.

minLength는 이모지를 한 글자로 세나요?

네. 사양대로 UTF-16 단위가 아니라 유니코드 코드 포인트 기준의 글자 수로 세므로 "😀"의 길이는 1입니다.

데이터가 업로드되나요?

업로드하지 않습니다. 두 입력은 브라우저에서 검증하며 각각 최대 20 MiB입니다. 200,000자를 넘는 입력은 worker에서 처리하고 1,000,000자를 넘으면 편집기 대신 크기와 줄 수 요약을 보여 줍니다. 큰 입력에서는 문제를 눌러 해당 값으로 이동할 수 없습니다.

마지막 업데이트: