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

يا جماعة الخير، السلام عليكم. اسمي أبو عمر، مبرمج قضيت سنين طويلة من عمري بين الأكواد والخوارزميات، من أيام ما كنا نكتب الكود على شاشات سوداء بخط أخضر لحد اليوم مع السحابة والذكاء الاصطناعي. خليني اليوم أحكيلكم قصة صارت معي قبل كم سنة، قصة علمتني درس كبير عن بناء الواجهات البرمجية (APIs) وكيف إن اختيار الأداة الصح ممكن ينقذ مشروعك من “وجع راس” كبير.

كنا شغالين على تطبيق موبايل، فكرته كانت تجمع بين المحتوى الاجتماعي والتجارة الإلكترونية. التطبيق كان فيه صفحة رئيسية بتعرض للمستخدم اسمه وصورة بروفايله، وآخر منتج أضافه، وعدد التعليقات على هاد المنتج. فريق الواجهة الأمامية (Frontend) كانوا شباب شاطرين، بس كل يوم يجوني يشتكوا: “يا أبو عمر، التطبيق بطيء! الصفحة الرئيسية بتاخد 5 ثواني عشان تفتح!”.

أنا بصراحة استغربت، السيرفرات قوية وقاعدة البيانات معمولة صح. قعدت معهم، وفتحنا أدوات المطورين لنشوف “شو القصة”. وهون كانت الصدمة. عشان يعرضوا هاي المعلومات البسيطة، كانوا مضطرين يعملوا 3 طلبات API مختلفة لـ REST API اللي بنيناه:

  1. طلب لـ /api/user/{id} عشان يجيبوا معلومات المستخدم.
  2. طلب ثاني لـ /api/user/{id}/products عشان يجيبوا كل منتجاته، وبعدين يفلتروها في التطبيق نفسه ليلاقوا آخر منتج.
  3. طلب ثالث لـ /api/products/{productId}/comments عشان يجيبوا كل التعليقات ويعدّوها.

والمصيبة الأكبر كانت في الطلب الأول تبع المستخدم. الـ API كان يرجع كائن JSON ضخم فيه كل شي: تاريخ ميلاده، عنوانه، سجل مشترياته، آخر مرة سجل دخول… بيانات ما إلنا فيها أي لزوم في الصفحة الرئيسية! كان التطبيق يستقبل كل هاي البيانات ويرمي 95% منها. هون أدركت إننا غرقانين في جحيم اسمه الـ Over-fetching والـ Under-fetching. ومن هاي النقطة، بدأت رحلتي مع GraphQL.


تشخيص المشكلة: ما هو الـ Over-fetching والـ Under-fetching؟

قبل ما نحكي عن الحل، خلينا نفهم أصل المشكلة اللي كل مطور تعامل مع REST APIs أكيد مر فيها. هدول المصطلحين هما سبب كثير من مشاكل الأداء في تطبيقاتنا.

الـ Over-fetching: لما تجيب بضاعة ما إلك فيها لزوم

الـ Over-fetching، أو “الجلب الزائد”، بيصير لما تطلب معلومة بسيطة من الـ API، فيقوم السيرفر بإرجاع كمية هائلة من البيانات اللي ما بتحتاجها. تخيل إنك بدك بس اسم المستخدم وصورته، بس الـ API مصمم يرجعلك كل بيانات المستخدم في طلب واحد.

مثال من العالم القديم (REST API):

لو عملنا طلب GET /api/users/123، ممكن يرجعلنا إشي زي هيك:


{
  "id": 123,
  "username": "abu_omar",
  "email": "abuomar@example.com",
  "profile_picture": "url/to/image.jpg",
  "first_name": "عمر",
  "last_name": "أحمد",
  "address": {
    "street": "شارع القدس",
    "city": "نابلس",
    "country": "فلسطين"
  },
  "phone_number": "+970...",
  "created_at": "2020-01-15T09:30:00Z",
  "last_login": "2023-10-26T10:00:00Z",
  "order_history": [ ... 50 عنصر ... ]
}

في الصفحة الرئيسية، كل اللي كنا محتاجينه هو username و profile_picture. كل البيانات الباقية هي عبء على الشبكة، بتستهلك باقة الإنترنت تبعت المستخدم، وبتبطئ التطبيق لأنه بحاجة يحلل كل هذا الـ JSON الضخم.

الـ Under-fetching: مشوار الألف ميل اللي ببدأ بمليون طلب

الـ Under-fetching، أو “الجلب الناقص”، هو الوجه الآخر للمشكلة. بيصير لما نقطة النهاية (Endpoint) الواحدة في الـ API ما بتعطيك كل البيانات اللي بتحتاجها، فتضطر تعمل سلسلة من الطلبات المتتالية عشان تجمع كل المعلومات المطلوبة.

