GraphQL vs REST API: الفرق الكامل وأيهما أفضل لمشروعك – شرح الفروقات والأمثلة العملية

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

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

قعدت مع حالي ليلة، وفنجان القهوة السادة جنبي، وبحلل المشكلة. اكتشفت إن الشاشة الرئيسية لحالها كانت تعمل 3 طلبات API مختلفة عشان تجيب كل هالمعلومات. طلب لبيانات المستخدم (/user/profile)، وطلب للمطاعم القريبة (/restaurants?location=...)، وطلب للعروض (/promotions). كل طلب برجع بيانات، بعضها ما بنحتاجه أصلًا في هاي الشاشة. هان كانت المشكلة: طلبات كثيرة، وبيانات زيادة عن اللزوم.

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

خلونا اليوم نفصّل هالموضوع ونشوف شو القصة بين هالاثنين، ومين تختار لمشروعك.

ما هي REST API؟ (تذكير سريع)

قبل ما نقارن، لازم نكون على نفس الصفحة. REST (Representational State Transfer) هي مش بروتوكول، هي نمط معماري (Architectural Style) لتصميم الواجهات البرمجية (APIs). هي الطريقة اللي أغلبنا تعلمناها وبنستخدمها من سنين. الفكرة بسيطة:

  • كل شيء هو “مورد” (Resource)، مثل: مستخدم، منتج، مقالة.
  • لكل مورد عنوان فريد (Endpoint)، مثل: /users أو /products/:id.
  • نستخدم أفعال HTTP القياسية (HTTP Verbs) للتفاعل مع هاي الموارد:
    • GET: لجلب البيانات.
    • POST: لإنشاء بيانات جديدة.
    • PUT/PATCH: لتحديث البيانات.
    • DELETE: لحذف البيانات.

يعني باختصار، الـ Server هو اللي بقرر شكل البيانات اللي رح ترجع، والـ Client ما عليه إلا يطلب من عنوان معين وياخذ اللي بيجيه.

مشاكل REST API التي دفعت لظهور GraphQL

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

مشكلة الـ Over-fetching (إحضار بيانات أكثر من اللازم)

هاي المشكلة بتصير لما الـ Endpoint يرجعلك حقول وبيانات أنت مش بحاجتها. تخيل إنك بدك تعرض قائمة بأسماء المستخدمين فقط، بس الـ Endpoint اللي عندك هو GET /users وبرجعلك لكل مستخدم: الاسم، الإيميل، تاريخ الميلاد، العنوان، آخر تسجيل دخول، وكل قصة حياته. أنت بس بدك الاسم!

هاي البيانات الزيادة بتستهلك Bandwidth (حزمة الإنترنت) وبتبطئ تحميل البيانات، خصوصًا على تطبيقات الموبايل.

مشكلة الـ Under-fetching (إحضار بيانات أقل من اللازم)

هاي هي المشكلة الثانية اللي واجهتني. بتصير لما تحتاج بيانات من موارد مختلفة، فتضطر تعمل أكثر من طلب API. تخيل عندك شاشة لعرض مقالة (Post) مع تعليقاتها (Comments) ومعلومات كاتب المقالة (Author).

باستخدام REST، رح تحتاج غالبًا لـ 3 طلبات:

  1. GET /posts/123 (لجلب المقالة نفسها، وهنا بتاخذ id الكاتب).
  2. GET /users/45 (لجلب معلومات الكاتب صاحب الـ id رقم 45).
  3. GET /posts/123/comments (لجلب التعليقات على المقالة).

ثلاث رحلات ذهاب وإياب بين العميل (Client) والخادم (Server). هذا التأخير المتراكم (Latency) هو اللي بقتل أداء التطبيقات.

مرحبًا بـ GraphQL: لغة الاستعلام لواجهتك البرمجية

GraphQL، اللي طورتها فيسبوك سنة 2012 وأطلقتها كمشروع مفتوح المصدر في 2015، هي مش نمط معماري زي REST، بل هي لغة استعلام (Query Language) للـ API، وكمان بيئة تشغيلية (Runtime) لتنفيذ هاي الاستعلامات.

