مقدمة إلى GraphQL مع PHP: لماذا يستحق التجربة
\n\nGraphQL هي لغة استعلام حديثة لواجهات برمجة التطبيقات (API)، طورتها Facebook. على عكس REST، حيث يعيد كل نقطة نهاية بنية بيانات ثابتة، يسمح GraphQL للعميل بطلب الحقول التي يحتاجها فقط. هذا يقلل من حجم البيانات المنقولة ويبسط تطوير التطبيقات المعقدة.
\n\nفي هذا الدليل التعليمي، سننشئ واجهة برمجة تطبيقات GraphQL كاملة باستخدام PHP مع مكتبة webonyx/graphql-php. ستتعلم كيفية تعريف المخطط، كتابة المحللات، معالجة الاستعلامات والتحويرات، وكذلك اختبار واجهة API عبر GraphiQL.
\n\nمن المفترض أن يكون لديك PHP 8.0+ و Composer مثبتين. إذا لم يكن الأمر كذلك، فابدأ بتثبيتهما.
\n\nتثبيت المشروع وإعداده
\n\nالخطوة 1: إنشاء المشروع وتثبيت التبعيات
\n\nأنشئ دليلاً جديداً للمشروع وقم بتهيئة Composer:
\n\nmkdir graphql-php-tutorial\ncd graphql-php-tutorial\ncomposer init\n\nقم بتثبيت مكتبة webonyx/graphql-php:
composer require webonyx/graphql-php\n\nقم أيضاً بتثبيت nikic/fast-route لتوجيه بسيط (اختياري ولكنه مفيد):
composer require nikic/fast-route\n\nالخطوة 2: هيكل المشروع
\n\nأنشئ هيكل المجلدات التالي:
\n\ngraphql-php-tutorial/\n├── src/\n│ ├── Schema/\n│ │ └── schema.php\n│ ├── Resolvers/\n│ │ ├── QueryResolver.php\n│ │ └── MutationResolver.php\n│ └── Data/\n│ └── Database.php\n├── public/\n│ └── index.php\n├── vendor/\n└── composer.json\n\nإنشاء مخطط GraphQL
\n\nالخطوة 3: تعريف الأنواع والمخطط
\n\nلننشئ نموذج بيانات بسيط: مستخدم (User) ومنشور (Post). افتح src/Schema/schema.php وأضف الكود التالي:
<?php\n\nnamespace App\\Schema;\n\nuse GraphQL\\Type\\Definition\\ObjectType;\nuse GraphQL\\Type\\Definition\\Type;\nuse GraphQL\\Type\\Schema as GraphQLSchema;\n\nclass Schema\n{\n public static function build(): GraphQLSchema\n {\n // نوع User\n $userType = new ObjectType([\n 'name' => 'User',\n 'fields' => [\n 'id' => Type::int(),\n 'name' => Type::string(),\n 'email' => Type::string(),\n 'posts' => [\n 'type' => Type::listOf(function() use (&$postType) {\n return $postType;\n }),\n 'resolve' => function($user) {\n return \\App\\Resolvers\\QueryResolver::getPostsByUser($user['id']);\n }\n ]\n ]\n ]);\n\n // نوع Post\n $postType = new ObjectType([\n 'name' => 'Post',\n 'fields' => [\n 'id' => Type::int(),\n 'title' => Type::string(),\n 'content' => Type::string(),\n 'author' => [\n 'type' => $userType,\n 'resolve' => function($post) {\n return \\App\\Resolvers\\QueryResolver::getUserById($post['author_id']);\n }\n ]\n ]\n ]);\n\n // النوع الجذر Query\n $queryType = new ObjectType([\n 'name' => 'Query',\n 'fields' => [\n 'users' => [\n 'type' => Type::listOf($userType),\n 'resolve' => function() {\n return \\App\\Resolvers\\QueryResolver::getAllUsers();\n }\n ],\n 'user' => [\n 'type' => $userType,\n 'args' => [\n 'id' => Type::nonNull(Type::int())\n ]