개요
Vercel Next.js의 공식 github 레포지스티에 가면 example 소스코드가 있는데
schema validation을 위해 zod라는 패키지를 쓰고 있다.
이전 글에서 소개한 ajv가 압도적으로 다운로드 수가 많지만 legacy한 부분도 없지않고,
Next.js 공식 코드에서 사용하는 만큼 zod가 장점이 꽤 많다.
아래 보는 것 처럼 올해 들어 다운로드수도 폭발적으로 증가 중이다.
schema validation이 필요한 이유
1. api request 하나만 실패해도 web app 전체가 다운되는 현상을 방지
물론 optional chaining을 이용해 어느 정도 web app 전체가 다운되는 현상을 방지할 수는 있지만 원인을 찾을 수는 없다.
2. Typescript에만 의존할 수 없는 경우
예를들어 분명 swagger에 product가 { name, price } 두 가지 필드만 있다고 했는데, 실제로는 { id, price }라는 이름으로 들어오고 있다면 typescript로 체크할 방법이 없다.
3. 단지 백엔드의 REST API만이 문제가 아니고 validation이 필요한 경우는 여러가지가 있다. 하나의 예로 url의 query parameter는 고객(사용자)가 직접 입력해서 get 요청을 보낼 수 있다. 이런 uri가 유효한지도 체크할 필요가 있다.
결론적으로 schema validation은 필수라고 할 수 있다.
사용
우선 install
zod는 runtime dependency로 사용할 것이므로 --save-dev (혹은 -D)를 붙이지 않고 바로 install 한다.
pnpm add zod
import { z } from "zod";
const productJson = {
name: "jeans",
price: 100,
};
const productSchema = z.object({
name: z.string(),
price: z.number().positive(), // 양수 음수도 구별 가능
});
type Product = z.infer<typeof productSchema>;
const Test1 = () => {
const validateProduct = productSchema.safeParse(productJson);
console.log("validateProduct", validateProduct);
if (!validateProduct.success) {
console.error(validateProduct.error);
return;
}
return <div>Test1</div>;
};
export default Test1;
1. 위 코드는 fetch를 통해 json을 가지고오지 않고 하드코딩했다.
만약 fetch를 통해 가져온다면 미리 type(interface)을 지정해줘야하는데, 이러면 validation에서 한 번 더 입력해줘야하니 interface를 두 번 작업해야되는 번거로움이 생긴다. 그래서 위에처럼
type Product = z.infer<typeof productSchema>;
zod로 한 번 type을 검토하고, 위 코드 한 줄로 type을 지정해줄 수 있다.
2. safeParse
위 코드처럼 safeParse를 해주고 validateProduct를 출력하면
validateProduct { success: true, data: { name: 'jeans', price: 100 } }
success라는 키가 true / false인지 출력해준다.
이제 위에 하드코딩된 Json의 name을 → id 로 변경해주면
validateProduct { success: false, error: [Getter] }
ZodError: [
{
"code": "invalid_type",
"expected": "string",
"received": "undefined",
"path": [
"name"
],
"message": "Required"
}
]
validateProduct.success는 위와 같이 false가 되고
Required 필드인 name이 invalid type이라고 나온다.
'Frontend (Next.js Tailwind Typescript) > Next.js' 카테고리의 다른 글
Route Groups, Dynamic Routes, searchParams & File based Routing (1) | 2024.01.02 |
---|---|
03-3. tailwind-merge + clsx + class-variance-authority (0) | 2023.12.13 |
02-2. Next.js를 위한 기본 javascript syntax (0) | 2023.12.11 |
02-4. JSON schema validator: ajv (0) | 2023.12.11 |
03-1. font (0) | 2023.12.10 |