المخطط الشامل: هندسة منطق الأعمال المشترك بين Next.js و Expo
توقف عن تكرار منطق الواجهة الخلفية (backend logic). تعلم كيفية هندسة مستودع موحد (monorepo) يركز على المنطق أولاً، لتشغيل كل من Next.js Server Actions وتطبيق Expo للجوال باستخدام مصدر واحد للحقيقة.

المخطط الشامل: هندسة منطق الأعمال المشترك بين Next.js و Expo
لسنوات، كنت أطارد شبحًا معماريًا متكررًا: تكرار منطق الأعمال (business logic). أنت تعرف القصة - تكتب وظيفة createOrder مصادق عليها بدقة للوحة تحكم Next.js، وبعد أسبوعين، تجد نفسك تعيد كتابة نفس المنطق، وقواعد التحقق، واستدعاءات قاعدة البيانات لتطبيق Expo للجوال.
إنه أمر هش، وعرضة للأخطاء، وبصراحة، كابوس في الصيانة.
مع ظهور Next.js Server Actions، تلاشت الحدود بين الواجهة الأمامية (frontend) والخلفية (backend)، ولكن في الغالب للويب فقط. مؤخرًا، أصبحت مهووسًا بنمط يسد هذه الفجوة، مما يسمح لنا باستخدام Server Actions كمواطن من الدرجة الأولى في Next.js مع الحفاظ على إمكانية وصول تطبيق Expo الأصلي (native client) إلى نفس المنطق.
إليك المخطط الذي أستخدمه لتحقيق ما أسميه "هندسة المنطق أولاً" (Logic-First Architecture).
الفلسفة الأساسية: "طبقة الخدمات" (Service Layer) هي الملك
الخطأ الذي يقع فيه معظم المهندسين هو وضع المنطق داخل الـ Server Action. إذا فعلت ذلك، فلن يتمكن تطبيق Expo من الوصول إليه. بدلاً من ذلك، نحتاج إلى معاملة الـ Server Action (للويد) والـ API Route (للجوال) كطبقات نقل (transport layers) بسيطة.
في مشاريعي التي تعتمد على مستودع موحد (monorepo) - وغالبًا ما يتم تشغيلها بواسطة Turborepo - أقوم بإنشاء حزمة مخصصة: @acme/api أو @acme/services. هذا هو المكان الذي يعيش فيه "المخطط الشامل".
1. تعريف المخطط المشترك (Shared Schema)
يبدأ الأمر بـ Zod. التحقق (Validation) هو خط الدفاع الأول. من خلال مشاركة المخطط، تضمن أن كلاً من نموذج الويب (web form) ومدخلات الجوال تتبع نفس القواعد.
2. وظيفة الخدمة الشاملة (Universal Service Function)
هذا هو العقل المدبر لعملياتك. لا يعرف شيئاً عن طلبات HTTP أو ملفات تعريف الارتباط (cookies). إنه ببساطة يأخذ بيانات تم التحقق منها وسياقاً (مثل جلسة المستخدم) ويؤدي المهمة.
تنفيذ Next.js: الـ Server Actions
الآن، في تطبيق Next.js الخاص بك، يصبح Server Action عبارة عن وظيفة من 5 أسطر. يتعامل مع الأمور "الخاصة بالويب" مثل إعادة التحقق من المسارات (revalidating paths) والتحقق من جلسة الويب.
اتصال Expo: جسر الـ API
لا يمكن لـ Expo استدعاء وظائف "use server" مباشرة. لحل هذه المشكلة، أقوم بعرض نفس وظيفة الخدمة من خلال REST endpoint قياسي أو tRPC procedure. وبما أننا في monorepo، فإن تطبيق الجوال يستهلك نفس الخدمة تمامًا.
لماذا يعتبر هذا الاختراق مهماً
في مشاريعي الأخيرة، قلل هذا النمط من "أخطاء المنطق" (logic bugs) بنسبة تقارب 40%. عندما يقرر مدير المنتج أن عنوان المهمة يجب أن يكون 5 أحرف بدلاً من 3، أقوم بتغيير مخطط Zod واحد في @acme/api.
- مزامنة فورية: تحديث التحقق من صحة نموذج Next.js على الفور.
- أمان الجوال: سيعرض تطبيق Expo (إذا كنت تستخدم حزمة أنواع مشتركة) خطأ TypeScript أثناء التطوير إذا تغير هيكل البيانات (payload structure).
- سلامة الواجهة الخلفية: يرث كل من API route و Server Action التغيير فوراً.
أفكار أخيرة
غالبًا ما نفكر في Next.js و Expo كعالمين مختلفين. ولكن عندما تجرد منطق الأعمال الخاص بك إلى طبقة خدمات مشتركة، يصبح "Server Action" مجرد طريقة أخرى لتشغيل وظيفة ما.
إذا كنت تبني منتجاً متعدد المنصات اليوم، فتوقف عن كتابة "منطق الويب" و"منطق الجوال". ابدأ بكتابة المخطط الشامل. سيتوجه لك نفسك المستقبلية - وزملائك في الفريق - بالشكر.
ابقَ تقنياً، وابقَ فضولياً.