Yup vs Zod - maeng2418/zzik-meok GitHub Wiki

Yup๊ณผ Zod ๋น„๊ต

Yup๊ณผ Zod๋Š” ๋ชจ๋‘ JavaScript/TypeScript์—์„œ ๋ฐ์ดํ„ฐ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ์œ„ํ•œ ์Šคํ‚ค๋งˆ ๊ธฐ๋ฐ˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค. ๋‘˜ ๋‹ค ํผ ๊ฒ€์ฆ, API ๋ฐ์ดํ„ฐ ๊ฒ€์ฆ, ๋Ÿฐํƒ€์ž„ ํƒ€์ž… ๊ฒ€์‚ฌ ๋“ฑ์— ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

๊ณตํ†ต์ 

  • ์Šคํ‚ค๋งˆ ๊ธฐ๋ฐ˜ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์ œ๊ณต
  • ์ฒด์ด๋‹ API ์ง€์›
  • React Hook Form, Formik ๋“ฑ ํผ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ํ†ตํ•ฉ ๊ฐ€๋Šฅ
  • ๋ณต์žกํ•œ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ ๊ฒ€์ฆ ๊ฐ€๋Šฅ

Yup

์žฅ์ 

  • ์—ญ์‚ฌ๊ฐ€ ์˜ค๋ž˜๋˜์–ด ์•ˆ์ •์ ์ด๊ณ  ์„ฑ์ˆ™ํ•จ
  • ์ต์ˆ™ํ•œ API (ํŠนํžˆ Joi ์‚ฌ์šฉ์ž๋“ค์—๊ฒŒ)
  • ๋” ๊ฐ€๋ฒผ์šด ๋ฒˆ๋“ค ํฌ๊ธฐ (Zod๋ณด๋‹ค ์•ฝ๊ฐ„ ์ž‘์Œ)
  • ๋” ๋งŽ์€ ์ปค๋ฎค๋‹ˆํ‹ฐ์™€ ์˜ˆ์ œ

๋‹จ์ 

  • TypeScript ํ†ตํ•ฉ์ด Zod๋งŒํผ ๊ฐ•๋ ฅํ•˜์ง€ ์•Š์Œ
  • ํƒ€์ž… ์ถ”๋ก  ๊ธฐ๋Šฅ์ด ์ œํ•œ์ 

์˜ˆ์‹œ ์ฝ”๋“œ

import * as yup from 'yup';

const userSchema = yup.object({
  name: yup.string().required(),
  email: yup.string().email().required(),
  age: yup.number().positive().integer().min(18).required(),
  website: yup.string().url().nullable()
});

// ์‚ฌ์šฉ
try {
  const validatedData = await userSchema.validate(userData);
  // ์„ฑ๊ณต
} catch (error) {
  // ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์‹คํŒจ
}

Zod

์žฅ์ 

  • TypeScript์™€์˜ ๊ฐ•๋ ฅํ•œ ํ†ตํ•ฉ
  • ํƒ€์ž… ์ถ”๋ก ์ด ๋›ฐ์–ด๋‚จ (์Šคํ‚ค๋งˆ์—์„œ TypeScript ํƒ€์ž…์„ ์ž๋™์œผ๋กœ ์ถ”์ถœ)
  • ๋” ํ˜„๋Œ€์ ์ธ API ์„ค๊ณ„
  • ๋” ์—„๊ฒฉํ•œ ๊ธฐ๋ณธ๊ฐ’ (์˜ˆ: null๊ณผ undefined๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ํ—ˆ์šฉํ•ด์•ผ ํ•จ)
  • ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ์ปค์Šคํ„ฐ๋งˆ์ด์ง•์ด ๋” ์œ ์—ฐํ•จ

๋‹จ์ 

  • ๋ฒˆ๋“ค ํฌ๊ธฐ๊ฐ€ ์•ฝ๊ฐ„ ๋” ํผ
  • Yup๋ณด๋‹ค ์—ญ์‚ฌ๊ฐ€ ์งง์Œ
  • ํ•™์Šต ๊ณก์„ ์ด ์•ฝ๊ฐ„ ๋” ๊ฐ€ํŒŒ๋ฆ„

