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

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

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

في البداية، الأمور كانت تمام. لكن مع زيادة البيانات وتعقيد الشاشات، بدأ التطبيق يصير بطيء… بطيء بشكل لا يطاق. فريق الموبايل كل يوم يشتكي: “يا أبو عمر، شاشة البروفايل بتحمّل 10 ثواني!”، “يا زلمة، الصفحة الرئيسية بتعمل 7 طلبات API مختلفة عشان تكتمل!”. كنت أفتح أدوات المطورين وأشوف الشبكة (Network Tab) عبارة عن شلال من الطلبات، نازلة ورا بعضها زي المطر. حسينا حالنا بنغرق حرفيًا، والعميل بدأ صبره ينفد. هون أدركت إن المشكلة أعمق من مجرد “بطء”، المشكلة كانت في صميم تصميم الـ API تبعنا. كنا ضايعين بين مطرقة الـ Over-fetching وسندان الـ Under-fetching.

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

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

المشكلة الأولى: الإفراط في جلب البيانات (Over-fetching)

بكل بساطة، الـ Over-fetching بيصير لما الـ API يرجعلك بيانات أكثر بكثير من اللي بتحتاجه في شاشة معينة. تخيل معي عندك شاشة في التطبيق بتعرض بس اسم المستخدم وصورته الشخصية. لكن الـ API اللي صممناه كان برجع كل معلومات المستخدم في طلب واحد.

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


{
  "id": "123",
  "name": "أبو عمر",
  "username": "abu_omar_dev",
  "email": "abu.omar@example.com",
  "profile_picture_url": "https://example.com/pic.jpg",
  "bio": "مبرمج فلسطيني يحب القهوة والكود النظيف...",
  "date_of_birth": "1985-01-15",
  "address": {
    "street": "شارع يافا",
    "city": "القدس",
    "country": "فلسطين"
  },
  "followers_count": 10000,
  "following_count": 500,
  "last_login": "2023-10-26T10:00:00Z"
  // ... وغيرها من البيانات الكثيرة
}

إحنا كل اللي محتاجينه هما حقلين: name و profile_picture_url. لكننا استقبلنا كل هاي البيانات اللي ما الها لزوم في هاي الشاشة بالذات. هاي البيانات الزائدة بتستهلك انترنت (باندويث)، بتزيد من وقت التحميل، وبتخلي التطبيق أبطأ، خصوصًا على شبكات الموبايل الضعيفة. هاي هي ورطة الـ Over-fetching.

المشكلة الثانية: القصور في جلب البيانات (Under-fetching)

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

لنرجع لمثالنا، تخيل عندنا شاشة بتعرض تفاصيل مقال (Post)، اسم كاتب المقال (Author)، وقائمة بالتعليقات (Comments) على المقال. باستخدام REST API تقليدي، السيناريو كان كالتالي:

  1. الطلب الأول: جلب بيانات المقال نفسه من /api/posts/45.
  2. الرد يحتوي على authorId لكن ليس اسم الكاتب.
  3. الطلب الثاني: جلب بيانات الكاتب باستخدام الـ ID اللي حصلنا عليه: /api/users/123.
  4. الطلب الثالث: جلب التعليقات المتعلقة بالمقال: /api/posts/45/comments.

شايفين الكارثة؟ شاشة واحدة بسيطة احتاجت 3 طلبات متتالية للشبكة! هذا ما يسمى بـ “شلال الطلبات” (Request Waterfall)، وهو قاتل لأداء التطبيق. كل طلب فيه وقت ضايع في الذهاب والإياب للسيرفر. هاي هي ورطة الـ Under-fetching.

اللقاء مع المنقذ: GraphQL

في عز حيرتي ويأسي وأنا ببحث عن حلول، قرأت مقالة عن تقنية اسمها GraphQL كانت فيسبوك طورتها داخليًا لحل نفس هاي المشاكل في تطبيق الموبايل تبعهم. في البداية كنت متشكك، “كمان تقنية جديدة نتعلمها؟ مش ناقصنا وجع راس!”. لكن كل ما قرأت عنها أكثر، كل ما حسيت إنها ممكن تكون الحل اللي بندور عليه.

