JSON Schema 검증기

JSON 문서를 JSON Schema(기본 Draft 2020-12)로 검증합니다. 실패 경로와 사유를 표시하며, Ajv로 브라우저 안에서 완전히 처리합니다.

Loading…

모든 처리는 브라우저 내부에서 실행됩니다 — 파일·입력은 서버로 전송되지 않습니다.

사용법

왼쪽에 JSON Schema, 오른쪽에 검증할 JSON 문서를 붙여 넣으세요. 검증기는 Ajv(Another JSON Validator, JS에서 가장 많이 쓰이는 라이브러리)를 `allErrors: true`로 실행해 첫 번째 오류만이 아니라 실패 지점을 모두 보고합니다. 각 에러에는 실패 필드로 가는 JSON Pointer, 거부한 스키마 키워드(`required`·`type`·`minLength`·`format` 등), 사람이 읽을 수 있는 메시지가 포함됩니다. 검증은 입력에 따라 실시간으로 실행되므로 붙여 넣고 편집하면서 에러가 사라지고 나타나는 모습을 볼 수 있습니다.

API 계약 설계, 공개된 스키마에 대한 샘플 페이로드 검증, 웹훅 수신 측이 본문을 계속 거부하는 원인 추적에 사용하세요. 이 도구는 `ajv-formats`를 포함해 표준 포맷 체크(`email`·`date-time`·`uri`·`uuid`·`ipv4`·`regex`)가 즉시 동작합니다. 스키마와 데이터는 브라우저 밖으로 나가지 않습니다. 사내 필드명이나 개인정보가 들어간 페이로드에도 안심하고 쓸 수 있습니다. 런타임에 자체 코드에서 쓸 때도 같은 Ajv 라이브러리가 다수의 서버 측·CLI 검증기(`ajv-cli`·NestJS의 validation pipe·Fastify의 스키마 등)를 구동합니다.

예제

기본 사용자 객체 검증

입력
schema:
{
  "type": "object",
  "required": ["id", "email"],
  "properties": {
    "id":    { "type": "integer", "minimum": 1 },
    "email": { "type": "string", "format": "email" },
    "tags":  { "type": "array", "items": { "type": "string" }, "uniqueItems": true }
  }
}

data:
{ "id": 1, "email": "[email protected]", "tags": ["admin", "founder"] }
출력
✓ valid

스키마는 1 이상의 정수 `id`와 email 형식의 `email`을 필수로 두고, `tags`는 선택이지만 있다면 고유한 문자열 배열이어야 합니다. 데이터는 세 조건을 모두 충족하므로 검증이 문제없이 통과합니다. email을 `"alice"`로 바꾸면 `format` 키워드가 실패하고, `id`를 빼면 `required`가 문제를 알려 줍니다.

여러 에러를 한 번에 표시

입력
schema: (same as above)

