كنا نغرق في بحر من الـ Endpoints: كيف أنقذنا GraphQL من جحيم الـ Over-fetching؟

يا أهلاً وسهلاً بكل المبرمجين والمبرمجات، معكم أخوكم أبو عمر.

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

فريق الـ Backend، اللي كنت جزء منه، كان عايش في جحيم اسمه REST APIs. الصفحة الرئيسية في تطبيق الموبايل بدها اسم المستخدم وصورة بروفايله بس. صفحة الويب بدها كل تفاصيل المستخدم: اسمه، إيميله، تاريخ ميلاده، آخر 10 مقالات كتبها، وأسماء أصدقائه. شو كنا نعمل؟

كنا نضطر نعمل endpoint لكل حالة! endpoint للموبايل اسمه /api/v1/users/123/mobile-profile، وendpoint ثاني للويب /api/v1/users/123/web-profile. ومع الوقت، صار عنا غابة من الـ endpoints، مئات! وكل ما فريق الواجهات الأمامية يطلب تعديل بسيط، “أبو عمر، بدنا نضيف تاريخ الانضمام في صفحة الموبايل”، كنا نضطر نعدّل على الـ endpoint، ونعمل build و deploy جديد، قصة طويلة عريضة.

الأسوأ من هيك كان مشكلة الـ Over-fetching. عشان نختصر على حالنا، كنا نعمل endpoint واحد زي /api/users/123 يرجع كلللل إشي عن المستخدم. فتطبيق الموبايل المسكين، اللي بس بده اسم وصورة، كان يستقبل ملف JSON حجمه نص ميجا مليان بيانات ما إله فيها لزوم. وهذا طبعاً كان يبطئ التطبيق ويستهلك باقة الإنترنت عند المستخدمين. كنا حرفياً بنغرق في بحر من البيانات غير اللازمة… لحد ما لقينا طوق النجاة: GraphQL.

ما هو الجحيم الذي كنا نعيش فيه؟ (مشاكل REST التقليدية)

قبل ما نحكي عن الحل، خلينا نفصّل المشكلة أكتر عشان الصورة تكون واضحة للجميع، خصوصاً للمبرمجين الجداد. المشكلة مع بنية REST التقليدية في المشاريع الكبيرة والمعقدة الها وجهين: Over-fetching و Under-fetching.

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

هاي المشكلة اللي حكيت عنها في القصة. باختصار، هي لما الـ API ترجعلك بيانات أكتر بكتير من اللي بتحتاجه. تخيل إنك طلبت من النادل كوب ماء، فجابلك معاه كل المشروبات الموجودة في المطعم!

مثال عملي:

لجلب بيانات مستخدم، بنعمل طلب GET على: /api/posts/1

الرد اللي بيجينا ممكن يكون هيك:

{
  "id": 1,
  "title": "مقدمة في الذكاء الاصطناعي",
  "content": "محتوى المقال الطويل جداً...",
  "published_at": "2023-10-27T10:00:00Z",
  "author": {
    "id": 123,
    "name": "أبو عمر",
    "email": "abu.omar@example.com",
    "bio": "مبرمج فلسطيني يحب الشاي والبرمجة.",
    "address": "مكان ما في هذا العالم",
    "followers_count": 5000
  },
  "comments": [
    { "id": 101, "text": "مقال رائع!", "user": "متابع1" },
    { "id": 102, "text": "شكراً للمعلومات", "user": "متابع2" }
  ]
}

طيب، لو أنا في الواجهة الأمامية كل اللي بدي أعرضه هو عنوان المقال (title) واسم الكاتب (author.name)؟ كل البيانات التانية هاي (المحتوى، الإيميل، التعليقات…) تعتبر Over-fetching. حمل زايد على الشبكة، ومعالجة إضافية على جهاز العميل بدون أي فايدة.

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

هاي هي الوجه الآخر للمشكلة. وهي لما الـ endpoint ما يرجعلك كل البيانات اللي بتحتاجها، فتضطر تعمل طلبات إضافية (multiple requests) عشان تكمل بياناتك. هاي المشكلة مشهورة باسم “N+1 Query Problem”.

مثال عملي:

تخيل عندك صفحة بتعرض قائمة بـ 10 مقالات، ولكل مقال بدك تعرض اسم الكاتب. الـ endpoint تبع قائمة المقالات /api/posts بيرجعلك بس معلومات المقالات بدون تفاصيل الكاتب:

[
  { "id": 1, "title": "مقدمة في الذكاء الاصطناعي", "author_id": 123 },
  { "id": 2, "title": "تعلم GraphQL", "author_id": 123 },
  ... 10 مقالات
]

هون إنت مضطر تعمل طلب أول (1) عشان تجيب المقالات، وبعدين لكل مقال من العشرة (N=10) تعمل طلب جديد عشان تجيب معلومات الكاتب من خلال author_id. يعني /api/users/123، وهكذا. المجموع: 1 + 10 = 11 طلب للـ API عشان تعرض صفحة واحدة بسيطة! مصيبة.

GraphQL: طوق النجاة الذي أنقذنا

في عز هاي الفوضى، سمعنا عن تقنية جديدة اسمها GraphQL. في البداية، زي أي مبرمج “خِتيار”، كنت متشكك. “شو هالتكنولوجيا الجديدة اللي بدها تحل كل مشاكل الدنيا؟ أكيد مجرد موضة وبتعدي”. بس لما قرأنا عنها أكتر وجربناها، اكتشفنا إنها الحل اللي كنا بندور عليه.

GraphQL هي لغة استعلام (Query Language) للـ APIs، وفكرة عملها بسيطة وعبقرية: العميل (Client) هو اللي بقرر شو البيانات اللي بده إياها بالزبط، لا زيادة ولا نقصان.