ما هو GraphQL باختصار؟

GraphQL مش لغة برمجة، ولا قاعدة بيانات، ولا مكتبة محددة. هي عبارة عن “لغة استعلام” (Query Language) للـ API تبعك، ومواصفة (Specification) لكيفية عمل السيرفر عشان يفهم هاي اللغة.

الفكرة الجوهرية في GraphQL بسيطة وعبقرية: بدلاً من وجود عشرات نقاط النهاية (Endpoints) الثابتة في السيرفر (زي REST)، بيكون عندك نقطة نهاية واحدة فقط. العميل (التطبيق) هو اللي بقرر شو البيانات اللي بده إياها بالضبط، عن طريق إرسال “استعلام” (Query) يوصف شكل البيانات المطلوبة. السيرفر بيفهم هذا الاستعلام، وبيرجعلك JSON بنفس الشكل اللي طلبته بالضبط. لا زيادة ولا نقصان.

كيف أنقذنا GraphQL من الجحيم؟

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

القضاء على الـ Over-fetching: اطلب ما تحتاجه فقط

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


query GetUserHeaderData {
  user(id: "123") {
    name
    profile_picture_url
  }
}

والرد اللي كان يجي من السيرفر كان تحفة فنية من البساطة والكفاءة:


{
  "data": {
    "user": {
      "name": "أبو عمر",
      "profile_picture_url": "https://example.com/pic.jpg"
    }
  }
}

فقط البيانات المطلوبة! لا بايت واحد زيادة. هذا لوحده سرّع تحميل الشاشة بشكل ملحوظ جدًا.

القضاء على الـ Under-fetching: اجمع كل شيء في طلب واحد

أما بالنسبة لمشكلة شاشة المقال اللي كانت تحتاج 3 طلبات، فكان الحل مع GraphQL ساحرًا. صار بإمكاننا نكتب استعلام واحد يطلب كل شيء دفعة واحدة:


query GetPostPageData {
  post(id: "45") {
    title
    content
    author {
      name
      username
    }
    comments {
      text
      createdAt
      author {
        name
      }
    }
  }
}

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

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

بعد ما خضت هاي التجربة وغيرها، تعلمت كم شغلة مهمة عن GraphQL بحب أشاركم إياها.

1. GraphQL ليس بديلاً كاملاً لـ REST

لا تفكر إنه لازم ترمي كل شغل الـ REST اللي عندك وتبدأ من الصفر. REST لا يزال ممتازًا ومناسبًا جدًا للـ APIs البسيطة والموجهة للموارد (Resource-oriented). GraphQL يلمع ويتألق لما يكون عندك تطبيقات عميلة متعددة (ويب، موبايل، ساعة ذكية) باحتياجات بيانات مختلفة، أو لما تكون علاقات البيانات عندك معقدة ومتشعبة.

2. ابدأ صغيرًا وقم بالتغليف (Wrap, don’t rewrite)

إذا عندك نظام قائم على REST API، أصعب وأخطر إشي ممكن تعمله هو إعادة كتابة كل شيء من الصفر. النصيحة الذهبية: ابدأ ببناء “طبقة GraphQL” فوق الـ REST APIs الموجودة عندك. يعني سيرفر GraphQL تبعك، بدل ما يكلم قاعدة البيانات مباشرة، بيقوم هو باستدعاء الـ REST APIs القديمة ويجمع البيانات منها ويرجعها للعميل. هذه طريقة آمنة وتدريجية للانتقال.

3. فكر في التخزين المؤقت (Caching) بذكاء

واحدة من نقاط قوة REST هي سهولة التخزين المؤقت على مستوى HTTP، لأن كل URL يمثل موردًا محددًا. مع GraphQL، كل الطلبات بتروح لنفس الـ URL (مثلاً /graphql)، وهذا يجعل التخزين المؤقت على مستوى HTTP أصعب. الحل يكمن في مكتبات العميل (Client Libraries) القوية مثل Apollo Client أو Relay. هذه المكتبات تقوم بعمل “تخزين مؤقت مُطَبَّع” (Normalized Caching) ذكي جدًا، بحيث تفهم البيانات اللي رجعت وتخزنها بشكل منظم، وهذا يقلل الطلبات للسيرفر بشكل كبير.

