GraphQL 与 PHP 入门:为何值得一试
\n\nGraphQL 是一种由 Facebook 开发的现代 API 查询语言。与 REST 不同,REST 的每个端点返回固定数据结构,而 GraphQL 允许客户端仅请求所需的字段。这减少了数据传输量,并简化了复杂应用的开发。
\n\n在本教程中,我们将使用 webonyx/graphql-php 库创建一个完整的 GraphQL API。您将学习如何定义模式、编写解析器、处理查询和变更,以及通过 GraphiQL 测试 API。
\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 ]