0Pricing
PHP Academy · 课时

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 反馈 — 无需本地设置。

此课程中的所有课时

  1. GraphQL 与 REST 对比
  2. 使用 graphql-php 构建架构
  3. 解析器、变更与订阅
  4. 性能:N+1 与 DataLoader
← 返回 PHP Academy