مثال من قصتنا:

عشان نعرض الصفحة الرئيسية، كنا بحاجة لـ:

  • الطلب الأول: GET /api/users/123 (للحصول على معلومات المستخدم)
  • الطلب الثاني: GET /api/users/123/posts (للحصول على منشوراته)
  • الطلب الثالث: GET /api/posts/abc/comments (للحصول على تعليقات آخر منشور)

هذا الأسلوب، اللي بسموه أحياناً مشكلة “N+1 requests”، كارثي للأداء، خصوصاً على شبكات الموبايل البطيئة. كل طلب إضافي يعني وقت انتظار أطول للمستخدم، وتجربة استخدام سيئة.

الحل السحري: تعرف على GraphQL

بعد ما شخصنا المشكلة، كان واضح إنه REST API، برغم قوته وبساطته في كثير من الحالات، مش هو الحل الأمثل لمشكلتنا. وهنا دخلت GraphQL على الخط. GraphQL مش مكتبة ولا إطار عمل، هي “لغة استعلام” (Query Language) للـ API تبعك، وفكرة عبقرية طورتها فيسبوك عام 2012 لحل هاي المشاكل بالزبط.

شو قصة GraphQL؟

الفكرة الأساسية في GraphQL بسيطة جداً: العميل (Client) هو اللي بقرر شو البيانات اللي بده إياها، وبالضبط بالشكل اللي بده إياه.

بدل ما يكون عندك عشرات الـ Endpoints المختلفة (/users, /posts, /comments)، في GraphQL عادة بيكون عندك نقطة نهاية واحدة بس (مثلاً /graphql). العميل بيرسل طلب واحد لهذه النقطة، وفي هذا الطلب بيوصف كل البيانات اللي بيحتاجها، حتى لو كانت من مصادر مختلفة (مستخدمين، منشورات، تعليقات).

نصيحة من أبو عمر: فكر في REST API كأنه بوفيه مفتوح عنده أطباق جاهزة (Users, Posts). ممكن طبق يكون فيه أكل زيادة ما بدك إياه (Over-fetching)، وممكن تحتاج تروح وترجع كذا مرة لتجمع وجبتك (Under-fetching). أما GraphQL، فهو كأنك بتعطي الشيف قائمة طلباتك بالتفصيل، وهو بحضّرلك طبق واحد فيه كل اللي طلبته بالزبط، لا زيادة ولا نقصان.

GraphQL في الميدان: مقارنة عملية مع REST

الحكي النظري حلو، بس خلينا نشوف كيف GraphQL بحل مشاكلنا على أرض الواقع. لنرجع لمثال الصفحة الرئيسية تبعت تطبيقنا.

مثال عملي: لنبني صفحة المستخدم من جديد

بدل ما نعمل 3 طلبات منفصلة، مع GraphQL بنعمل طلب واحد فقط. العميل بيكتب “استعلام” (Query) بيشبه الـ JSON وبيبعته للسيرفر.

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

العميل يرسل طلب POST إلى /graphql مع الاستعلام التالي:


query GetHomePageData {
  user(id: "123") {
    username
    profile_picture
    latestPost {
      title
      commentsCount
    }
  }
}

شوفوا جمال وبساطة الموضوع! في طلب واحد، طلبنا: من المستخدم اللي الـ id تبعه “123”، أعطيني الـ username و الـ profile_picture، ومن آخر منشور له (latestPost)، أعطيني الـ title وعدد التعليقات (commentsCount).

والسيرفر، اللي بيفهم GraphQL، راح يرجع استجابة JSON شكلها مطابق تماماً لشكل الطلب:


{
  "data": {
    "user": {
      "username": "abu_omar",
      "profile_picture": "url/to/image.jpg",
      "latestPost": {
        "title": "مقدمة إلى GraphQL",
        "commentsCount": 42
      }
    }
  }
}

وهيك، بطلب واحد فقط، حصلنا على كل البيانات اللي بنحتاجها بالزبط. لا في بيانات زيادة (Over-fetching)، ولا في طلبات ناقصة (Under-fetching). كل المشاكل انحلت بضربة واحدة.

وداعاً للـ Over-fetching و الـ Under-fetching

  • حل الـ Under-fetching: جمعنا بيانات من مصادر مترابطة (User, Post, Comments) في طلب شبكة واحد.
  • حل الـ Over-fetching: حددنا الحقول اللي بنحتاجها بالضبط (username, profile_picture, etc.) وما استلمنا أي بيانات إضافية.

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

بعد ما اشتغلت على مشاريع كثيرة باستخدام GraphQL، جمعت شوية نصائح عملية بحب أشاركها معكم.

متى تستخدم GraphQL؟ ومتى تلتزم بـ REST؟

