تطبيقي كان يغرق في بحر من طلبات API: كيف أنقذتني GraphQL من جحيم الـ Over-fetching والـ Under-fetching؟

مقدمة: لما كان التطبيق “بِشَرّق” بالبيانات

يا جماعة الخير، السلام عليكم. معكم أخوكم أبو عمر. قبل كم سنة، كنت شغال على تطبيق اجتماعي لأحد العملاء، تطبيق فكرته بسيطة: صفحة شخصية للمستخدم، فيها شوية معلومات عنه، وآخر منشوراته، مع كم تعليق تحت كل منشور. على الورق، المشروع كان يبدو “لوز”، يعني سهل ومباشر.

بديت الشغل واستخدمت معمارية REST API المعتادة. لكن لما بلّشنا نختبر التطبيق على شبكة جوال بطيئة شوي، بدت المشاكل. الصفحة الرئيسية كانت تأخذ وقت طويل جداً للتحميل، والتطبيق كان “يعلّق” ويستهلك بطارية بشكل مش طبيعي. قعدت مع حالي وحكيت: “يا أبو عمر، شو القصة؟ الكود نظيف والسيرفر قوي!”.

بعد تحليل للشبكة، اكتشفت الكارثة. تطبيقي المسكين كان يرسل طلب (request) عشان يجيب معلومات المستخدم. بعد ما ترجع البيانات، يرسل طلب ثاني عشان يجيب قائمة منشوراته. وبعدها، لكل منشور في القائمة، كان يرسل طلب جديد عشان يجيب التعليقات! تخيلوا معي، لو المستخدم عنده 5 منشورات، إحنا بنحكي عن 1 (للمستخدم) + 1 (للمنشورات) + 5 (للتعليقات) = 7 طلبات API منفصلة بس عشان نعرض صفحة واحدة! يا زلمة، كان التطبيق زي السلحفاة وهو يحاول يجمع كل هالمعلومات.

هنا كانت بداية رحلتي للبحث عن حل، حل ينقذني من هذا الجحيم اللي اسمه “Under-fetching”، ومن توأمه الشرير “Over-fetching”. الحل كان اسمه GraphQL.

ما هو جحيم الـ Over-fetching والـ Under-fetching؟

قبل ما نغوص في تفاصيل GraphQL، خلونا نفهم بالضبط شو المشاكل اللي كنت أواجهها مع REST API التقليدية. القصة وما فيها إنها بتتلخص في مفهومين:

الـ Over-fetching (الجلب الزائد للبيانات)

هذا بيصير لما نقطة النهاية (Endpoint) في الـ API بترجعلك بيانات أكثر بكثير من اللي بتحتاجه فعلاً في واجهة المستخدم. مثلاً، عشان أعرض اسم المستخدم وصورته الشخصية في رأس الصفحة، كنت أضطر أطلب كل معلوماته من خلال /api/users/123. الرد كان يرجعلي كائن (object) ضخم فيه اسمه، عمره، تاريخ ميلاده، عنوانه، قائمة أصدقائه، وكل إعدادات حسابه. أنا كل اللي كنت محتاجه حقلين، بس استلمت ثلاثين حقل! هذا استهلاك زائد للبيانات (bandwidth) وعبء إضافي على التطبيق لمعالجة كل هالمعلومات اللي ما إلها لزوم.

الـ Under-fetching (الجلب الناقص للبيانات)

وهذا هو الكابوس اللي حكيتلكم عنه في قصتي. بيصير لما نقطة النهاية ما بتعطيك كل البيانات اللي بتحتاجها دفعة واحدة. عشان تبني شاشة معقدة، بتحتاج ترسل طلبات متعددة لعدة endpoints عشان تجمع كل القطع. مثالنا كان واضح: احتجت طلب لبيانات المستخدم، ثم طلب لمنشوراته، ثم سلسلة من الطلبات لتعليقات كل منشور. هذا الأسلوب بيخلق ما يسمى بـ “Request Waterfall” (شلال الطلبات)، وهو سبب رئيسي لبطء التطبيقات وتجربة المستخدم السيئة.

GraphQL: المنقذ الذي طال انتظاره

وسط هذا الإحباط، بدأت أسمع عن تقنية اسمها GraphQL، وهي لغة استعلام (Query Language) للـ APIs طورتها فيسبوك داخلياً عام 2012 وأطلقتها كمشروع مفتوح المصدر في 2015. الفكرة الأساسية وراها عبقرية وبسيطة بنفس الوقت.

فكر في GraphQL كأنك رايح على بوفيه مفتوح. مع REST API، أنت مضطر تاخذ طبق جاهز محدد مسبقاً من الشيف، حتى لو ما بدك كل الأصناف اللي فيه (Over-fetching)، أو يمكن تضطر ترجع كذا مرة عشان تاخذ أصناف مختلفة من أقسام مختلفة (Under-fetching). أما مع GraphQL، أنت بتدخل ومعك صحنك، وبتحكي للشيف بالضبط شو الأصناف اللي بدك ياها وبأي كمية، وهو بجهزلك إياها كلها في طبق واحد ومرة واحدة.

