유효성 체크

X2BEE 솔루션에서 Zod 라이브러리를 사용해 데이터 유효성을 검증합니다. 본 가이드는 스키마 정의, 필드별 유효성 검증, 전체 데이터 검증, 데이터 가공 및 타입 추론을 효율적으로 구현하는 방법을 설명합니다.


1

Zod 스키마 정의 방법

Zod는 TypeScript를 우선으로 하는 스키마 선언 및 유효성 검증 라이브러리이며, 중복된 유형 선언을 제거하기 위해 사용됩니다. Zod를 통해 유효성 검사를 하고 TypeScript 유형을 추론할 수 있습니다.

예시: 기본 객체 스키마
import { z } from 'zod'

/** 기본적인 zod 객체 선언은 내부에 object 함수를 이용하여 객체를 생성하고 반환해줄 수 있습니다.
    Argument로 객체를 던져주면 상수 형태의 zod schema를 사용할 수 있습니다.
    Argument로 전달하는 객체의 경우 각 필드를 정의하고 타입을 zod의 타입으로 정의해줘야 합니다.
**/
const zodExampleSchema = z.object({
  name: z.string(),
  userId: z.string(),
  password: z.string(),
  phone: z.number()
})
2

각 필드별 유효성 체크 방법

Zod만으로는 일부 자유도 높은 검증에 제한이 있으므로, 각 항목에 대해 refine를 사용한 필드별 커스텀 검증을 적용할 수 있습니다. 아래는 빈 값 체크 등 기본적인 검증 예시입니다.

예시: refine를 이용한 필드 검증
import { z } from 'zod'

/** min, max 등 다양한 기본 검증 방식들이 존재하지만,
    자유도 있는 검증을 위해 zod의 refine를 이용할 수 있습니다.
    refine의 첫번째 인자는 검증 통과 여부(boolean)를 반환하는 함수,
    두번째 인자는 메시지 등의 옵션입니다.
**/
const zodExampleSchema = z.object({
  name: z.string().refine(
    (data) => !!data, // data는 name 필드의 값을 의미 (boolean 반환)
    {
      message: "이름을 입력해주세요."
    }
  ),
  userId: z.string(),
  password: z.string(),
  phone: z.number()
})
3

전체 필드를 대상으로 한 유효성 체크 방법

필드 간 참조가 필요한 검증(예: 비밀번호와 비밀번호 확인 일치 여부)은 개별 필드의 refine로는 어려우므로, object 레벨에서 superRefine를 사용합니다. superRefine는 전체 데이터 객체와 컨텍스트를 받아 복합 검증을 수행할 수 있습니다.

예시: superRefine를 이용한 전체 필드 검증
import { z } from 'zod'

/** superRefine는 z.object에 적용되는 함수로,
    첫번째 인자는 전체 필드 데이터를 가진 객체,
    두번째 인자는 zod의 context(ctx) 입니다.
**/
const zodExampleSchema = z.object({
  userId: z.string(),
  password: z.string(),
  rePassword: z.string()
}).superRefine((data, ctx) => {
  if (data.password !== data.rePassword) {
    ctx.addIssue({
      message: "비밀번호가 일치하지 않습니다.",
      code: z.ZodIssueCode.custom,
      path: ['password']
    })
    return false
  }
  return true
})
4

최종 스키마 데이터 가공 방법

검증 후 반환되는 데이터를 변환하거나 불필요한 필드를 제거하는 등 스키마 레벨에서 데이터를 가공하려면 transform을 사용합니다. transform은 검증이 통과된 후 최종값으로 변환된 객체를 반환합니다. 필요하다면 transform 전에 데이터를 가공하고 superRefine로 검증할 수도 있습니다.

예시: superRefine + transform
import { z } from 'zod'

/** 아래 예시는 아이디 비어있음 체크, 비밀번호 확인 검사 후
    transform로 최종 반환값을 가공하는 예시입니다.
**/
const zodExampleSchema = z.object({
  userId: z.string().refine(
    (data) => !!data,
    { message: "아이디를 입력해주세요." }
  ),
  password: z.string(),
  rePassword: z.string()
}).superRefine((data, ctx) => {
  if (data.password !== data.rePassword) {
    ctx.addIssue({
      message: "비밀번호가 일치하지 않습니다.",
      code: z.ZodIssueCode.custom,
      path: ['password']
    })
    return false
  }
  return true
}).transform((data) => {
  return {
    userId: data.userId,
    password: data.password
  }
})
5

타입 추론 방법

Zod 스키마로부터 TypeScript 타입을 추론하려면 z.infer를 사용합니다.

예시: z.infer로 타입 추론
import { z } from 'zod'

/** Typescript 변환 예시 **/
const zodExampleSchema = z.object({
  // ...스키마 정의
})

// Typescript type
type zodExampleType = z.infer<typeof zodExampleSchema>

마지막 업데이트