GraphQL مش دايماً هو الحل السحري لكل شي. REST ما زال خيار ممتاز جداً في حالات كثيرة. القاعدة اللي بمشي عليها هي:

  • استخدم REST: لما تكون الـ API بسيطة جداً، أو بتتعامل مع مصادر بيانات واضحة ومحددة. مثلاً، API داخلية بين خدمتين (Microservices) ممكن تكون REST أبسط وأسرع في التنفيذ.
  • استخدم GraphQL: لما يكون عندك تطبيق عنده متطلبات بيانات معقدة ومتغيرة، وخصوصاً لما يكون عندك أكثر من عميل (تطبيق موبايل، موقع ويب، تطبيق ديسكتوب). GraphQL بيعطي قوة ومرونة هائلة لفريق الواجهة الأمامية (Frontend) ليطلبوا البيانات اللي بدهم إياها بدون ما يرجعوا لفريق الـ Backend كل شوي.

لا تخف من التعقيد المبدئي

بناء سيرفر GraphQL لأول مرة ممكن تحسه أصعب من بناء REST API. لازم تعرف مفاهيم جديدة زي الـ Schema (المخطط)، والـ Types (الأنواع)، والـ Resolvers (المحللات اللي بتجيب البيانات). لكن صدقني، هذا الجهد المبدئي بيوفر عليك أضعاف الوقت والجهد في المستقبل، خصوصاً لما التطبيق يكبر ويتعقد.

فكر في التخزين المؤقت (Caching)

التخزين المؤقت في REST سهل: كل URL هو معرّف فريد للبيانات، فممكن تعمل Cache على مستوى الـ HTTP. في GraphQL، كل الطلبات بتروح على نفس الـ URL (/graphql)، فالـ Caching بيختلف. لحسن الحظ، في مكتبات عملاقة زي Apollo Client و Relay بتهتم بهذا الموضوع بشكل ذكي جداً على مستوى العميل، وبتعمل Cache للبيانات بناءً على أنواعها ومعرّفاتها (IDs).


الخلاصة: هل GraphQL هو المستقبل؟ 🚀

من الآخر، GraphQL مش مجرد موضة وراح تعدي. هي أداة قوية جداً حلت مشاكل حقيقية كنا نعاني منها كمطورين لسنوات طويلة. أعطت فريق الـ Frontend استقلالية أكبر، وحسّنت أداء التطبيقات بشكل ملحوظ، وخلّت عملية تطوير وتحديث الـ APIs أكثر مرونة وسلاسة.

هل هذا يعني إن REST انتهى؟ طبعاً لأ. REST سيظل موجوداً وهو الخيار الأمثل للبساطة والوضوح في كثير من السيناريوهات. لكن أي مطور اليوم لازم يكون عنده GraphQL في صندوق أدواته، ويفهم متى وكيف يستخدمه.

نصيحتي الأخيرة إلك: لا تتردد. ابدأ اليوم بتعلم GraphQL. ابني مشروع صغير، جرب تكتب Schema، واكتب أول Query إلك. راح تكتشف عالم جديد من القوة والمرونة في التعامل مع البيانات. وبالتوفيق يا جماعة الخير!

أبو عمر

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

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

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

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

آخر المدونات

التوظيف وبناء الهوية التقنية

سيرتي الذاتية عبرت فلتر الـ ATS لكنها فشلت أمام المدير التقني: كيف أعدت بناءها لتتحدث لغة المهندسين؟

من واقع تجربة شخصية، أسرد لك كيف تحوّل سيرتك الذاتية من مجرد قائمة مهارات يتجاهلها المديرون التقنيون إلى قصة إنجازات مُقنعة تفتح لك أبواب المقابلات....

28 فبراير، 2026 قراءة المزيد
التوسع والأداء العالي والأحمال

خدمة واحدة فاشلة كادت أن تسقط النظام بأكمله: كيف أنقذني نمط ‘قاطع الدائرة’ (Circuit Breaker) من كارثة متتالية؟

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

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

لقد ‘هاجمت’ تطبيقي بنفسي عمداً: كيف كشفت لي ‘هندسة الفوضى’ نقاط الضعف التي لم تظهرها الاختبارات التقليدية

أشارككم قصة حقيقية حول إطلاق فاشل كاد أن يدمر سمعتنا، وكيف قادتنا هذه التجربة المريرة إلى تبني "هندسة الفوضى" (Chaos Engineering). اكتشفوا معنا كيف يمكن...

26 فبراير، 2026 قراءة المزيد
التوسع والأداء العالي والأحمال

عاصفة من الطلبات كادت أن تغرق تطبيقي: كيف أنقذتني طوابير الرسائل (Message Queues) من كارثة الجمعة السوداء؟

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

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