الفكرة عبقرية وبسيطة: بدل ما يكون عندك عشرات الـ Endpoints اللي الخادم بحدد شكلها، بكون عندك Endpoint واحد فقط (عادة /graphql).

العميل (Client) هو اللي بيبعت “استعلام” (Query) لهذا الـ Endpoint، وبحدد فيه بالضبط البيانات اللي بده إياها، وبالشكل اللي بده إياه. الخادم بقرأ هذا الاستعلام، وبجمع البيانات من مصادرها المختلفة (قواعد بيانات، خدمات أخرى…)، وبرجعها في استجابة واحدة (Response) مطابقة تمامًا لشكل الطلب.

نصيحة من أبو عمر: فكر في REST كأنك بتطلب وجبة محددة من قائمة طعام (Fixed Menu). أما GraphQL، فكأنك داخل على بوفيه مفتوح (Buffet) وبتعبي صحنك باللي بدك إياه بالضبط، وبالكمية اللي بدك إياها.

الـ Schema والـ Type System: عقد ملزم بين الطرفين

أهم ما يميز GraphQL هو نظام الأنواع (Type System). قبل ما تكتب أي كود، أنت بتعرّف “مخطط” أو “خريطة” (Schema) لكل البيانات اللي ممكن العميل يطلبها. هذا الـ Schema هو العقد الرسمي بين الـ Frontend والـ Backend.

الـ Schema بحدد أنواع البيانات (Types) مثل User, Product, Review، والحقول اللي داخل كل نوع، والعلاقات بينها.

مثال بسيط لـ Schema لمتجر إلكتروني:


type Product {
  id: ID!
  name: String!
  description: String
  price: Float!
  seller: User!
  reviews: [Review]
}

type User {
  id: ID!
  username: String!
  avatarUrl: String
}

type Review {
  id: ID!
  rating: Int!
  comment: String
  author: User!
}

# هذا هو النوع الرئيسي اللي بنبدأ منه الاستعلامات
type Query {
  product(id: ID!): Product
  products: [Product]
}

هذا الـ Schema المكتوب بلغة (Schema Definition Language – SDL) واضح جدًا. أي مطور Frontend بيقدر يشوفه ويعرف فورًا شو البيانات المتاحة وكيف يطلبها، بدون ما يسأل مطور الـ Backend.

المقارنة العملية: بناء API لمتجر إلكتروني

خلينا نرجع للمثال العملي ونشوف الفرق بشكل ملموس. بدنا نبني صفحة منتج تعرض: تفاصيل المنتج، معلومات البائع، وآخر 3 تقييمات على المنتج.

الطريقة باستخدام REST API

للحصول على هاي البيانات، الـ Frontend رح يضطر يعمل سلسلة من الطلبات:

  1. الطلب الأول: جلب المنتج.
    GET /api/products/prod_123
    الاستجابة ممكن تكون هيك (لاحظ الـ Over-fetching، يمكن ما نحتاج stock_quantity):
    
    {
      "id": "prod_123",
      "name": "كيبورد ميكانيكي",
      "description": "أفضل كيبورد للمبرمجين",
      "price": 99.99,
      "stock_quantity": 150,
      "sellerId": "user_789"
    }
    
  2. الطلب الثاني: جلب معلومات البائع.
    بناخذ sellerId من الطلب الأول وبنعمل طلب جديد:
    GET /api/users/user_789
    الاستجابة:
    
    {
      "id": "user_789",
      "username": "متجر أبو عمر للتقنية",
      "email": "contact@abouomar.tech",
      "memberSince": "2020-01-15T00:00:00Z",
      "avatarUrl": "https://.../avatar.png"
    }
    
  3. الطلب الثالث: جلب التقييمات.
    GET /api/products/prod_123/reviews?limit=3
    الاستجابة:
    
    [
      { "id": "rev_1", "rating": 5, "comment": "ممتاز جدا!", "authorId": "user_111" },
      { "id": "rev_2", "rating": 4, "comment": "جيد ولكنه صاخب قليلا", "authorId": "user_222" },
      ...
    ]
    

