JSON Schema 생성기 - JSON 데이터에서 스키마 생성 온라인
API 유효성 검사, 문서화, 코드 생성을 위한 JSON Schema를 JSON 데이터에서 생성합니다. Draft-04, Draft-07, 2020-12 지원 — 100% 클라이언트 사이드, 서버로 데이터 전송 없음.
자주 묻는 질문
JSON Schema Generator란 무엇인가요?
JSON Schema Generator는 샘플 JSON 데이터에서 자동으로 JSON Schema 정의를 생성하는 도구입니다. JSON Schema는 JSON 문서의 구조, 타입, 제약 조건을 설명하는 표준 어휘(json-schema.org에서 정의)입니다. 스키마 정의를 수동으로 작성하는 대신, JSON 예시를 붙여넣기만 하면 객체 속성, 데이터 타입, 필수 필드, 배열 항목 타입, 날짜와 이메일 같은 문자열 형식을 포함한 올바른 스키마를 추론합니다.
JSON 데이터에서 JSON Schema를 어떻게 생성하나요?
왼쪽 입력 필드에 JSON 데이터를 붙여넣으세요. 도구가 즉시 오른쪽 출력 패널에 JSON Schema를 생성합니다. 스키마 드래프트 버전(Draft-04, Draft-07, 2020-12) 선택, 필수 필드 감지 토글, 날짜와 이메일 같은 패턴의 문자열 형식 감지 활성화, 추가 속성 허용 여부 제어로 출력을 사용자 정의할 수 있습니다. 만족스러우면 '복사'를 클릭하여 스키마를 복사하거나 '다운로드'로 .schema.json 파일로 저장하세요.
이 도구를 사용할 때 JSON 데이터가 안전한가요?
네, 완전히 안전합니다. 이 도구는 클라이언트 측 JavaScript를 사용하여 브라우저에서 모든 것을 처리합니다. JSON 데이터가 절대 컴퓨터를 떠나지 않습니다 — 서버 업로드, API 호출, 데이터 저장이 없습니다. 따라서 민감한 API 응답, 독점 데이터 스키마, 기밀 설정 파일에도 안전하게 사용할 수 있습니다.
어떤 JSON Schema 드래프트 버전을 사용해야 하나요?
생태계에 따라 선택하세요: Draft 2020-12(기본값)는 최신 안정 표준이며 OpenAPI 3.1에서 사용됩니다. Draft-07은 검증 라이브러리와 도구에서 널리 지원되며 최대 호환성을 위한 안전한 선택입니다. Draft-04는 레거시 시스템과 OpenAPI 3.0 호환성에 필요합니다. 확실하지 않다면 새 프로젝트에는 2020-12, 넓은 라이브러리 지원에는 Draft-07로 시작하세요.
도구는 필수 필드를 어떻게 결정하나요?
기본적으로 도구는 생성된 스키마에서 모든 non-null 속성을 필수로 표시합니다. null 값을 가진 필드는 해당 필드가 없거나 선택 사항일 수 있음을 시사하므로 required 배열에서 제외됩니다. 필수 제약 조건 없는 스키마를 선호하는 경우 이 동작을 완전히 끌 수 있으며, 문서 전용 스키마에 유용합니다.
도구는 어떤 문자열 형식을 감지하나요?
형식 감지가 활성화되면 도구가 문자열 값을 분석하여 인식된 패턴에 대해 'format' 키워드를 자동으로 추가합니다: date-time(ISO 8601 타임스탬프, 예: '2024-01-15T10:30:00Z'), date('2024-01-15'), time('10:30:00'), 이메일 주소, URI/URL, UUID, IPv4 주소, IPv6 주소. 이를 통해 기본 타입 정보를 넘어 스키마를 풍부하게 하고 형식 인식 유효성 검사를 가능하게 합니다.
'추가 속성' 옵션은 무엇을 하나요?
JSON Schema의 'additionalProperties' 키워드는 객체에 스키마에 나열되지 않은 속성을 포함할 수 있는지 여부를 제어합니다. '허용'(기본값)으로 설정하면 생성된 스키마가 추가 필드를 허용합니다 — 유연한 API에 유용합니다. '거부'로 설정하면 객체 스키마에 '"additionalProperties": false'를 추가하여 예상치 못한 필드를 거부하는 엄격한 계약을 만듭니다. 오타와 알 수 없는 필드를 잡으려는 API 요청 유효성 검사에 '거부'를 사용하세요.
코드 예제
// JSON to JSON Schema generator
function jsonToSchema(json, options = {}) {
const { draft = '2020-12', includeRequired = true, detectFormats = true } = options;
const schemaUri = {
'draft-04': 'http://json-schema.org/draft-04/schema#',
'draft-07': 'http://json-schema.org/draft-07/schema#',
'2020-12': 'https://json-schema.org/draft/2020-12/schema',
}[draft];
function inferSchema(value) {
if (value === null) return { type: 'null' };
if (typeof value === 'boolean') return { type: 'boolean' };
if (typeof value === 'number') {
return { type: Number.isInteger(value) ? 'integer' : 'number' };
}
if (typeof value === 'string') {
const schema = { type: 'string' };
if (detectFormats) {
if (/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}/.test(value)) schema.format = 'date-time';
else if (/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)) schema.format = 'email';
else if (/^https?:\/\//.test(value)) schema.format = 'uri';
}
return schema;
}
if (Array.isArray(value)) {
if (value.length === 0) return { type: 'array', items: {} };
const itemSchemas = value.map(inferSchema);
const unique = dedup(itemSchemas);
return { type: 'array', items: unique.length === 1 ? unique[0] : { oneOf: unique } };
}
if (typeof value === 'object') {
const properties = {};
const required = [];
for (const [key, val] of Object.entries(value)) {
properties[key] = inferSchema(val);
if (includeRequired && val !== null) required.push(key);
}
const schema = { type: 'object', properties };
if (required.length > 0) schema.required = required;
return schema;
}
return {};
}
function dedup(schemas) {
const seen = new Map();
for (const s of schemas) {
const key = JSON.stringify(s);
if (!seen.has(key)) seen.set(key, s);
}
return [...seen.values()];
}
const parsed = JSON.parse(json);
return { $schema: schemaUri, ...inferSchema(parsed) };
}
// Usage
const json = '{"name":"Alice","age":30,"email":"alice@example.com"}';
console.log(JSON.stringify(jsonToSchema(json), null, 2));