GraphQL مقابل REST
افهم متى يتفوّق GraphQL على REST ولماذا
GraphQL مقابل REST درس مجاني في PHP Academy على CoddyKit. هذا هو الدرس 1 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في PHP Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة PHP Academy 4 دروس في المجموع.
لماذا GraphQL؟
أنتم تعرفون بالفعل كيفية إطلاق REST APIs في PHP. GraphQL ليس بديلًا عن HTTP ولا حلًا سحريًا — بل هو لغة استعلام ونظام أنواع يتيح للعميل وصف ما يحتاج إليه بالضبط والحصول على ذلك بالضبط، في رحلة ذهاب وإياب واحدة.
في هذا الدرس نقارن بينهما بإنصاف: المواضع التي يتفوق فيها GraphQL حقًا، والمواضع التي يظل فيها REST هو الخيار الصحيح، والتكلفة التشغيلية التي يفرضها GraphQL.
الجلب الزائد والجلب الناقص
نقاط الألم الكلاسيكية في REST:
- الجلب الزائد:
GET /users/1يعيد 40 حقلًا بينما تحتاج واجهة المستخدم إلى 3. - الجلب الناقص: لعرض منشورات مستخدم وعدد التعليقات لكل منشور، تستدعي
/users/1، ثم/users/1/posts، ثم N من نقاط نهاية التعليقات.
يجمع GraphQL هذا في طلب وصفي واحد.
query {
user(id: 1) {
name
posts {
title
commentCount
}
}
}نقطة نهاية واحدة ومخطط محدد الأنواع
يعرض REST عناوين URL كثيرة؛ بينما يعرض GraphQL نقطة نهاية واحدة (عادةً POST /graphql) يدعمها مخطط محدد الأنواع بقوة. المخطط هو العقد — ويمكن فحصه، لذلك تتوفر أدوات (الإكمال التلقائي والتوثيق وتوليد الشيفرة) مجانًا.
فيما يلي مخطط مصغّر بلغة SDL. ويكون شكل كل استجابة ممكنة معروفًا مسبقًا.
type User {
id: ID!
name: String!
posts: [Post!]!
}
type Post {
id: ID!
title: String!
commentCount: Int!
}
type Query {
user(id: ID!): User
}تعكس الاستجابة الاستعلام
خاصية أساسية: يمكن التنبؤ بشكل استجابة JSON من الاستعلام. لا يضطر العملاء إلى تخمين أسماء الحقول. ويلغي ذلك فئة كاملة من مشكلات تغيّر الإصدارات — يمكنكم إضافة حقول دون كسر العملاء القدامى، وإهمال الحقول باستخدام @deprecated بدلًا من قطع عناوين /v2.
{
"data": {
"user": {
"name": "Ada",
"posts": [
{ "title": "On Engines", "commentCount": 12 }
]
}
}
}متى يتفوق GraphQL على REST
يكون GraphQL الخيار الأقوى عندما:
- تخدمون عملاء متنوعين كثيرين (الويب وiOS وAndroid) باحتياجات مختلفة للبيانات.
- تكون البيانات رسمًا بيانيًا يحوي علاقات عميقة يتنقل العملاء خلالها ديناميكيًا.
- تريدون تجميع واجهات خلفية متعددة خلف بوابة واحدة محددة الأنواع.
- يهمكم التكرار السريع لتطوير الواجهة الأمامية، وتريدون تجنب التغييرات المستمرة في نقاط نهاية الواجهة الخلفية.
متى يظل REST الخيار الأفضل
لا تلجؤوا إلى GraphQL تلقائيًا. يكون REST أبسط وغالبًا أفضل عندما:
- تحتاجون إلى التخزين المؤقت عبر HTTP — إذ تعتمد ذاكرات CDN/edge المؤقتة على عناوين URL والأفعال؛ أما
POST /graphqlالواحد فيكون غير شفاف بالنسبة إليها. - تكون واجهة API موجّهة نحو الموارد ومستقرة (عمليات CRUD على عدد قليل من الكيانات).
- تعتمدون على تحميل الملفات أو تنزيلها أو على البث، حيث يُعدّ multipart ونطاقات البايت من الإمكانات الأساسية في REST.
- يكون المستهلكون من جهات خارجية ويتوقعون دلالات REST التقليدية.
مقارنة سريعة بين PHP
فيما يلي البيانات نفسها مجمّعة بالطريقة المعتمدة في REST باستخدام PHP — لاحظوا أن العميل سيظل بحاجة إلى عدة استدعاءات، أو سيتعين عليكم إنشاء معلمة embed يدويًا. أما GraphQL فينقل منطق الاختيار هذا إلى العميل.
<?php
// REST: server decides the payload shape
function userResource(int $id): array {
return [
'id' => $id,
'name' => 'Ada',
'email' => 'ada@example.com', // over-fetched by mobile
'createdAt' => '1815-12-10',
'posts' => [ // pre-embedded, all-or-nothing
['title' => 'On Engines', 'commentCount' => 12],
],
];
}
header('Content-Type: application/json');
echo json_encode(userResource(1), JSON_PRETTY_PRINT);
التكاليف التي يضيفها GraphQL
ينقل GraphQL التعقيد إلى الخادم، فتتحملون الآن مسؤولية مخاوف جديدة:
- استعلامات N+1 — تنفّذ المحللات المتداخلة استعلامًا واحدًا لقاعدة البيانات لكل عقدة ما لم تجمعوها (باستخدام DataLoader).
- تحديد تكلفة الاستعلام / عمقه — قد يؤدي استعلام ضار ومتداخل بعمق إلى DoS لخدمتكم.
- يصبح التخزين المؤقت أصعب؛ إذ تضعون عادةً ذاكرة التخزين المؤقت في طبقة المحلّل/البيانات، وليس على مستوى HTTP.
- تختلف معالجة الأخطاء — فقد تحمل الاستجابة
errorsحتى مع رمز200 OK.
الأخطاء: الرمز 200 مع مصفوفة errors
على خلاف رموز حالة REST، يعيد GraphQL عادةً استجابة HTTP تحمل الرمز 200، ويبلّغ عن الإخفاقات الجزئية داخل نص الاستجابة. قد تكون data معبّأة جزئيًا، بينما تسرد errors ما فشل. يجب على عملائكم فحص الاثنين.
{
"data": { "user": null },
"errors": [
{
"message": "User not found",
"path": ["user"],
"extensions": { "code": "NOT_FOUND" }
}
]
}قاعدة اتخاذ القرار
قاعدة إرشادية عملية:
- واجهات API عامة، كثيرة الاعتماد على التخزين المؤقت، وتنفّذ CRUD على الموارد → REST.
- واجهات API داخلية أو خاصة بالمنتج تغذي عملاء متنوعين وغنيين عبر بيانات مترابطة → GraphQL.
- خلفيات متعددة تريدون توحيدها خلف عقد typed واحد → بوابة GraphQL.
من الشائع والمفيد تشغيل كليهما: REST لخطافات الويب وعمليات تحميل الملفات، وGraphQL لرسم القراءة البياني للتطبيق.
تقديم GraphQL عبر HTTP باستخدام PHP
من الناحية التشغيلية، تكون نقطة نهاية GraphQL في PHP مسارًا واحدًا يقرأ نص JSON، ويستخرج منه query وvariables، وينفذهما مقابل المخطط، ثم يعيد { data, errors }. وبالمقارنة مع مسارات REST المتعددة، يكون النقل موحّدًا — إذ يكمن كل الاختلاف في سلسلة الاستعلام التي يرسلها العميل.
<?php
// Minimal GraphQL-over-HTTP entry point
$input = json_decode(file_get_contents('php://input'), true) ?? [];
$query = $input['query'] ?? '';
$variables = $input['variables'] ?? null;
// $result = GraphQL::executeQuery($schema, $query, null, $ctx, $variables);
// header('Content-Type: application/json');
// echo json_encode($result->toArray());
var_dump(['query' => $query, 'variables' => $variables]);
اختبار سريع
متى يحتفظ REST بميزة واضحة على GraphQL؟
مراجعة
قارنتم بين GraphQL وREST من حيث الجوهر:
- يعالج GraphQL مشكلة جلب بيانات أكثر أو أقل من المطلوب باستخدام نقطة نهاية واحدة typed واختيار يحدده العميل.
- يتفوق عند التعامل مع عملاء متعددين، وبيانات على شكل رسم بياني، وتجميع الخلفيات.
- يبقى REST قويًا في واجهات API العامة القابلة للتخزين المؤقت، وعمليات CRUD البسيطة، وتحميل الملفات، والعملاء الذين يتوقعون الأساليب التقليدية.
- ينقل GraphQL التكلفة إلى الخادم: استعلامات N+1، وحدود تكلفة الاستعلام، والتخزين المؤقت، ودلالات 200 مع الأخطاء.
التالي: بناء مخطط فعلي باستخدام webonyx/graphql-php.
الأسئلة الشائعة
هل درس «GraphQL مقابل REST» مجاني؟
نعم — نص درس «GraphQL مقابل REST» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة PHP Academy، انتقل إلى CoddyKit PRO. تتضمن دورة PHP Academy 4 دروس في المجموع.
ماذا ستتعلم في «GraphQL مقابل REST»؟
افهم متى يتفوّق GraphQL على REST ولماذا تتمرن على PHP Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ PHP Academy؟
لا تُشترط خبرة سابقة. PHP Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 1 من أصل 4.
كم من الوقت يستغرق درس «GraphQL مقابل REST»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس PHP Academy هذا؟
نعم. كل درس في PHP Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- GraphQL مقابل REST
- بناء مخطط باستخدام graphql-php
- المحللات والطفرات والاشتراكات
- الأداء: N+1 وDataLoader