Yup 라이브러리를 이용한 validation 검증

Yup 라이브러리를 이용한 validation 검증

들어가기에 앞서

이 글은 Yup의 자세한 사용법을 다루지 않습니다. 자세한 내용은 공식문서를 참고 바랍니다. 이 글에서는 기본적인 사용법을 정리하며 이 중 착각하거나, 놓치고 지나가기 쉬운 부분에 대해 다루고자 합니다.

Yup 이란

Yup은 모델의 스키마를 정의할 수 있도록 하며, 유효 값 검증(validation), 형 변환(parsing), 원하는 값으로 조작(transformation)등의 기능을 제공하는 라이브러리 입니다. 이를 통해 더욱 안정성 있는 어플리케이션의 설계와 구현이 가능합니다.

Yup 사용법

객체의 프로퍼티의 타입으로 사용할 수 있는 타입 중에서 주로 사용되는 아래 다섯 가지에 대해 다루도록 하겠습니다.

  • string
  • number
  • boolean
  • date
  • array

타입 지정

기본적으로 아래와 같은 방식으로 각각의 프로퍼티의 타입을 지정해 줄 수 있습니다.

const basicSchema = object({
  str: string(),
  num: number(),
  bool: boolean(),
  date: date(),
  arr: array(), // array().of(number()) 또는 array(number())와 타입 지정 가능
});

당 스키마를 사용하여 validation 오류를 체크할 경우 에러가 발생하는 경우는 이와 같습니다.

  • null 값을 갖는 경우
  • 타입에 맞지 않는 값을 가진 경우(다만 지정한 타입으로 파싱이 가능한 값의 경우 에러가 발생하지 않습니다.)
// 성공
await basicSchema.validate({ str: undefined });
await basicSchema.validate({ str: '' });
await basicSchema.validate({ str: '문자열' });
await basicSchema.validate({ str: new Date() });

// 실패
await basicSchema.validate({ str: null });
await basicSchema.validate({ str: [] });

그런데 주의해야 할 점이 있습니다. 스키마에서 정의한 프로퍼티가 검증하고자 하는 객체에 존재하지 않아도 에러는 발생하지 않습니다. 극단적으로 아래와 같은 경우에도 에러는 발생하지 않습니다.

// 성공
await basicSchema.validate({});

해당 프로퍼티가 가진 값이 유효한지만 체크하기 때문입니다. 위 경우를 피하고자 한다면 아래 소개할 defined() 또는 required()와 함께 사용합니다.

defined()

defined()를 사용 시, 스키마에 정의한 property는 검증하고자 하는 객체에 반드시 존재해야 합니다. 또한 값은 null, undefined 일 수 없습니다. 해당 프로퍼티는 말 그대로 defined 된 유효한 값을 가지고 있어야 하는 것 입니다.

const definedSchema = object({
  str: string().defined(),
});

// 성공
await definedSchema.validate({ str: '' });
await definedSchema.validate({ str: '문자열' });

// 실패
await definedSchema.validate({});
await definedSchema.validate({ str: null });
await definedSchema.validate({ str: undefined });

required()

required()가 지정된 경우 해당 프로퍼티는 반드시 유효한 값을 가지고 있어야 합니다. defined()의 역할과 동일하다고 볼 수 있지만, string 타입에 사용된 경우 빈 문자열을 허용하지 않는다는 한 가지 조건이 더 붙습니다.

const requiredSchema = object({
  str: string().required(),
});

// 성공
await requiredSchema.validate({ str: '문자열' });

// 실패
await requiredSchema.validate({});
await requiredSchema.validate({ str: '' }); // <- 빈 문자열의 경우 에러발생
await requiredSchema.validate({ str: null });
await requiredSchema.validate({ str: undefined });

nullable()

스키마에 타입이 정의된 프로퍼티의 경우 값으로 null을 가질 수 없습니다. 만약 null 값을 허용해야 하는 프로퍼티의 경우 nullable()를 사용합니다.

const nullableSchema = object({
  str: string().nullable(),
});

// 성공
await nullableSchema.validate({})
await nullableSchema.validate({ str: null })

nullable()은 해당 프로퍼티의 유효한 값으로 null을 허용한 것입니다. 아래와 같이 defined() 또는 required()와 함께 사용할 수 있습니다.

const nullableSchema2 = object({
  str: string().defined().nullable(),
});

// 성공
await nullableSchema.validate({ str: null })

// 실패
await nullableSchema2.validate({})

Typescript 사용

Yup은 라이브러리 특성상 타입스크립트와 함께 사용하면 더욱 효과적입니다. 아래와 같이 정의한 스키마를 interface가 상속하여 사용할 수 있습니다. 만약 스키마로 관리할 필요성이 떨어지는 프로퍼티의 경우 interface에 정의해 타입을 관리하는 방법도 고려할 수 있습니다.

const typescriptSchema = object({
  str: string().required(),
  num: number().defined(),
  date: date().defined().nullable(),
  bool: boolean().default(false),
})

interface Types extends InferType<typeof typescriptSchema> {
  arr?: Array<number>;
}

const obj: Types = {
  str: '문자열',
  num: 12,
  date: new Date(),
  bool: false
}

디지엠유닛원 주식회사

  • 대표이사 권혁태
  • 개인정보보호책임자 정경영
  • 사업자등록번호 252-86-01619
  • 주소
    서울특별시 금천구 가산디지털1로 83, 6층 601호(가산동, 파트너스타워)
  • 이메일 web@dgmit.com