در برنامههای React، مدیریت پاسخهای API میتواند به مسئلهای چالشبرانگیز تبدیل شود. گاهی دادههایی دریافت میکنیم که فیلدهای ضروری را ندارند، ساختارشان غیرمنتظره است یا با قالب مورد انتظار مطابقت ندارند. وقتی توسعهدهنده با دادههای ناسازگار روبهرو میشود، احتمال بروز خطا افزایش مییابد و مدیریت دادهها برای او دشوارتر میشود. در این شرایط، استفاده از Zod در React به عنوان راهکاری مؤثر مطرح میشود. این کتابخانه سبک و قدرتمند، امکان اعتبارسنجی دقیق پاسخهای API را فراهم میکند و از بروز خطاهای ناشی از دادههای نامعتبر جلوگیری مینماید.
در پایان این آموزش، یاد خواهیم گرفت که چگونه:
Zod را برای اعتبارسنجی پاسخهای API در React راهاندازی و استفاده کنیم.
اسکیمایی تعریف کنیم که دادههای ورودی را اعتبارسنجی و تبدیل کند.
Zod یک کتابخانه قدرتمند مبتنی بر تایپ اسکریپت است که فرآیند اعتبارسنجی دادهها را ساده میسازد. این ابزار به ما این امکان را میدهد تا قوانین روشنی (اسکیماها) برای قالب دادههای مورد انتظار خود تعریف نماییم.
همچنین، Zod میتواند دادههای ورودی (که اغلب از پاسخهای API هستند) را اعتبارسنجی کند تا اطمینان حاصل شود که با این قوانین تطابق دارند. این فرآیند اعتبارسنجی تضمین میکند که دادهها از قالب تعریفشده تبعیت میکنند و در نتیجه، قابلیت اطمینان و یکپارچگی برنامه ما افزایش مییابد.
دلایل درخشش Zod در اعتبارسنجی API در React عبارتاند از:
با استفاده از Zod میتوانیم پاسخهای غیرقابل پیشبینی API را به دادههایی تمیز و ساختارمند تبدیل کنیم و مسیر توسعه در React را برای خود هموارتر و مؤثرتر سازیم.
ایجاد یک پروژه جدید React با پشتیبانی از تایپ اسکریپت بسیار ساده است. کافیست دستور زیر را در ترمینال اجرا کنیم:
npm create vite@latest my-react-app -- --template react-ts
پس از ایجاد پروژه، وارد پوشه آن میشویم و دستورات زیر را اجرا میکنیم:
cd my-react-app npm install npm run dev
اکنون میتوانیم از پروژه React خود با پشتیبانی از تایپ اسکریپت استفاده کنیم. برای نصب کتابخانه Zod، دستور زیر را اجرا میکنیم:
npm install zod
Zod با استفاده از اسکیمای دادهها به ما کمک میکند تا انتظارات روشنی برای پاسخهای API خود تعریف کنیم. این اسکیماها مانند نقشههایی هستند که نوع دادههایی که انتظار دریافت آنها را داریم، مشخص میکنند.
Zod توابع سازندهای مانند z.string()، z.number() و z.object() در اختیار ما قرار میدهد تا بتوانیم اسکیماهای خود را تعریف کنیم. این توابع مشخص میکنند که یک فیلد خاص در پاسخ API باید چه نوع دادهای داشته باشد:
import { z } from 'zod';
// Define basic data types
const userName = z.string().min(5).max(10); // String with min 5 and max 10 characters
const userAge = z.number().positive().int(); // Positive integer
const userEmail = z.string().email(); // Ensures a valid email format
console.log(userName.parse('John Doe')); // Output: John Doe (valid)
console.log(userAge.parse(30)); // Output: 30 (valid)
console.log(userEmail.parse("johnDoe@gmail.com")); // Output: johnDoe@gmail.com (valid)
کد بالا سه نوع داده بیسیک را تعریف میکند:
userName: رشتهای با حداقل ۵ و حداکثر ۱۰ کاراکترuserAge: عدد صحیح مثبتuserEmail: قالب معتبر ایمیلZod به ما این امکان را میدهد تا با زنجیرهسازی متدهایی مانند min، max، positive، int و email، قوانین خاصی را بر روی این نوع دادهها اعمال نماییم.
در ادامه، نمونهای از رشتهای را میبینیم که از حداکثر تعداد کاراکتر مجاز عبور کرده است:
console.log(userName.parse("Hello there, My Name is John Doe")); // Throws ZodError
کد فوق به دلیل تجاوز از حداکثر طول ۱۰ کاراکتر، یک ZodError ایجاد میکند. این خطا ممکن است جریان برنامه را مختل کند و در نهایت باعث شود برنامه از کار بیفتد.
Zod دو روش برای بررسی دادهها با استفاده از اسکیما ارائه میدهد:
schema.parse(data): این متد تلاش میکند داده را مطابق اسکیما تجزیه کند. اما اگر خطای اعتبارسنجی وجود داشته باشد، یک خطا ZodError ایجاد میکند. همانطور که در مثال قبلی دیدیم، این موضوع میتواند باعث اختلال در جریان اجرای برنامه شود.schema.safeParse(data): توسعهدهنگان این روش را توصیه میکنند. این متد، داده را تجزیه کرده و یک آبجکت از نوع ZodResult object بازمیگرداند که شامل ویژگیهای کلیدی زیر است:
success: این مقدار بولین مشخص میکند که آیا عملیات تجزیه با موفقیت انجام شده است یا خیر.data: داده تجزیه شده، در صورتی که success برابر true باشد.error: پیام خطا در صورتی که success برابر false باشد.مثال اول: استفاده از safeParse با دادههای معتبر
const userSchema = z.object({
name: userName,
age: userAge,
email: userEmail,
});
const userData = {
name: "John Doe",
age: 24,
email: "johndoe@gmail.com"
};
const result = userSchema.safeParse(userData);
console.log(result); // ZodObject containing data and success status
در این مثال، یک اسکیمای کاربر با ویژگیهای name، age و email تعریف کردهایم. سپس با استفاده از safeParse() تلاش میکنیم آبجکت userData مطابق این اسکیما تجزیه شود. وقتی عملیات با موفقیت انجام میشود، کامپوننت داده تجزیهشده را نمایش میدهد. در غیر این صورت، پیغام خطا چاپ خواهد شد.
مثال دوم: استفاده از safeParse با دادههای نامعتبر
const userSchema = z.object({
name: userName,
age: userAge,
email: userEmail,
});
const userData = {
name: "John Doe",
age: 24,
email: "johndoe.com" // invalid email
};
const result = userSchema.safeParse(userData);
console.log(result); // ZodObject containing error and success status
در این مثال هم اسکیما مشابهی تعریف کردهایم؛ اما اینبار، عمداً دادهای نامعتبر (با فرمت نادرست ایمیل) را به تابع safeParse ارسال کردهایم. بر خلاف متد parse که هنگام بروز خطا برنامه را متوقف میکند و خطای ZodError میدهد، متد safeParse امکان مدیریت خطا را بهصورت ایمن و بدون توقف در اجرای برنامه فراهم میکند.
اکنون، با استفاده از مفاهیم اصلی Zod، اسکیماهایی طراحی میکنیم که بهطور خاص برای دادههای دریافتی از API کاربرد دارند. در اینجا از دادههای سایت JSONPlaceholder استفاده میکنیم که اطلاعات مربوط به پستها را در اختیارمان قرار میدهد.
نمونهای از پاسخ JSON برای یک پست:
{
"userId": 1,
"id": 3,
"title": "ea molestias quasi exercitationem repellat qui ipsa sit aut",
"body": "et iusto sed quo iure\nvoluptatem occaecati omnis eligendi aut"
}
برای اینکه نحوه استفاده از Zod در کنار API را نشان بدهیم، میتوانیم یک کامپوننت React بسازیم. اسم کامپوننت را میتوانیم مطابق ساختار پروژه خود انتخاب نماییم، اما در این مقاله، برای سادگی از اسم ZodApi استفاده میکنیم.
import { z } from 'zod';
const postSchema = z.object({
userId: z.number().positive().int(),
id: z.number().positive().int(),
title: z.string(),
body: z.string()
});
const postSchemaArray = z.array(postSchema); // Schema for array of posts
در این قطعه کد:
postSchema ساختار مورد انتظار برای یک پست را مشخص میکند.postSchemaArray اسکیمایی برای یک آرایه از پستها میباشد.اکنون میخواهیم اسکیماهایی که ساختیم را به دادههای واقعی از API متصل کنیم و آنها را اعتبارسنجی نماییم. برای این کار کدی که در بخش قبل نوشتیم را باید بهروزرسانی کنیم:
import { z } from 'zod';
import { useEffect } from 'react';
const postSchema = z.object({
userId: z.number().positive().int(),
id: z.number().positive().int(),
title: z.string(),
body: z.string()
});
const postSchemaArray = z.array(postSchema); // schema for an array of posts
type Posts = z.infer<typeof postSchemaArray>; // type of the posts
const ZodApi = () => {
useEffect(() => {
fetch("https://jsonplaceholder.typicode.com/posts")
.then((response) => response.json())
.then((posts: Posts) => {
const validatedPosts = postSchemaArray.safeParse(posts); // remember to use safeParse instead of parse
if (validatedPosts.success === false) {
console.log("Validation Error:"validatedPosts.error);
return;
}
// we can now safely use the posts
console.log(validatedPosts.data);
});
}, []);
return <div>ZodApi</div>;
};
export default ZodApi;
کامپوننت ZodApi موارد زیر را بیان میکند:
useEffect و fetch برای گرفتن اطلاعات از API استفاده میکنیم.type Posts = z.infer<typeof postSchemaArray>;، Posts type به صورت خودکار از اسکیما postSchemaArray استخراج میشود که باعث ایمنی و دقت بیشتر میگردد.postSchemaArray با استفاده از safeParse و اسکیما بررسی میشوند.success: در صورتی که اعتبارسنجی موفقیتآمیز باشد، داده معتبر در validatedPosts.data قرار میگیرد و میتواند در رابط کاربری یا state مورد استفاده قرار بگیرد.validatedPosts.success === false، خطاهای اعتبارسنجی به صورت ساده در کنسول لاگ میشوند.در این بخش، یاد میگیریم چگونه دادههای اعتبارسنجیشده را در رابط کاربری نمایش دهیم و با استفاده از stateهای React، مکانیزم مدیریت خطا را پیادهسازی کنیم.
import { z } from "zod";
import { useEffect, useState } from "react";
const postSchema = z.object({
userId: z.number().positive().int(),
id: z.number().positive().int(),
title: z.string(),
body: z.string(),
});
const postSchemaArray = z.array(postSchema); // schema for an array of posts
type Posts = z.infer<typeof postSchemaArray>; // type of the posts
const ZodApi = () => {
const [posts, setPosts] = useState<Posts>([]); // State to store validated posts
const [error, setError] = useState(""); // State to store any errors
useEffect(() => {
fetch("https://jsonplaceholder.typicode.com/posts")
.then((response) => response.json())
.then((posts: Posts) => {
const validatedPosts = postSchemaArray.safeParse(posts); // remember to use safeParse instead of parse
if (validatedPosts.success === false) {
console.log(validatedPosts.error.name);
setError(validatedPosts.error.message); // set error state
return;
}
// we can now safely use the validatedPosts
console.log(validatedPosts.data);
setPosts(validatedPosts.data)
});
}, []);
// Handle loading state (optional)
if (!posts.length && !error) {
return <div>Loading posts...</div>;
}
// Handle error state
if (error) {
return <div>Error fetching Data</div>; // Display user-friendly error message
}
return (
<div>
<h1>Posts</h1>
<ol>
{posts.map((post) => (
<li key={post.id}>
{post.title}
</li>
))}
</ol>
</div>
);
};
export default ZodApi;
کدی که در اختیار داریم، مربوط به کامپوننت ZodApi است که برای انجام وظایف مشخصی بهروزرسانی شده است:
posts و error تعریف شدهاند. posts برای نگهداری دادههای دریافتی از API و error برای ذخیره پیامهای خطا استفاده میشود.map در رابط کاربری رندر میشوند.در نهایت، زمانی که فرآیند بارگذاری با موفقیت انجام شود، کاربران باید بتوانند ۱۰۰ پست را روی صفحه مشاهده کنند. اگر همه مراحل را بهدرستی طی کرده باشیم، این تعداد پست قابل نمایش خواهد بود. در غیر این صورت، لازم است بررسی کنیم که درخواست fetch بهدرستی ارسال و پردازش میشود.
با اضافه کردن Zod به روند توسعه React، میتوانیم برنامههایی مقاومتر و قابلاعتمادتر بسازیم.
Zod این امکان را فراهم میکند تا ما در همان مراحل اولیه، ناسازگاریهای دادهای را شناسایی کنیم و جلوی خطاهای پیچیده را بگیریم. این ویژگی موجب صرفهجویی در زمان اشکالزدایی و افزایش کیفیت کد خواهد شد.
همچنین، پیامهای خطای قابلفهم و کاربرپسند Zod، تجربه کاربری را بهبود میبخشند و توسعهدهندگان را در شناسایی سریعتر مشکلات یاری میدهند.