Zod와 객체지향 프로그래밍: 클래스 및 상속을 통한 검증 로직 구조화 방법

Zod와 객체지향 프로그래밍의 통합

Zod는 타입스크립트 중심의 데이터 스키마 검증 라이브러리로, 선언식 방식으로 데이터 구조와 검증 규칙을 정의할 수 있습니다. 이 가이드에서는 객체지향 프로그래밍 원칙과 Zod를 결합하여 유지보수성과 확장성을 극대화하는 검증 시스템을 설계하는 방법을 다룹니다.

Zod 기반 검증 패턴

Zod의 핵심은 Schema 클래스입니다. 다양한 검증기들은 이 기본 클래스를 상속하여 구현됩니다:


export abstract class Schema<Output = any, Input = Output, Def extends TypeDef = TypeDef> {
  readonly _def: Def;
  constructor(def: Def) {
    this._def = def;
  }
  
  parse(data: unknown): Output {
    // 검증 로직
  }
}

검증 기반 클래스 설계

공통 검증 로직을 포함한 기본 클래스를 생성합니다:


class ValidationBase {
  protected ruleSet: z.ZodSchema;
  
  constructor(rules: z.ZodSchema) {
    this.ruleSet = rules;
  }
  
  validate(input: unknown) {
    const result = this.ruleSet.safeParse(input);
    if (!result.success) {
      throw new Error(`검증 실패: ${JSON.stringify(result.error)}`);
    }
    return result.data;
  }
}

상속을 통한 기능 확장

특정 도메인에 맞춘 검증 로직을 추가합니다:


class UserValidator extends ValidationBase {
  constructor() {
    super(
      z.object({
        username: z.string().min(3, '아이디는 최소 3자여야 합니다'),
        emailAddress: z.string().email('잘못된 이메일 형식'),
        birthYear: z.number().positive('년도는 양수여야 합니다')
      })
    );
  }
  
  sanitize(input: unknown) {
    const data = this.validate(input);
    return { ...data, username: data.username.trim() };
  }
}

복합 검증 시스템 구축

다중 검증 클래스를 조합하여 복잡한 구조를 처리합니다:


class AddressValidator extends ValidationBase {
  constructor() {
    super(
      z.object({
        street: z.string(),
        city: z.string(),
        postalCode: z.string().regex(/^[0-9]{5}$/, '올바른 우편번호가 아닙니다')
      })
    );
  }
}

class ExtendedUserValidator extends UserValidator {
  private addressValidator: AddressValidator;
  
  constructor() {
    super();
    this.addressValidator = new AddressValidator();
  }
  
  validateWithAddress(input: unknown) {
    const userData = super.validate(input);
    if (userData.address) {
      userData.address = this.addressValidator.validate(userData.address);
    }
    return userData;
  }
}

설계 패턴 적용 가이드

  1. 단일 책임 원칙: 각 검증 클래스는 특정 데이터 유형만 담당
  2. 개방/폐쇄 원칙: 기존 코드 수정 없이 기능 확장 가능
  3. 의존성 주입: 관련 검증기들을 외부에서 주입
  4. 오류 처리 표준화: 공통 오류 처리 메커니즘 구현

Zod의 소스코드에서 Schema 클래스 구조를 분석하면 검증 시스템 설계에 대한 많은 통찰을 얻을 수 있습니다.

태그: Zod TypeScript 객체지향 검증패턴 클래스상속

6월 18일 20:49에 게시됨