النتيجة: 3 طلبات منفصلة، زمن انتظار مضاعف، واحتمال كبير لوجود بيانات زائدة في كل استجابة.

الطريقة باستخدام GraphQL

هنا الوضع مختلف تمامًا. عنا Endpoint واحد: /graphql. الـ Frontend بيكتب استعلام واحد يصف كل ما يحتاجه:


query GetProductPageDetails {
  product(id: "prod_123") {
    id
    name
    description
    price
    seller {
      username
      avatarUrl
    }
    reviews(limit: 3) {
      rating
      comment
      author {
        username
      }
    }
  }
}

الخادم بستقبل هذا الطلب، وبيرجع استجابة واحدة فقط شكلها مطابق 100% للطلب:


{
  "data": {
    "product": {
      "id": "prod_123",
      "name": "كيبورد ميكانيكي",
      "description": "أفضل كيبورد للمبرمجين",
      "price": 99.99,
      "seller": {
        "username": "متجر أبو عمر للتقنية",
        "avatarUrl": "https://.../avatar.png"
      },
      "reviews": [
        {
          "rating": 5,
          "comment": "ممتاز جدا!",
          "author": {
            "username": "ahmad_dev"
          }
        },
        {
          "rating": 4,
          "comment": "جيد ولكنه صاخب قليلا",
          "author": {
            "username": "sara_codes"
          }
        }
      ]
    }
  }
}

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

أركان GraphQL الثلاثة

GraphQL مش بس للقراءة، فيها 3 عمليات أساسية:

1. Queries (للقراءة)

زي ما شفنا، هي لطلب وجلب البيانات. أنت بتحدد شو بدك والخادم بجيبلك ياه.

2. Mutations (للتعديل)

هي المعادل لعمليات POST, PUT, DELETE في REST. بنستخدمها لإنشاء أو تحديث أو حذف البيانات. الفرق إنها كمان مرنة، بتقدر تطلب بيانات معينة ترجعلك بعد إتمام العملية. مثلاً، بعد إضافة تقييم جديد، بتقدر تطلب القائمة المحدثة للتقييمات في نفس الاستجابة.

مثال لـ Mutation لإضافة تقييم:


mutation AddReviewToProduct {
  addReview(productId: "prod_123", rating: 5, comment: "تجربة شراء رائعة!") {
    id
    rating
    comment
  }
}

هنا نحن نضيف تقييمًا جديدًا، ونطلب من الخادم أن يعيد لنا تفاصيل التقييم الذي تم إنشاؤه للتو.

3. Subscriptions (للبيانات الحية)

هاي من أقوى ميزات GraphQL. بتسمح للعميل إنه “يشترك” (Subscribe) في حدث معين على الخادم، وكل ما يصير هذا الحدث، الخادم بيبعت تحديث للعميل بشكل فوري عبر اتصال مفتوح (عادة WebSockets).

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

مثال لـ Subscription:


subscription OnNewReview {
  newReview(productId: "prod_123") {
    id
    rating
    comment
    author {
      username
    }
  }
}

تحقيق هذا الأمر باستخدام REST يتطلب حلول معقدة مثل الـ Long Polling أو Webhooks، بينما GraphQL تقدمه كجزء أساسي من مواصفاتها.

إذًا، متى أستخدم REST ومتى أستخدم GraphQL؟ (نصيحة أبو عمر)

السؤال الذهبي: أيهما أفضل؟ الجواب، كالعادة في البرمجة: “يعتمد”. كل تقنية إلها مكانها وزمانها.