์˜ˆ์‹œ ์ฝ”๋“œ

import { z } from 'zod';

const userSchema = z.object({
  name: z.string(),
  email: z.string().email(),
  age: z.number().int().positive().min(18),
  website: z.string().url().nullable()
});

// ํƒ€์ž… ์ถ”๋ก 
type User = z.infer<typeof userSchema>;

// ์‚ฌ์šฉ
try {
  const validatedData = userSchema.parse(userData);
  // ์„ฑ๊ณต: validatedData๋Š” User ํƒ€์ž…
} catch (error) {
  // ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์‹คํŒจ
}

์„ฑ๋Šฅ ๋น„๊ต

์ผ๋ฐ˜์ ์œผ๋กœ Zod๊ฐ€ ์•ฝ๊ฐ„ ๋” ๋А๋ฆฌ์ง€๋งŒ ๋Œ€๋ถ€๋ถ„์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๊ทธ ์ฐจ์ด๋Š” ๋ฏธ๋ฏธ Yup์˜ ์•ฝ๊ฐ„ ๋” ์ž‘์€ ๋ฒˆ๋“ค ํฌ๊ธฐ๋Š” ํด๋ผ์ด์–ธํŠธ ์ธก ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์•ฝ๊ฐ„์˜ ์ด์ 

์–ด๋–ค ๊ฒƒ์„ ์„ ํƒํ•ด์•ผ ํ• ๊นŒ?

Yup์„ ์„ ํƒํ•˜๋Š” ๊ฒฝ์šฐ:

  • JavaScript ํ”„๋กœ์ ํŠธ
  • ๋” ๊ฐ€๋ฒผ์šด ๋ฒˆ๋“ค ํฌ๊ธฐ๊ฐ€ ์ค‘์š”ํ•œ ๊ฒฝ์šฐ
  • ๋” ์ต์ˆ™ํ•œ API๋ฅผ ์›ํ•˜๋Š” ๊ฒฝ์šฐ
  • ์„ฑ์ˆ™ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์„ ํ˜ธํ•˜๋Š” ๊ฒฝ์šฐ

Zod๋ฅผ ์„ ํƒํ•˜๋Š” ๊ฒฝ์šฐ:

  • TypeScript ํ”„๋กœ์ ํŠธ
  • ํƒ€์ž… ์ถ”๋ก ์ด ์ค‘์š”ํ•œ ๊ฒฝ์šฐ
  • ๋” ํ˜„๋Œ€์ ์ธ API๋ฅผ ์›ํ•˜๋Š” ๊ฒฝ์šฐ
  • ์—„๊ฒฉํ•œ ํƒ€์ž… ๊ฒ€์‚ฌ๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ

์ตœ๊ทผ ํŠธ๋ Œ๋“œ๋Š” TypeScript์˜ ์ธ๊ธฐ ์ฆ๊ฐ€์™€ ํ•จ๊ป˜ Zod๋กœ ๊ธฐ์šธ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ํŠนํžˆ TypeScript ํ”„๋กœ์ ํŠธ์—์„œ๋Š” Zod์˜ ๊ฐ•๋ ฅํ•œ ํƒ€์ž… ์ถ”๋ก  ๊ธฐ๋Šฅ์ด ํฐ ์žฅ์ ์ด ๋ฉ๋‹ˆ๋‹ค. React Hook Form์ด๋‚˜ Formik๊ณผ ๊ฐ™์€ ํผ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ๋‘ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ชจ๋‘ ์ž˜ ํ†ตํ•ฉ๋ฉ๋‹ˆ๋‹ค. ๊ฒฐ๊ตญ ํ”„๋กœ์ ํŠธ์˜ ์š”๊ตฌ ์‚ฌํ•ญ๊ณผ ํŒ€์˜ ์„ ํ˜ธ๋„์— ๋”ฐ๋ผ ์„ ํƒํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.