메인 콘텐츠로 건너뛰기
Deep Thought
← 목록으로
Frontend

JSON Schema를 활용한 데이터 검증과 타입 안전성

신중선-- views
json-schemadata-validationtypescriptapi-contract

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와 결합하면 더욱 강력한 타입 안전성을 제공하여 안정적인 프론트엔드 애플리케이션 개발을 지원합니다.

References