هذا بالضبط ما تفعله GraphQL. أنت، كمطور للواجهة الأمامية (Frontend)، بتحدد بدقة البيانات اللي محتاجها، وشكلها، والسيرفر بيرجعلك إياها بالضبط، لا زيادة ولا نقصان، وكل هذا في طلب واحد فقط!

كيف يعمل هذا السحر؟

العملية بتعتمد على ثلاثة أعمدة رئيسية:

  1. Schema (المخطط): هو العقد أو “المنيو” بين العميل (Client) والخادم (Server). يتم تعريفه في الخادم، ويصف كل البيانات الممكنة اللي ممكن العميل يطلبها، وأنواعها، والعلاقات بينها. هو مصدر الحقيقة الأوحد.
  2. Queries (الاستعلامات): هي الطلبات اللي بيرسلها العميل. بدل ما يطلب endpoint معين، هو بيكتب استعلام بيشبه كائن JSON وبيوصف فيه البيانات اللي بده إياها.
  3. Resolvers (المُحَلِّلات): هي دوال (functions) موجودة على الخادم. وظيفتها إنها “تعرف” من وين تجيب البيانات لكل حقل مطلوب في الـ Query. ممكن تجيبها من قاعدة بيانات، من API ثانية، أو من أي مصدر آخر.

مثال عملي: قبل وبعد GraphQL

خلينا نرجع لمثال تطبيقنا الاجتماعي ونشوف الفرق بشكل عملي.

الطريقة القديمة (REST API)

كما ذكرنا، كنا نحتاج سلسلة من الطلبات:

  1. GET /api/users/123
  2. GET /api/users/123/posts
  3. GET /api/posts/post-abc/comments
  4. GET /api/posts/post-def/comments
  5. … وهكذا

الطريقة الجديدة (GraphQL)

الآن، مع GraphQL، كل اللي بحتاجه هو إرسال طلب POST واحد إلى نقطة نهاية وحيدة (عادة /graphql)، وفي جسم الطلب أضع الاستعلام التالي:


query GetUserProfilePage {
  user(id: "123") {
    name
    profilePictureUrl
    posts(first: 5) {
      id
      title
      comments(first: 3) {
        text
        author {
          name
        }
      }
    }
  }
}

والسيرفر سيرد بملف JSON واحد يحتوي على كل هذه البيانات المطلوبة، وبالشكل الذي طلبته تماماً. لا أكثر ولا أقل. لاحظ كيف أني طلبت الاسم وصورة الملف الشخصي فقط من المستخدم، وأول 5 منشورات، وأول 3 تعليقات لكل منشور. هذا هو قمة التحكم والمرونة.

مقارنة مباشرة: GraphQL مقابل REST

الميزة REST API GraphQL
جلب البيانات يتم تحديده من قبل الخادم. يعاني من Over/Under-fetching. يتم تحديده من قبل العميل. يطلب البيانات التي يحتاجها فقط.
نقاط النهاية (Endpoints) العديد من النقاط (e.g., /users, /posts). نقطة نهاية واحدة عادة (e.g., /graphql).
هيكلة البيانات لا يوجد معيار ثابت، يعتمد على التوثيق (e.g., Swagger). مخطط (Schema) صارم يصف أنواع البيانات والعلاقات.
إدارة الإصدارات (Versioning) شائعة من خلال الرابط (e.g., /v1/users, /v2/users). يمكن تجنبها بإضافة حقول جديدة للـ Schema دون كسر القديمة.

نصائح أبو عمر العملية

بعد الشغل على مشاريع بالتقنيتين، صار عندي شوية نصائح بحب أشاركها معكم “من الآخر”:

  • متى تختار GraphQL؟ إذا كان تطبيقك يحتوي على علاقات معقدة بين البيانات (مثل شبكة اجتماعية)، أو إذا كنت تطور لعدة واجهات (ويب، جوال، ساعة ذكية) ولكل منها متطلبات بيانات مختلفة، أو إذا كان استهلاك باقة الإنترنت على الجوال أمراً حساساً. GraphQL هنا “اشي مرتب” وبيحللك مشاكل كتير.
  • هل يعني هذا أن REST سيئة؟ أبداً! REST لا تزال خياراً ممتازاً وبسيطاً جداً للـ APIs الصغيرة والمباشرة، أو في معماريات الخدمات المصغرة (Microservices) حيث تكون كل خدمة مسؤولة عن نطاق محدد جداً. إذا كانت واجهتك البرمجية بسيطة مثل “أعطني قائمة المنتجات”، فلا داعي لتعقيد الأمور مع GraphQL.
  • انتبه لمشكلة N+1: على الرغم من أن GraphQL تحل مشكلة شلال الطلبات من طرف العميل، إلا أنها يمكن أن تخلق مشكلة مشابهة في الخادم تسمى “N+1 Query Problem”. تأكد من استخدام أدوات مثل `DataLoader` (في بيئة Node.js) لتجميع استعلامات قاعدة البيانات وتحسين أداء الـ Resolvers.
  • استثمر في الأدوات: البيئة المحيطة بـ GraphQL قوية جداً. مكتبات مثل Apollo Client و Relay تجعل التعامل مع GraphQL في الواجهة الأمامية تجربة ممتعة، حيث تدير التخزين المؤقت (caching)، وحالة الواجهة، وغيرها الكثير تلقائياً.

