النماذج الآمنة نوعيًا وعقود استجابات API
استخدم Zod لاستنتاج أنواع TypeScript من المخططات والتحقق من بيانات النماذج واستجابات API.
النماذج الآمنة نوعيًا وعقود استجابات API درس مجاني في React Academy على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في React Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة React Academy 4 دروس في المجموع.
أهمية أشكال البيانات الآمنة من ناحية الأنواع
تمثل النماذج واستجابات API حدودًا تدخل عبرها البيانات إلى تطبيقك من مصادر غير موثوقة. يتيح لك Zod تعريف مخططات تتحقق من البيانات وقت التشغيل وتستنتج أنواع TypeScript في الوقت نفسه.
أساسيات مخططات Zod
عرّف المخططات باستخدام واجهة Zod المرنة. استخدم z.infer<typeof schema> لاستخراج نوع TypeScript.
import { z } from 'zod';
const UserSchema = z.object({
id: z.string().uuid(),
name: z.string().min(1).max(100),
email: z.string().email(),
age: z.number().int().min(0).max(150).optional(),
role: z.enum(['admin', 'user', 'guest']),
});
type User = z.infer<typeof UserSchema>;
// { id: string; name: string; email: string; age?: number; role: 'admin'|'user'|'guest' }React Hook Form مع محلّل Zod
ادمج مخططات Zod مع React Hook Form للتحقق من النماذج مع أمان الأنواع — إذ يعرف TypeScript بنية بيانات النموذج والأخطاء.
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
const LoginSchema = z.object({
email: z.string().email('Invalid email'),
password: z.string().min(8, 'At least 8 characters'),
});
type LoginData = z.infer<typeof LoginSchema>;
function LoginForm() {
const { register, handleSubmit, formState: { errors } } = useForm<LoginData>({
resolver: zodResolver(LoginSchema),
});
const onSubmit = (data: LoginData) => {
// data is LoginData — fully typed, already validated
};
}التحقق من استجابات API
حلّل استجابات API باستخدام Zod لاكتشاف عدم تطابق البنية عند الحد الفاصل — فإذا أعادت API بيانات غير متوقعة، تحصل على خطأ مفصل بدلًا من انهيار وقت التشغيل في عمق المكوّن.
async function fetchUser(id: string): Promise<User> {
const res = await fetch(`/api/users/${id}`);
const json = await res.json();
return UserSchema.parse(json); // throws ZodError if shape is wrong
}التحليل الآمن لمعالجة الأخطاء بسلاسة
استخدم schema.safeParse() للحصول على كائن نتيجة بدلًا من إطلاق استثناء — وهو مثالي للتحقق من النماذج عندما تريد عرض الأخطاء للمستخدم.
const result = UserSchema.safeParse(formData);
if (!result.success) {
const errors = result.error.flatten().fieldErrors;
// { name: ['Must be at least 1 character'], email: ['Invalid email'] }
return errors;
}
const user = result.data; // User — fully typedالاتحادات المميِّزة باستخدام Zod
استخدم z.discriminatedUnion لنمذجة استجابات API التي تختلف بنيتها استناداً إلى علامة النجاح أو الخطأ.
const ApiResponse = z.discriminatedUnion('ok', [
z.object({ ok: z.literal(true), data: UserSchema }),
z.object({ ok: z.literal(false), error: z.string(), code: z.number() }),
]);
type ApiResult = z.infer<typeof ApiResponse>;
// { ok: true; data: User } | { ok: false; error: string; code: number }تحويلات Zod
استخدم .transform() لتحويل البيانات أو إعادة تشكيلها أثناء تحليلها — مثل تحويل سلسلة تاريخ إلى كائن Date.
const DateSchema = z.string().transform(s => new Date(s));
// Input: '2024-01-15' → Output: Date object
const EventSchema = z.object({
title: z.string(),
date: z.string().pipe(z.coerce.date()),
});
type Event = z.infer<typeof EventSchema>;
// { title: string; date: Date }إعادة استخدام المخططات
اشتق مخططات الإنشاء والتحديث من المخطط الأساسي لتجنب التكرار.
const UserSchema = z.object({ name: z.string(), email: z.string().email() });
// For creation: add password
const CreateUserSchema = UserSchema.extend({ password: z.string().min(8) });
// For update: all fields optional
const UpdateUserSchema = UserSchema.partial();
type CreateUser = z.infer<typeof CreateUserSchema>;
type UpdateUser = z.infer<typeof UpdateUserSchema>;إجراء خادم باستخدام Zod
تحقق من بيانات النموذج في إجراء خادم Next.js باستخدام Zod قبل الوصول إلى قاعدة البيانات.
async function createPost(formData: FormData) {
'use server';
const schema = z.object({ title: z.string().min(3), body: z.string().min(10) });
const result = schema.safeParse(Object.fromEntries(formData));
if (!result.success) return { errors: result.error.flatten().fieldErrors };
await db.post.create({ data: result.data });
revalidatePath('/blog');
redirect('/blog');
}مخططات مشتركة بين الواجهة الأمامية والخلفية
صدّر مخططات Zod من حزمة مشتركة كي تستخدم الواجهة الأمامية والخلفية منطق التحقق نفسه — وليكون المخطط الواحد هو المصدر الوحيد للحقيقة.
// packages/schemas/src/user.ts
export const CreateUserSchema = z.object({ ... });
export type CreateUser = z.infer<typeof CreateUserSchema>;
// Frontend imports:
import { CreateUserSchema, CreateUser } from '@company/schemas';
// Backend imports:
import { CreateUserSchema } from '@company/schemas';رسائل أخطاء Zod
خصّص رسائل الأخطاء لكل حقل لتحسين تجربة المستخدم — إذ يمررها Zod تلقائياً إلى واجهة عرض أخطاء النموذج عبر resolver.
const RegistrationSchema = z.object({
username: z.string()
.min(3, 'Username must be at least 3 characters')
.max(20, 'Username cannot exceed 20 characters')
.regex(/^[a-z0-9_]+$/, 'Only lowercase letters, numbers, and underscores'),
});تحقق سريع
ماذا يوفّر z.infer في TypeScript؟
مراجعة
عرّف مخططات Zod مرة واحدة، واستخدم z.infer لاشتقاق أنواع TypeScript. استخدم zodResolver في React Hook Form للتحقق الآمن من الأنواع. حلّل استجابات API باستخدام Zod عند الحدود، واستخدم safeParse لعرض أخطاء مناسبة للمستخدم، وشارك المخططات بين الواجهة الأمامية والخلفية عبر حزمة مشتركة.
الأسئلة الشائعة
هل درس «النماذج الآمنة نوعيًا وعقود استجابات API» مجاني؟
نعم — نص درس «النماذج الآمنة نوعيًا وعقود استجابات API» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة React Academy، انتقل إلى CoddyKit PRO. تتضمن دورة React Academy 4 دروس في المجموع.
ماذا ستتعلم في «النماذج الآمنة نوعيًا وعقود استجابات API»؟
استخدم Zod لاستنتاج أنواع TypeScript من المخططات والتحقق من بيانات النماذج واستجابات API. تتمرن على React Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ React Academy؟
لا تُشترط خبرة سابقة. React Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 4 من أصل 4.
كم من الوقت يستغرق درس «النماذج الآمنة نوعيًا وعقود استجابات API»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس React Academy هذا؟
نعم. كل درس في React Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- الاتحادات المميّزة لأشكال المكوّنات
- الأنواع الشرطية والمُعيّنة في React
- المكوّنات متعددة الأشكال باستخدام خاصية 'as'
- النماذج الآمنة نوعيًا وعقود استجابات API