حالات أنصح فيها بالبقاء مع REST

  • المشاريع البسيطة: إذا كنت تبني تطبيق CRUD بسيط (Create, Read, Update, Delete) والبيانات مش متداخلة كثير، REST أسرع في الإعداد وأسهل للفريق.
  • الـ APIs العامة البسيطة: إذا كنت تقدم API بسيطة جدًا ومواردها واضحة ومحددة (مثل API للطقس)، REST قد يكون كافيًا وأكثر شيوعًا.
  • عندما يكون الأداء ليس المشكلة الأكبر: إذا كان تطبيقك لا يعاني من مشاكل Over/Under-fetching، فربما لا تحتاج لتعقيد GraphQL.
  • الخدمات المصغرة (Microservices): في بنية الخدمات المصغرة، كل خدمة تكون مسؤولة عن مورد واحد فقط. هنا REST يكون خيارًا ممتازًا للتواصل بين الخدمات. (معلومة إضافية: يمكن بناء GraphQL Gateway فوق هذه الخدمات المصغرة لتوحيدها للعميل).

حالات أنصح فيها بالانتقال إلى GraphQL

  • تطبيقات الموبايل أولًا (Mobile-first): حيث تكون سرعة الشبكة وحجم البيانات المنقولة عوامل حاسمة. المرونة في طلب البيانات بالضبط هي ميزة قاتلة هنا.
  • التطبيقات ذات الواجهات المعقدة: مثل لوحات التحكم (Dashboards) أو التطبيقات التي تعرض بيانات من مصادر متعددة في شاشة واحدة.
  • عند وجود عملاء متعددين (Web, Mobile, IoT): كل عميل له احتياجات بيانات مختلفة. بدل بناء Endpoints مخصصة لكل واحد، GraphQL يسمح لكل عميل بطلب ما يحتاجه فقط.
  • عندما تريد تسريع عملية التطوير للـ Frontend: مطورو الواجهات الأمامية يحصلون على استقلالية أكبر. لا حاجة لانتظار مطور الـ Backend ليضيف حقلًا بسيطًا. إذا كان موجودًا في الـ Schema، يمكنهم طلبه فورًا.

  • التطبيقات التي تحتاج ميزات الوقت الحقيقي (Real-time): إذا كانت الـ Subscriptions (مثل الإشعارات الفورية، الدردشة، تحديثات البيانات الحية) جزءًا أساسيًا من تطبيقك، فـ GraphQL هو خيارك الأمثل.

خلاصة الكلام والنصيحة الأخيرة 🚀

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

  • REST API مثل سيارة صالون عائلية: موثوقة، معروفة للجميع، وتقوم بالمهمة بكفاءة في معظم الحالات اليومية. هي الخيار القياسي والآمن.
  • GraphQL مثل سيارة دفع رباعي مخصصة للطرق الوعرة: تحتاج لبعض الإعداد والخبرة في البداية، لكنها تمنحك قوة ومرونة هائلة للتعامل مع التضاريس الصعبة والبيانات المعقدة والمتشابكة.

نصيحتي الأخيرة: لا تتبع “الموضة” البرمجية بشكل أعمى. افهم مشكلتك جيدًا. هل تعاني حقًا من مشاكل Over/Under-fetching؟ هل تحتاج إلى المرونة التي تقدمها GraphQL؟ إذا كانت الإجابة “نعم”، فاستثمر الوقت لتعلمها وتطبيقها. إذا كان مشروعك بسيطًا ومباشرًا، فـ REST سيخدمك بشكل ممتاز.

وإذا كنت مترددًا، يمكنك دائمًا البدء بشكل هجين، ببناء واجهة GraphQL تعمل كـ “بوابة” (Gateway) فوق واجهات REST API الموجودة لديك. هذا يسمح لك بالحصول على أفضل ما في العالمين.

أتمنى يكون هذا الشرح المفصل قد أوضح الصورة. بالتوفيق في مشاريعكم القادمة!

أبو عمر

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

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

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

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

آخر المدونات

أتمتة العمليات

قهوتك الصباحية مع ملخص الإنجازات: كيف تبني داشبورد يومي يصلك على الموبايل باستخدام n8n والذكاء الاصطناعي

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

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