PHP API:REST、GraphQL 和 gRPC — 2025 年该如何选择?

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

引言:API 不是魔法,而是工具

\n

当您的 PHP 网站不再只是一个静态页面,而是开始与外部世界(如 Telegram 机器人、支付网关或您自己的移动应用)通信时,您将不可避免地接触到 API(应用程序编程接口)。这只是一个契约:“如果你以这种格式向我发送请求,我将返回数据给你。”如今在 PHP 领域,有三个主要参与者:经典的 REST、灵活的 GraphQL 和激进的 gRPC。该如何选择?让我们通过实际示例来探讨。

\n

本文面向那些已经会用 PHP 编写代码并希望拓宽视野的开发者。我们不会简单地复制文档,而是以解决实际问题的开发者的视角来审视每种协议。

\n\n

PHP 中的 REST API:久经考验的经典

\n

REST(表述性状态转移)不是一种协议,而是一种架构风格。它使用 HTTP 方法(GET、POST、PUT、DELETE)来处理资源。如果您曾经写过 file_get_contents('https://api.example.com/users'),那么您已经使用过 REST 了。

\n

为什么 REST 仍然是王者?

\n
    \n
  • 简单性:任何 HTTP 客户端都可以使用它。
  • \n
  • 缓存:可以在 HTTP 级别缓存 GET 请求。
  • \n
  • 广泛支持:从 curl 到专门的库。
  • \n
\n

使用 Guzzle 的 PHP REST 客户端示例

\n

Guzzle 库是 PHP 中 HTTP 请求的事实标准。通过 Composer 安装:composer require guzzlehttp/guzzle。

\n
<?php\nrequire 'vendor/autoload.php';\n\nuse GuzzleHttp\\Client;\n\n$client = new Client([\n    'base_uri' => 'https://jsonplaceholder.typicode.com/',\n    'timeout'  => 5.0,\n]);\n\n// GET 请求\n$response = $client->get('posts/1');\n$post = json_decode($response->getBody(), true);\necho "帖子标题: " . $post['title'] . PHP_EOL;\n\n// POST 请求\n$response = $client->post('posts', [\n    'json' => [\n        'title' => '新帖子',\n        'body' => '帖子正文',\n        'userId' => 1\n    ]\n]);\necho "创建的帖子 ID: " . json_decode($response->getBody(), true)['id'];\n?>
\n

我们做了什么?只是发送了 HTTP 请求。REST 不需要专门的库——甚至可以使用带上下文的 file_get_contents(),但 Guzzle 提供了便捷的错误处理、中间件和流式传输。

\n

什么时候 REST 不是最佳选择?

\n

如果您需要获取关联数据(例如,帖子 + 作者 + 评论),REST 会迫使您发出多个请求。这时,GraphQL 就登场了。

\n\n

PHP 中的 GraphQL:只请求你需要的内容

\n

GraphQL 是一种由 Facebook 开发的查询语言。客户端自己描述响应的结构。一个请求,一个响应,没有数据过多或不足的问题。

\n

GraphQL 在 PHP 中如何工作?

\n

服务端:webonyx/graphql-php 库(安装:composer require webonyx/graphql-php)。客户端:一个带有 JSON 主体的普通 HTTP POST 请求。

\n

来自 PHP 的 GraphQL 请求示例

\n
<?php\nrequire 'vendor/autoload.php';\n\nuse GuzzleHttp\\Client;\n\n$client = new Client(['base_uri' => 'https://countries.trevorblades.com/']);\n\n$query = '\nquery GetCountry {\n    country(code: "RU") {\n        name\n        capital\n        currency\n        languages {\n            name\n        }\n    }\n}';\n\n$response = $client->post('', [\n    'json' => ['query' => $query]\n]);\n\n$data = json_decode($response->getBody(), true);\necho "国家: " . $data['data']['country']['name'] . PHP_EOL;\necho "首都: " . $data['data']['country']['capital'] . PHP_EOL;\necho "货币: " . $data['data']['country']['currency'] . PHP_EOL;\necho "语言: ";\nforeach ($data['data']['country']['languages'] as $lang) {\n    echo $lang['name'] . " ";\n}\n?>

博客

书籍推荐