الخلاصة 💡

الانتقال إلى GraphQL كان نقلة نوعية في طريقة تفكيري وتطويري للتطبيقات. لقد حررتني من قيود الـ endpoints الثابتة وأعطتني (ولفريق الواجهات الأمامية) القوة لتصميم تجارب مستخدم سريعة وفعالة دون القلق بشأن “ثرثرة” الشبكة واستهلاك البيانات.

نصيحتي الأخيرة لكل مطور: لا تخف من تجربة التقنيات الجديدة. REST لن تموت، و GraphQL ليست الحل السحري لكل المشاكل. لكن فهم نقاط قوة وضعف كل منهما سيجعلك مهندساً أفضل، قادراً على اختيار الأداة المناسبة للمهمة المناسبة. ابدأ بمشروع جانبي صغير، جرب بناء GraphQL API بسيطة، وشوف بنفسك الفرق. صدقني، راح تدعيلي. 😉

أبو عمر

سجل دخولك لعمل نقاش تفاعلي

كافة المحادثات خاصة ولا يتم عرضها على الموقع نهائياً

آراء من النقاشات

لا توجد آراء منشورة بعد. كن أول من يشارك رأيه!

آخر المدونات

برمجة وقواعد بيانات

تحديثات قاعدة البيانات بدون توقف: كيف أنقذنا نمط التوسيع والتعاقد (Expand/Contract) من جحيم التوقفات المجدولة؟

هل سئمت من إيقاف الخدمة مع كل تحديث لهيكلة قاعدة البيانات؟ أشارككم قصة حقيقية وكيف أنقذنا نمط التوسيع والتعاقد (Expand/Contract) من ليالي النشر الطويلة والمُجهدة،...

4 يونيو، 2026 قراءة المزيد
الشبكات والـ APIs

كانت إعادة المحاولة كارثة: كيف أنقذتنا مفاتيح عدم تكرار العمليات (Idempotency Keys) من جحيم الفواتير المزدوجة؟

أشارككم قصة حقيقية من الخنادق البرمجية، يوم كاد خطأ بسيط في إعادة محاولة طلبات الدفع أن يكلفنا سمعتنا وأموال عملائنا. اكتشفوا معنا كيف كانت مفاتيح...

4 يونيو، 2026 قراءة المزيد
الحوسبة السحابية

من التوقف التام إلى النجاة: كيف أنقذتنا استراتيجية “الضوء المرشد” (Pilot Light) يوم انقطعت السحابة؟

أتذكر ذلك اليوم جيدًا، فنجان القهوة الصباحي، وصوت تنبيهات المراقبة يصرخ كأنه يوم القيامة. كانت منطقة سحابية كاملة قد توقفت عن العمل، لكن بفضل استراتيجية...

4 يونيو، 2026 قراءة المزيد
التوظيف وبناء الهوية التقنية

كانت مهمتي البرمجية للاختبار مجرد كود: كيف أنقذني توثيق القرارات من جحيم الصمت بعد المقابلة؟

أشارككم قصة حقيقية من بداياتي، وكيف تعلمت بالطريقة الصعبة أن المهمة البرمجية ليست مجرد كتابة كود، بل هي فرصة لإظهار طريقة تفكيرك. اكتشف كيف يمكن...

4 يونيو، 2026 قراءة المزيد
التكنلوجيا المالية Fintech

من الانتظار لأيام إلى الدفع في ثوانٍ: كيف أنقذتنا شبكات الدفع الفوري من جحيم التحويلات البنكية؟

أسرد لكم من واقع تجربتي كـ "أبو عمر"، كيف عانينا من بطء وتكلفة التحويلات البنكية الدولية، وكيف جاءت شبكات الدفع الفوري ومعيار ISO 20022 لتكون...

4 يونيو، 2026 قراءة المزيد
البنية التحتية وإدارة السيرفرات

كان كل خادم لدينا ‘ندفة ثلج’ فريدة: كيف أنقذنا ‘الكود كبنية تحتية’ (IaC) من جحيم الانجراف اليدوي؟

في هذه المقالة، أشارككم قصة حقيقية من قلب المعركة التقنية مع "خوادم ندفات الثلج" الفوضوية. سنغوص في مفهوم "الكود كبنية تحتية" (IaC) وكيف أن أدوات...

4 يونيو، 2026 قراءة المزيد
اختبارات الاداء والجودة

كانت تغطية الاختبارات 100% لكن الأخطاء تتسرب: كيف أنقذنا “الاختبار الطفري” من جحيم الثقة الزائفة؟

كنا نظن أن تغطية الاختبار بنسبة 100% هي درعنا الواقي، لكن الأخطاء كانت تتسلل إلى الإنتاج كاللصوص في ليل بهيم. اكتشف كيف أنقذنا "الاختبار الطفري"...

4 يونيو، 2026 قراءة المزيد
البودكاست