GraphQL 和 PHP 入门
GraphQL 是一种由 Facebook 开发的 API 查询语言,它允许客户端只请求他们真正需要的数据。与 REST 不同,REST 的每个端点返回固定的数据结构,而 GraphQL 提供了灵活性和效率。如果您正在使用 PHP 并希望引入现代 API,本教程适合您。
在本指南中,我们将使用 webonyx/graphql-php 库创建一个简单但功能完整的 GraphQL API。您将学习如何安装依赖项、定义 schema、类型、解析器以及处理查询。代码示例将帮助您快速上手。
1. 环境准备和安装依赖项
首先,确保您已安装 PHP 7.4 或更高版本以及 Composer(PHP 的依赖管理器)。如果尚未安装 Composer,请从官方网站下载。
创建一个新项目并安装 webonyx/graphql-php 库:
mkdir graphql-php-tutorialcd graphql-php-tutorialcomposer init --name="myapp/graphql-demo" --type="project" --no-interactioncomposer require webonyx/graphql-php安装完成后,项目文件夹中会出现 vendor 目录和 composer.json 文件。同时创建一个 index.php 文件——我们的所有代码都将放在这里。
此外,为了方便处理 HTTP 请求,请安装 laminas/laminas-diactoros(一个流行的 PSR-7 实现)和 laminas/laminas-httphandlerrunner:
composer require laminas/laminas-diactoroscomposer require laminas/laminas-httphandlerrunner2. 定义 GraphQL Schema 和类型
任何 GraphQL API 的核心都是 schema。它描述了哪些数据可用以及如何查询这些数据。在我们的示例中,我们将创建一个简单的"用户"(User)和"帖子"(Post)模型。
首先,使用 GraphQL\\Type\\Definition\\ObjectType 类定义类型。创建一个 schema.php 文件(或者直接将代码添加到 index.php 中)。
<?phprequire_once __DIR__ . '/vendor/autoload.php';
use GraphQL\\Type\\Definition\\ObjectType;use GraphQL\\Type\\Definition\\Type;use GraphQL\\Type\\Schema;use GraphQL\\GraphQL;
// 定义 User 类型$userType = new ObjectType([ 'name' => 'User', 'description' => '表示系统用户', 'fields' => [ 'id' => Type::int(), 'name' => Type::string(), 'email' => Type::string(), ]]);
// 定义 Post 类型$postType = new ObjectType([ 'name' => 'Post', 'description' => '用户帖子', 'fields' => [ 'id' => Type::int(), 'title' => Type::string(), 'content' => Type::string(), 'author' => $userType, // 与用户的关联 ]]);请注意:我们使用了 Type::int() 和 Type::string()——这些是 GraphQL 内置的标量类型。author 字段引用了另一个对象类型,这允许构建嵌套查询。
3. 创建解析器和模拟数据
解析器(resolvers)是为每个字段返回数据的函数。在最简单的情况下,我们可以使用模拟数据(数组)。
为根 Query 类型添加解析器。客户端将通过它来获取数据。
// 模拟数据$users = [ 1 => ['id' => 1, 'name' => 'Ivan Petrov', 'email' => 'ivan@example.com'], 2 => ['id' => 2, 'name' => 'Maria Smirnova', 'email' => 'maria@example.com'],];
$posts = [ 1 => ['id' => 1, 'title' => 'First Post', 'content' => 'Content of the first post', 'author_id' => 1],