JSON Schema란?
JSON Schema는 JSON 데이터의 구조, 타입, 제약 조건을 정의하는 명세서입니다. 특정 JSON 객체가 어떤 형태를 가져야 하는지를 기술하여 데이터의 유효성을 검증할 수 있게 해줍니다.
프론트엔드 개발에서는 API 응답 데이터 검증, 설정 파일 구조 정의, 폼 데이터 유효성 검사 등 다양한 상황에서 활용됩니다. JSON Schema를 통해 런타임에서 발생할 수 있는 데이터 관련 오류를 사전에 방지하고, 개발 도구와 연동하여 생산성을 높일 수 있습니다.
핵심 개념
1. 스키마 구성 요소
JSON Schema는 다양한 키워드를 통해 데이터 구조를 정의합니다:
// 사용자 정보 스키마 정의
const userSchema = {
type: "object",
properties: {
id: { type: "number" },
username: {
type: "string",
minLength: 3,
maxLength: 20
},
email: {
type: "string",
format: "email"
},
age: {
type: "number",
minimum: 18,
maximum: 120
},
tags: {
type: "array",
items: { type: "string" },
uniqueItems: true
}
},
required: ["id", "username", "email"],
additionalProperties: false
};
// 검증 예시 데이터
const userData = {
id: 123,
username: "john_doe",
email: "john@example.com",
age: 25,
tags: ["developer", "typescript"]
};
2. 데이터 검증 구현
실제 프로젝트에서 JSON Schema를 활용한 검증 구현 방법입니다:
import Ajv from 'ajv';
import addFormats from 'ajv-formats';
// AJV 인스턴스 생성 및 포맷 추가
const ajv = new Ajv();
addFormats(ajv);
// 스키마 컴파일
const validateUser = ajv.compile(userSchema);
// API 응답 검증 함수
async function fetchUserWithValidation(userId: number) {
try {
const response = await fetch(`/api/users/${userId}`);
const userData = await response.json();
// 스키마 검증
if (!validateUser(userData)) {
console.error('검증 실패:', validateUser.errors);
throw new Error('Invalid user data structure');
}
return userData as User; // 타입 안전성 확보
} catch (error) {
console.error('사용자 데이터 조회 실패:', error);
throw error;
}
}
// 폼 데이터 검증
function validateFormData(formData: unknown) {
if (validateUser(formData)) {
return { isValid: true, data: formData, errors: null };
}
return {
isValid: false,
data: null,
errors: validateUser.errors
};
}
3. TypeScript 타입 자동 생성
JSON Schema로부터 TypeScript 타입을 자동 생성하여 개발 효율성을 높입니다:
// json-schema-to-typescript 사용 예시
import { compile } from 'json-schema-to-typescript';
// 스키마에서 TypeScript 인터페이스 생성
const userInterface = await compile(userSchema, 'User');
// 생성된 타입 (예시)
interface User {
id: number;
username: string;
email: string;
age?: number;
tags?: string[];
}
// API 클라이언트에서 활용
class UserApiClient {
async getUser(id: number): Promise<User> {
const response = await fetch(`/api/users/${id}`);
const data = await response.json();
// 런타임 검증 + 컴파일 타임 안전성
if (!validateUser(data)) {
throw new Error('Invalid user data');
}
return data; // User 타입으로 안전하게 반환
}
}
4. 설정 파일과 개발 도구 연동
JSON Schema는 설정 파일의 구조를 정의하여 IDE 지원을 향상시킵니다:
// package.json에서 스키마 참조
{
"$schema": "https://json.schemastore.org/package.json",
"name": "my-project",
"version": "1.0.0",
"dependencies": {
// IDE가 자동 완성과 검증 제공
}
}
// 프로젝트 설정 스키마 정의
const configSchema = {
type: "object",
properties: {
apiUrl: { type: "string", format: "uri" },
debug: { type: "boolean" },
features: {
type: "object",
properties: {
analytics: { type: "boolean" },
notifications: { type: "boolean" }
},
additionalProperties: false
}
},
required: ["apiUrl"]
};
// 설정 로더 함수
function loadConfig(configPath: string) {
const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
const validate = ajv.compile(configSchema);
if (!validate(config)) {
throw new Error(`Invalid config: ${ajv.errorsText(validate.errors)}`);
}
return config;
}
정리
JSON Schema는 프론트엔드 개발에서 데이터 안전성과 개발 생산성을 높이는 핵심 도구입니다:
| 영역 | 활용 방법 | 장점 |
|---|---|---|
| API 통신 | 응답 데이터 구조 검증 | 런타임 오류 방지, 타입 안전성 |
| 타입 생성 | Schema → TypeScript 자동 변환 | 개발 시간 단축, 일관성 보장 |
| 설정 관리 | 설정 파일 구조 정의 | IDE 지원, 설정 오류 방지 |
| 폼 검증 | 입력 데이터 유효성 검사 | 사용자 경험 개선, 데이터 품질 향상 |
JSON Schema를 통해 명확한 데이터 계약을 정의하고, 런타임 검증과 컴파일 타임 안전성을 모두 확보할 수 있습니다. 특히 TypeScript와 결합하면 더욱 강력한 타입 안전성을 제공하여 안정적인 프론트엔드 애플리케이션 개발을 지원합니다.