4. الأمان أولاً يا صاحبي

مع القوة تأتي المسؤولية. GraphQL بيعطي العميل قوة كبيرة، وهذا ممكن يُستغل بشكل سيء. ممكن عميل خبيث يرسل استعلامًا معقدًا جدًا ومتشعبًا لدرجة إنه يستهلك كل موارد السيرفر ويوقعه (Denial of Service). لازم تحمي سيرفرك عن طريق:

  • تحديد عمق الاستعلام (Query Depth Limiting): منع الاستعلامات المتشعبة لأكثر من مستوى معين.
  • تحليل تعقيد الاستعلام (Query Complexity Analysis): إعطاء “تكلفة” لكل حقل في الاستعلام، ورفض الاستعلامات اللي بتتجاوز تكلفة معينة.
  • وضع مهلة زمنية (Timeout): إيقاف أي استعلام يأخذ وقتًا أطول من اللازم.

الخلاصة: هل يستحق GraphQL كل هذا العناء؟

بالنسبة لي ولفريقي، الجواب كان نعم وبقوة. GraphQL لم يحل مشاكل الأداء فقط، بل حسّن تجربة المطورين بشكل لا يصدق. صار فريق الواجهات الأمامية (Frontend) وفريق الموبايل عندهم استقلالية أكبر، وما عادوا بحاجة يطلبوا تعديلات على الـ API مع كل تغيير بسيط في تصميم الشاشة.

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

في المرة القادمة التي تشعر فيها أن واجهاتك تغرق في بحر من الطلبات البطيئة، تذكر قصة أبو عمر. ربما حان الوقت لتعطي GraphQL فرصة، فقد يكون هو طوق النجاة الذي يحتاجه مشروعك. بالتوفيق يا جماعة! 💪

أبو عمر

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

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

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

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

آخر المدونات

تسويق رقمي

محتوانا كان غير مرئي لمحركات البحث: كيف أنقذتنا ‘البيانات المنظمة’ (Structured Data) من جحيم الترتيب المتدني؟

كنا نملك محتوى ذهبياً لكنه كان كالشبح في عيون جوجل. في هذه المقالة، أشارككم قصتي كـ "أبو عمر" وكيف انتشلنا "البيانات المنظمة" (Structured Data) من...

6 أبريل، 2026 قراءة المزيد
برمجة وقواعد بيانات

جداولي كانت فوضى من التكرار: كيف أنقذتني ‘تسوية قاعدة البيانات’ (Database Normalization) من جحيم البيانات؟

أشارككم قصة حقيقية من بداياتي في البرمجة، وكيف تحولت جداولي الفوضوية إلى نظام متكامل بفضل مفهوم 'تسوية قاعدة البيانات' (Normalization). دليل عملي للمبتدئين والمحترفين لفهم...

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

خوادمي كانت تعمل 24/7 لمهمة تستغرق ثوانٍ: كيف أنقذتني “الدوال عديمة الخادم” من جحيم التكاليف؟

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

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

مقابلاتي كانت كارثية: كيف أنقذني نموذج STAR من جحيم الأسئلة السلوكية والرفض المتكرر؟

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

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

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

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

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

التحقق من هوية عملائنا كان يستغرق أياماً: كيف أنقذني ‘التعرف الضوئي على الحروف’ (OCR) والذكاء الاصطناعي من جحيم الـ KYC اليدوي؟

كانت عملية التحقق من هوية العملاء الجدد (KYC) كابوسًا يدويًا يستنزف أيامًا من وقت فريقي. في هذه المقالة، أشارككم قصتي كـ "أبو عمر" وكيف حوّلنا...

5 أبريل، 2026 قراءة المزيد
ادارة الفرق والتنمية البشرية

فريقنا كان ينهار مع كل استقالة: كيف أنقذتني ‘كتيبات التشغيل’ (Playbooks) من جحيم فقدان المعرفة؟

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

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