ما هو tRPC ولماذا هو مطلوب؟
\n\ntRPC (استدعاء الإجراءات عن بُعد لـ TypeScript) هي مكتبة حديثة لإنشاء واجهات برمجة تطبيقات (API) آمنة من حيث الأنواع (type-safe) بين العميل والخادم. السمة الرئيسية لـ tRPC هي أنه لا يتطلب إنشاء كود أو تكرار الأنواع. كل ما عليك فعله هو كتابة الدوال على الخادم، ويحصل العميل على إمكانية الوصول إليها مع دعم كامل لـ TypeScript - الإكمال التلقائي، والتحقق من الأنواع، و IntelliSense.
\n\nعلى عكس REST أو GraphQL، حيث تحتاج إلى وصف المخططات ونقاط النهاية والأنواع يدويًا، يقوم tRPC تلقائيًا باستنتاج الأنواع من كود الخادم الخاص بك. هذا يبسط التطوير بشكل جذري ويقلل من عدد الأخطاء.
\n\nالمزايا الرئيسية لـ tRPC:
\n- \n
- أمان كامل للأنواع - يتم اكتشاف أخطاء الأنواع في مرحلة التجميع، وليس في وقت التشغيل \n
- لا حاجة لإنشاء كود - لا حاجة لتشغيل المولدات أو مزامنة المخططات \n
- حد أدنى من الكود التكراري (Boilerplate) - كود أقل من REST أو GraphQL \n
- توثيق تلقائي - الأنواع تعمل كتوثيق \n
- البساطة - يعمل مثل استدعاء دالة عادي \n
tRPC مثالي لتطبيقات full-stack على TypeScript (Next.js، Remix، Express، Fastify) وللهندسة المعمارية القائمة على الخدمات المصغرة.
\n\nتثبيت tRPC
\n\nيتكون tRPC من عدة حزم. للاستخدام الأساسي، ستحتاج إلى:
\n\n# تثبيت أجزاء الخادم والعميل\nnpm install @trpc/server @trpc/client\n\n# تثبيت محول React (إذا كنت تستخدم React)\nnpm install @trpc/react-query @tanstack/react-query\n\n# تثبيت محول Next.js\nnpm install @trpc/next @trpc/react-query @tanstack/react-query\n\n# تثبيت Zod للتحقق من الصحة (موصى به)\nnpm install zod\n\nإذا كنت تستخدم yarn أو pnpm:
\n\nyarn add @trpc/server @trpc/client\npnpm add @trpc/server @trpc/client\n\nلمطوري Python (إذا كنت تستخدم Python في الواجهة الخلفية): tRPC هي مكتبة TypeScript، ولكن يمكنك استخدامها مع Python عبر trpc-py (غلاف تجريبي). ومع ذلك، فإن النظام البيئي الرئيسي هو TypeScript.
بداية سريعة مع مثال كود
\n\nلنقم بإنشاء تطبيق بسيط: خادم بإجراءات للعمل مع المستخدمين وعميل يقوم باستدعائها.
\n\n1. الخادم (server.ts)
\n\nimport { initTRPC } from '@trpc/server';\nimport { z } from 'zod';\n\n// إنشاء مثيل tRPC\nconst t = initTRPC.create();\n\n// تعريف نوع المستخدم\ninterface User {\n id: number;\n name: string;\n email: string;\n}\n\n// قاعدة بيانات وهمية\nconst users: User[] = [\n { id: 1, name: 'Alice', email: 'alice@example.com' },\n { id: 2, name: 'Bob', email: 'bob@example.com' },\n];\n\n// إنشاء موجه (Router) بالإجراءات\nconst appRouter = t.router({\n // إجراء لجلب جميع المستخدمين\n getUsers: t.procedure\n .query(() => {\n return users;\n }),\n\n // إجراء لجلب مستخدم حسب المعرف\n getUserById: t.procedure\n .input(z.number())\n .query(({ input }) => {\n return users.find(user => user.id === input) || null;\n }),\n\n // إجراء لإنشاء مستخدم\n createUser: t.procedure\n .input(z.object({\n name: z.string().min(1),\n email: z.string().email(),\n }))\n .mutation(({ input }) => {\n const newUser: User = {\n id: users.length + 1,\n name: input.name,\n email: input.email,\n };\n users.push(newUser);\n return newUser;\n }),\n});\n\n// تصدير نوع الموجه للعميل\nexport type AppRouter = typeof appRouter;\n\n2. العميل (client.ts)
\n\nimport { createTRPCClient, httpBatchLink } from '@trpc/client';\nimport type { AppRouter } from './server';\n\n// إنشاء عميل\nconst client