بدل ما يكون عندك مئات الـ endpoints، صار عندك endpoint واحد فقط (عادة /graphql). العميل بيبعت لهذا الـ endpoint “استعلام” (Query) بيوصف فيه شكل البيانات اللي محتاجها، والسيرفر بيرجعله JSON بنفس الشكل تماماً.

كيف حلت GraphQL مشاكلنا؟

خلينا نرجع لنفس الأمثلة اللي فوق ونشوف كيف GraphQL بتتعامل معها.

حل مشكلة الـ Over-fetching

بدل ما أطلب /api/posts/1 وأستقبل كل إشي، الآن ببعت طلب POST للـ endpoint الوحيد /graphql ومعه هذا الاستعلام:

query {
  post(id: "1") {
    title
    author {
      name
    }
  }
}

شو تتوقع الجواب؟ بالضبط اللي طلبته:

{
  "data": {
    "post": {
      "title": "مقدمة في الذكاء الاصطناعي",
      "author": {
        "name": "أبو عمر"
      }
    }
  }
}

شايفين الجمال؟ لا محتوى، ولا إيميل، ولا تعليقات. طلبت عنوان واسم، أجاك عنوان واسم. تطبيق الموبايل بيقدر يطلب بيانات خفيفة، وتطبيق الويب بيقدر يطلب بيانات مفصلة، والاتنين بيستخدموا نفس الـ API وبدون ما فريق الـ Backend يكتب سطر كود إضافي.

حل مشكلة الـ Under-fetching (N+1)

طيب، وقصة قائمة المقالات وأسماء الكتاب؟ بكل بساطة، بنعمل استعلام واحد بيطلب كل اللي بدنا إياه دفعة واحدة:

query {
  posts {
    title
    author {
      name
    }
  }
}

والسيرفر الذكي (بمساعدة مكتبات زي Apollo أو Relay) راح يفهم هذا الطلب ويجيب كل البيانات من قاعدة البيانات بطلب واحد أو طلبين بالكتير، ويرجعلك النتيجة النهائية مرة واحدة. لا 11 طلب ولا وجع راس.

مفاهيم أساسية في GraphQL

عشان تبدأ صح مع GraphQL، في كم مفهوم لازم تعرفهم:

  • Schema (المخطط): هو عقد الاتفاق بين العميل والسيرفر. السيرفر بيعرّف كل أنواع البيانات اللي بيقدر يقدمها (Users, Posts, Comments) والحقول اللي داخل كل نوع. هذا بيخلي الـ API موثقة ذاتياً (Self-documenting).
  • Queries (الاستعلامات): لقرآءة أو جلب البيانات. زي ما شفنا في الأمثلة.
  • Mutations (التعديلات): لتغيير البيانات (إضافة، تعديل، حذف). بتشبه فكرة POST/PUT/DELETE في REST. مثال:
mutation {
  createPost(title: "مقال جديد", content: "محتوى...") {
    id
    title
  }
}
  • Subscriptions (الاشتراكات): للحصول على تحديثات لحظية (Real-time). تخيل إنك بتقدر “تشترك” في التعليقات على مقال معين، وكل ما مستخدم جديد يضيف تعليق، السيرفر يبعتلك إياه فوراً بدون ما تحتاج تعمل refresh. هاي قوة خارقة للـ GraphQL.

نصيحة من خبرة أبو عمر

لا تفكر في GraphQL كبديل كامل لـ REST. فكر فيها كأداة أخرى في صندوق أدواتك. للمشاريع البسيطة جداً أو الـ APIs اللي بتتعامل مع موارد واضحة ومحددة (Resource-oriented)، قد يكون REST أسرع وأسهل في التنفيذ. لكن بمجرد ما مشروعك يكبر ويصير عندك واجهات متعددة (web, mobile, etc.) ومتطلبات بيانات متغيرة، هنا يتألق GraphQL ويصبح المنقذ الحقيقي. لا تخاف من استخدامهما معاً في نفس النظام، كلٌّ حسب الحاجة.

الخلاصة: هل يجب أن أتعلم GraphQL اليوم؟

جوابي القاطع: نعم. الانتقال من فوضى الـ Endpoints المتعددة ومشاكل الـ Over-fetching إلى نظام GraphQL كان نقلة نوعية في طريقة تفكيرنا وتطويرنا للبرمجيات. أعطى قوة ومرونة لفريق الواجهات الأمامية (Frontend) بدون ما يسبب ضغط إضافي على فريق الواجهات الخلفية (Backend).

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

إذا كنت لسا بتستخدم REST بالطريقة التقليدية وبتعاني من نفس المشاكل اللي حكيت عنها، صدقني، جرّب GraphQL… وحتدعيلي. 😉

بالتوفيق في رحلتكم البرمجية!

أبو عمر

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

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

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

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

آخر المدونات

الحوسبة السحابية

كانت فاتورة السحابة تلتهم ميزانيتنا: كيف أنقذتنا ‘ممارسات FinOps’ من جحيم الإنفاق غير المراقب؟

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

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

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

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

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

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

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

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

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

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

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

كانت أعطالنا ألغازاً بلا خيوط: كيف أنقذنا ‘التتبع الموزع’ من جحيم البحث في سجلات متفرقة؟

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

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

كان الجميع يخشى قول ‘لا أعرف’: كيف أنقذتنا ‘ثقافة الأمان النفسي’ من جحيم الأخطاء الصامتة؟

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

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

كانت اختباراتنا خضراء لكنها عمياء: كيف أنقذنا ‘اختبار الطفرات’ (Mutation Testing) من جحيم الثقة الزائفة؟

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

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