data:
{ "id": -3, "email": "not-an-email", "tags": ["a", "a"] }
출력
✗ 3 errors
/id     minimum  must be >= 1
/email  format   must match format "email"
/tags   uniqueItems  must NOT have duplicate items (items ## 1 and 0 are identical)

`allErrors: true` 덕분에 첫 실패에서 멈추지 않고 모든 위반이 한 번에 드러납니다. JSON Pointer(`/id`·`/tags` 같은)가 실패 필드를 정확히 가리키고, `keyword` 열이 어떤 스키마 규칙이 실패했는지 알려 주므로 스키마 소스를 grep으로 빠르게 찾아갈 수 있습니다.

`$ref`와 `$defs`가 포함된 스키마

입력
schema:
{
  "$defs": {
    "Address": {
      "type": "object",
      "required": ["city"],
      "properties": { "city": { "type": "string" }, "zip": { "type": "string", "pattern": "^[0-9]{5}$" } }
    }
  },
  "type": "object",
  "properties": {
    "home":   { "$ref": "#/$defs/Address" },
    "office": { "$ref": "#/$defs/Address" }
  }
}

data:
{ "home": { "city": "Seoul" }, "office": { "city": "Tokyo", "zip": "100-0001" } }
출력
✗ 1 error
/office/zip  pattern  must match pattern "^[0-9]{5}$"

`$defs`(2019-09 이전에는 `definitions`)는 재사용 가능한 서브 스키마를 보관하고, `$ref`가 그것들을 JSON Pointer로 가져옵니다. 도쿄 우편번호 `100-0001`은 일본 형식(하이픈 포함)이지만 스키마는 미국 5자리 형식을 강제합니다. 패턴을 완화하거나(`^[0-9-]{5,8}$`) 미국용·일본용 두 주소 스키마를 `oneOf`로 구성하는 둘 중 하나입니다.

자주 묻는 질문

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

이 도구가 채택한 Ajv 8의 기본은 Draft 2020-12로 2026년 중반 기준 최신 공개 드래프트입니다. 스키마 첫머리의 `$schema` 선언을 적절히 설정하면 Draft 2019-09·07·06도 읽습니다. 07과 2019-09 사이의 큰 변화는 `definitions`를 `$defs`로 개명한 것, `$anchor` 추가, `$ref`와 형제 키워드의 관계 정리입니다. 도구 체인이 지금도 Draft 07을 출력한다면 `"$schema": "http://json-schema.org/draft-07/schema#"`를 지정하면 검증기가 모드를 전환합니다.

JSON Schema와 OpenAPI의 관계는?

OpenAPI는 요청·응답 본문이나 파라미터의 타입 시스템에 JSON Schema를 채택하지만 단서가 있습니다. OpenAPI 3.0은 Draft Wright-00의 *부분 집합*에 자체 확장(`nullable`·`discriminator`·`xml` 등)을 더한 형태입니다. OpenAPI 3.1(2021년 5월)은 JSON Schema 2020-12와 완전히 정렬됩니다. 그러니까 3.0 스키마는 대체로 이식 가능하지만 엄격한 JSON Schema는 아니며, 3.1 스키마는 그대로 검증됩니다. 이행 시 대표적인 함정은 `nullable: true`(`type: [..., "null"]`로 대체)와 `example` 폐지(배열 `examples`로 대체)입니다.

`format: "email"`은 실제로 무엇을 검증하나요?

실용적인 정규식으로 문자열 구문을 검사할 뿐 RFC 5321 완전 준수를 확인하지는 않습니다. 사람이 일상적으로 입력하는 주소 대부분은 통과합니다. 일부 드물지만 합법적인 형태(`"hello world"@example.com` 같은 인용 로컬 부분, IP 리터럴 호스트 등)는 거부됩니다. JSON Schema는 `format`을 일부러 반쯤 정의해 두어 구현마다 엄격도를 고를 수 있게 했습니다. "전형적인 email 같은 형태"로 보는 편이 적절하며, "실재하고 배달 가능한 주소"를 확인하려면 실제 메일을 보내고 바운스를 확인하는 수밖에 없습니다.

에러 메시지가 없는 경로를 가리키는 이유는?

흔한 원인이 두 가지입니다. `additionalProperties: false`에서 예기치 않은 필드가 나타나면 알 수 없는 필드 경로가 아니라 부모 경로에 대한 에러로 표시됩니다. 검증기가 그 필드를 무엇으로 부를지 모르기 때문입니다. `anyOf`·`oneOf`에서는 실패한 각 브랜치에 대해 에러가 보고되므로 한 건의 잘못된 값이 3~4 행의 에러를 만들고 각각이 같은 자리를 다른 각도로 가리킬 수 있습니다. `keyword` 열을 읽어 자신이 실제로 만족시키고 싶었던 브랜치를 찾으세요.

스키마에서 샘플 데이터를 생성할 수 있나요?

아니요. 이 도구는 검증 전용입니다. 스키마에서 목 데이터 생성은 별도의 문제(`json-schema-faker`·`Mockoon`·`jsf` CLI 등)이며 합리적인 기본값 추정, 제약 내 난수화, `enum`·`format`의 영리한 처리 같은 것이 얽힙니다. 검증은 통과하지만 실제로 만족하는 값이 없는 스키마(예: `not: { type: "string" }`은 문자열 외 모든 것을 받음)도 있고, 좋은 생성기는 이를 우아하게 처리합니다.

strict 모드가 꺼져 있는데 영향이 있나요?

Ajv의 strict 모드는 알 수 없는 키워드나 허용되지 않은 구문(문자열이 아닌 `type`에 대한 `format` 키워드 등)을 가진 스키마를 거부합니다. 이 도구는 strict를 꺼서 실행하므로 더 느슨한 명세로 작성된 스키마(초기 드래프트, OpenAPI 전용 확장이 든 스키마, 손으로 짠 단축형 등)도 받아들입니다. 대가는 키워드명 오타가 감지되지 않는다는 점입니다. `required`를 `requried`로 적어도 조용히 아무 일도 하지 않습니다. 신규 스키마를 작성할 때는 자체 코드에서 별도로 Ajv strict 모드를 거치세요.

관련 개념

JSON Schema는 JSON 데이터의 "모양"을 기술하기 위한 어휘입니다. 어떤 필드가 필요한지, 어떤 타입을 가질 수 있는지, 어떤 값이 허용되는지, 배열은 어떻게 생겨야 하는지 같은 것들입니다. 사양 드래프트는 2026년 기준 Draft 2020-12에서 *멈춰* 있고, 2022년에 표준화 트랙이 IETF로 옮겨졌지만 현재까지 공식 RFC는 나오지 않았습니다. 그럼에도 주요 생태계(Ajv·Python의 jsonschema·Swagger·OpenAPI 3.1·AWS API Gateway·JSON Forms 등)는 2020-12나 그 전임인 2019-09를 구현합니다. 옛 코드는 여전히 2018년의 준 LTS 체크포인트였던 Draft 07을 참조하기도 합니다.

어휘는 크게 4 영역을 다룹니다. **구조**: `type`·`properties`·`required`·`items`·`additionalProperties`·`patternProperties`. **제약**: `minimum`·`maximum`·`minLength`·`maxLength`·`pattern`·`uniqueItems`·`enum`·`const`. **합성**: `allOf`(모두 만족)·`anyOf`(최소 1개)·`oneOf`(정확히 1개)·`not`·`if·then·else`. **재사용**: 명명 서브 스키마용 `$defs`, JSON Pointer나 절대 URI로 참조하는 `$ref`, 안정된 명명 대상을 만드는 `$anchor`. 실운영 스키마에서 쓰이는 키워드는 총 5~10개 정도이며, 롱테일은 주로 명세 자체의 자기 기술과 엣지 케이스를 위해 존재합니다.

인접한 3가지 개념이 있습니다. **OpenAPI**(이전 명칭 Swagger)는 JSON Schema를 HTTP API 기술 형식으로 감싼 것이며 3.1이 완전 일치, 3.0은 분기된 부분 집합입니다. **TypeScript 타입**은 컴파일 시점에 비슷한 영역을 다루지만 런타임 측은 브리지(`zod`·`io-ts`·`runtypes`·`valibot`·`typia` 등)가 필요합니다. TypeScript는 컴파일 시점에 소거되기 때문입니다. **Protocol Buffers**와 **GraphQL SDL**은 같은 문제를 다른 구문으로 풉니다. protobuf는 스키마 + 바이너리 와이어 포맷, GraphQL은 스키마 + 쿼리 언어 접근입니다. JSON Schema가 이기는 자리는 이미 JSON을 다루고 있어 전송 계층을 다시 쓰지 않고 검증을 얹고 싶을 때입니다.

관련 글

관련 도구