GraphQL: كيف أنقذنا واجهاتنا من جحيم الطلبات المتعددة والبيانات الزائدة؟

يا جماعة الخير، السلام عليكم ورحمة الله.

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

لحد ما يوم، إجانا مدير المشروع وجهه أحمر ومعصّب، وبحكي: “يا أبو عمر، شو القصة؟ التطبيق بطيء جداً على الموبايل، خصوصاً على النت الضعيف. المستخدمين بشتكوا!”. طبعاً أول ناس بتتجه إلهم الأنظار في هالحالات هم جماعة الباك-إند. حسينا حالنا زي اللي واقف في المحكمة والكل بتهمه.

قعدنا، فتحنا القهوة، وشغلنا أدوات المراقبة. ولما طلعنا على سجلات الشبكة من تطبيق الموبايل، لقينا المصيبة. شاشة البروفايل الرئيسية لحالها كانت بتعمل حوالي 7-8 طلبات API مختلفة! طلب عشان يجيب معلومات المستخدم، وطلب عشان يجيب منشوراته، وطلب عشان يجيب عدد المتابعين، وطلب للإشعارات… شلال من الطلبات (Waterfall) واحد ورا الثاني. والأسوأ من هيك، إنه كل طلب كان برجع كتل ضخمة من البيانات (JSON)، 90% منها التطبيق ما كان بحتاجها أصلاً في هاي الشاشة.

هنا أدركت إنه مشكلتنا مش في سرعة الخوادم، مشكلتنا في “معمارية” الواجهات البرمجية نفسها. كنا غرقانين في جحيم الـ REST API التقليدي. ومن هداك اليوم، بدأت رحلتي مع حل غيّر طريقة تفكيرنا تماماً: GraphQL.

جحيم الواجهات البرمجية التقليدية (REST APIs)

قبل ما ننتقل للحل، خلينا نفهم أصل المشكلة. معمارية REST هي السائدة والممتازة لكثير من الحالات، وهي قائمة على فكرة “المصادر” (Resources). كل شيء هو مصدر له عنوان URL خاص فيه (endpoint). بدك مستخدم؟ روح على /users/123. بدك منشوراته؟ روح على /users/123/posts. بسيطة وواضحة، لكن هاي البساطة بتخلق مشكلتين رئيسيتين لما التطبيقات تتعقد.

المشكلة الأولى: الجلب الزائد (Over-fetching)

هاي المشكلة بتصير لما الواجهة البرمجية ترجعلك بيانات أكثر من اللي بتحتاجها. تخيل إنك في شاشة رئيسية وبدك تعرض بس اسم المستخدم وصورته الرمزية. بتعمل طلب لـ GET /api/v1/users/123، والرد اللي بيجيك بكون هيك:


{
  "id": 123,
  "username": "abu_omar_dev",
  "firstName": "عمر",
  "lastName": "أحمد",
  "email": "omar@example.com",
  "avatarUrl": "https://example.com/avatar.jpg",
  "bio": "مبرمج فلسطيني بحب القهوة والكود النظيف...",
  "dateOfBirth": "1985-05-10",
  "lastLogin": "2023-10-27T10:00:00Z",
  "followersCount": 5000,
  "followingCount": 150,
  "address": {
    "street": "شارع القدس",
    "city": "نابلس",
    "country": "فلسطين"
  },
  "isActive": true,
  "createdAt": "2020-01-15T08:30:00Z"
  // ... و 30 حقل زيادة
}

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

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

هاي المشكلة هي الوجه الآخر للعملة. بتصير لما الطلب الواحد ما يرجع كل البيانات اللي بتحتاجها، فتضطر تعمل طلبات إضافية. هاي هي مشكلة “الشلال” (Network Waterfall) اللي حكيت عنها في قصتي.

لنعرض صفحة بروفايل كاملة، الواجهة الأمامية كانت بتعمل الآتي:

  1. الطلب الأول: GET /api/users/123 للحصول على معلومات المستخدم.
  2. انتظر… وصل الرد.
  3. الطلب الثاني: GET /api/users/123/posts للحصول على منشورات المستخدم.
  4. انتظر… وصل الرد.
  5. الطلب الثالث: GET /api/users/123/followers للحصول على قائمة المتابعين.
  6. وهكذا…

كل طلب يعتمد على اللي قبله، والنتيجة هي وقت تحميل طويل وتجربة مستخدم سيئة. والمصيبة الأكبر هي لما يكون عندك واجهات مختلفة (موبايل، ويب، ساعة ذكية). كل واجهة بتحتاج بيانات مختلفة، فهل الحل إنك تعمل endpoint مخصص لكل واجهة (/api/mobile/profile, /api/web/profile)؟ هذا طريق مباشر للفوضى والصيانة المستحيلة.

GraphQL.. الضو اللي بآخر النفق

