GraphQL 与 REST 对比
了解 GraphQL 何时优于 REST,以及原因
GraphQL 与 REST 对比 是 CoddyKit 上的免费 PHP Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 PHP Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 PHP Academy 课程共包含 4 节课。
为什么选择 GraphQL
您已经知道如何用 PHP 发布 REST API。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/边缘缓存依据 URL 和动词建立缓存键;单一的
POST /graphql对它们来说是不透明的。 - API 面向资源且稳定(围绕少数实体执行增删改查)。
- 您依赖 文件上传/下载 或流式传输,而多部分传输和字节范围在 REST 中都是一等功能。
- 您的使用方是期待传统 REST 语义的第三方。
PHP 快速比较
下面是在 PHP 中以 REST 方式组装相同数据的示例——请注意,客户端仍然需要发起多次调用,或者由您手动构造嵌入参数。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),否则嵌套解析器会为每个节点执行一次数据库查询。
- 查询开销/深度限制——恶意的深层嵌套查询可能使您的服务遭受拒绝服务攻击。
- 缓存更困难;通常需要在解析器/数据层缓存,而不是使用 HTTP 缓存。
- 错误处理有所不同——一个 200 OK 响应仍然可能携带
errors数组。
错误:200 响应中的错误数组
不同于 REST 的状态码,GraphQL 通常返回 HTTP 200,并在响应体中报告部分失败。data 可能只填充了一部分,而 errors 会列出失败的内容。您的客户端必须同时检查这两者。
{
"data": { "user": null },
"errors": [
{
"message": "User not found",
"path": ["user"],
"extensions": { "code": "NOT_FOUND" }
}
]
}决策启发式规则
一个务实的经验法则是:
- 面向公众、重度依赖缓存、以资源增删改查为主 → REST。
- 为连接数据上的多样化富客户端提供服务的内部/产品 API → GraphQL。
- 需要将多个后端统一到一个类型化契约之后 → GraphQL 网关。
同时运行两者很常见,也很合理:使用 REST 处理网络钩子/上传,使用 GraphQL 处理应用的读取图。
在 PHP 中通过 HTTP 提供 GraphQL
从运维角度看,PHP 中的 GraphQL 端点就是一条路由:它读取 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 通过一个类型化端点和由客户端驱动的选择,解决了获取过多或过少数据的问题。
- 它特别适合多客户端、图状数据以及后端聚合。
- 对于可缓存的公共 API、简单的增删改查、文件上传以及遵循传统约定的使用方,REST 依然很有优势。
- GraphQL 将成本转移到了服务器端:N+1、查询开销限制、缓存,以及带错误的 200 响应语义。
下一步:使用 webonyx/graphql-php 实际构建一个模式。
常见问题解答
「GraphQL 与 REST 对比」课时是免费的吗?
是的 — 「GraphQL 与 REST 对比」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 PHP Academy 课程的其余内容,请升级到 CoddyKit PRO。 PHP Academy 课程共包含 4 节课。
「GraphQL 与 REST 对比」这节课中我会学到什么?
了解 GraphQL 何时优于 REST,以及原因 你通过在浏览器中直接运行的动手代码来练习 PHP Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 PHP Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 PHP Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。
「GraphQL 与 REST 对比」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 PHP Academy 课中编写并运行代码吗?
能。每节 PHP Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- GraphQL 与 REST 对比
- 使用 graphql-php 构建架构
- 解析器、变更与订阅
- 性能:N+1 与 DataLoader