تطبيقي كان يغرق في بحر من طلبات 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 بسيطة، وشوف بنفسك الفرق. صدقني، راح تدعيلي. 😉

أبو عمر

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

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

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

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

آخر المدونات

تجربة المستخدم والابداع البصري

تطبيقي كان يستبعد الملايين بصمت: كيف أنقذتني ‘إرشادات الوصول الرقمي (WCAG)’ من جحيم التصميم الإقصائي؟

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

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

بياناتي كانت تتلف بصمت: كيف أنقذتني ‘معاملات قاعدة البيانات’ (Transactions) من جحيم البيانات الفاسدة؟

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

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

مقابلاتي لتصميم النظم كانت كارثة: كيف أنقذني هذا الإطار المنهجي من جحيم الرفض؟

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

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

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

أشارككم قصة حقيقية عن ليلة كاد فيها عطل بسيط في خدمة واحدة أن ينهار نظامنا بالكامل. سأشرح لكم بالتفصيل نمط "قاطع الدائرة" (Circuit Breaker) الهندسي،...

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

شبكة خدماتي المصغرة كانت الغرب المتوحش: كيف أنقذتني ‘شبكة الخدمات’ (Service Mesh) من جحيم انعدام الأمان والتحكم؟

أشارككم قصتي مع فوضى الخدمات المصغرة (Microservices) وكيف تحولت بنيتي التحتية من كابوس لا يمكن السيطرة عليه إلى نظام آمن ومنظم. هذه رحلتي مع شبكة...

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