GraphQL (لغة الاستعلام الرسومية) هي ليست مكتبة أو إطار عمل، بل هي “لغة استعلام” للواجهات البرمجية، تم تطويرها في فيسبوك لحل نفس المشاكل اللي واجهناها. الفكرة عبقرية وبسيطة: بدلاً من وجود عشرات الـ endpoints الثابتة، عندك endpoint واحد فقط (عادة /graphql) يتلقى “سؤال” من العميل ويجيب عليه بدقة متناهية.

نصيحة من أبو عمر: لا تفكر في GraphQL كبديل كامل لـ REST. فكر فيه كأداة قوية في صندوق أدواتك. أحياناً المطرقة هي الحل، وأحياناً المفك. REST ما زال ممتازاً للخدمات المصغرة (Microservices) البسيطة والواجهات التي تتعامل مباشرة مع الآلات.

كيف يعمل GraphQL؟ (الآلية المبسطة)

القوة كلها تكمن في ثلاث مفاهيم أساسية:

1. المخطط (Schema)

هذا هو “الدستور” أو العقد بين الواجهة الأمامية والخلفية. أنت كـ “باك-إند” بتعرّف أنواع البيانات اللي عندك والعلاقات بينها. هذا المخطط هو مصدر الحقيقة الأوحد (Single Source of Truth).

مثلاً، ممكن نعرّف أنواعنا هيك بلغة GraphQL:


type User {
  id: ID!
  username: String!
  avatarUrl: String
  posts: [Post!]
}

type Post {
  id: ID!
  title: String!
  content: String
  author: User!
}

type Query {
  user(id: ID!): User
}

هذا المخطط يقول بوضوح: عندنا نوع اسمه User ونوع اسمه Post. المستخدم له منشورات، والمنشور له كاتب (وهو من نوع User). وعندنا استعلام اسمه user يمكننا من جلب مستخدم معين عن طريق الـ ID تبعه.

2. الاستعلامات (Queries)

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

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


query GetUserProfile {
  user(id: "123") {
    username
    avatarUrl
    posts {
      title
    }
  }
}

هذا الاستعلام معناه: “يا سيرفر، أعطيني المستخدم اللي الـ ID تبعه 123. ومن هذا المستخدم، أنا فقط مهتم بـ username و avatarUrl. وبدي كمان منشوراته posts، ومن كل منشور أنا مهتم فقط بالعنوان title“.

والرد اللي بيجي من الخادم بكون صورة طبق الأصل عن شكل الطلب:


{
  "data": {
    "user": {
      "username": "abu_omar_dev",
      "avatarUrl": "https://example.com/avatar.jpg",
      "posts": [
        { "title": "مقدمة إلى GraphQL" },
        { "title": "أفضل ممارسات Node.js" },
        { "title": "القهوة والبرمجة" }
      ]
    }
  }
}

لاحظ الجمال هنا: طلب واحد، رد واحد، وبدون أي بيانات زائدة. حلينا مشكلة الـ Over-fetching والـ Under-fetching بضربة واحدة.

3. التعديلات (Mutations)

إذا كانت الـ Queries للقراءة، فالـ Mutations هي للكتابة (إنشاء، تحديث، حذف). الفكرة نفسها، تقوم بتعريف التعديلات الممكنة في المخطط، والعميل يستدعيها مع البيانات اللازمة.

مثلاً، لإنشاء منشور جديد:


mutation CreateNewPost {
  createPost(title: "تجربتي مع GraphQL", content: "المحتوى هنا...") {
    id
    title
  }
}

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

خلاصة الحكي.. والزبدة 🚀

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

  • هل يعني هذا أن REST ماتت؟ بالطبع لا. لكل أداة مكانها وزمانها.
  • هل GraphQL أصعب؟ نعم، هناك منحنى تعلم في البداية، خصوصاً في إعداد الخادم والمخطط. لكن الفائدة على المدى الطويل تستحق العناء.

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

يلا يا جماعة، شدوا حيلكم، والله يوفقكم في رحلتكم البرمجية.

أبو عمر

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

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

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

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

آخر المدونات

تسويق رقمي

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

في هذه المقالة، أشارككم قصة حقيقية عن كيفية تسبب أدوات حظر الإعلانات في فقدان بياناتنا التسويقية، وكيف كان "التتبع من جانب الخادم" (Server-Side Tracking) هو...

6 مايو، 2026 قراءة المزيد
تجربة المستخدم والابداع البصري

كان كل زر بلون مختلف: كيف أنقذنا ‘نظام التصميم’ (Design System) من جحيم الفوضى البصرية؟

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

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

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

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

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

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

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

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

من العمى التشغيلي إلى البصيرة الكاملة: رحلتي مع Prometheus و Grafana لإنقاذ أنظمتنا

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

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