GraphQL vs REST在PHP中:2024年你的项目该选哪个?

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

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

开始课程

GraphQL vs REST在PHP中:架构之争还是不同任务的工具?

\n\n

当你再次打开代码编辑器,为你的PHP应用编写一个新端点时,一种似曾相识的感觉挥之不去。又要创建控制器?又要写验证逻辑?或许,是时候尝试点新东西了?在PHP开发世界中,GraphQL与REST之间的争论,就像“Laravel”与“Symfony”的永恒之争——每个人都声嘶力竭地捍卫自己的技术栈。但让我们坦诚地说:这两种方法都不是信仰,而是工具。今天,我们将把它们拆解成一个个零件,看看真实的代码,并决定何时PHP的REST API是你的选择,何时又该关注PHP中的GraphQL。

\n\n

快速入门:它们是什么?

\n\n

REST(表述性状态转移)是一种架构风格,建立在资源和HTTP方法的原则之上。你访问/api/users,获得用户列表。想要单个用户?加上/api/users/42。一切都很逻辑、可预测且简单。

\n\n

GraphQL是一种由Facebook创建的查询语言。你不受URL的束缚。你向一个统一的端点(例如/graphql)发送一个请求,并说:“给我用户42的名字、他最近的5篇帖子以及每篇帖子下的点赞数。”服务器只返回你所请求的内容。不多一个字节。

\n\n

看起来,GraphQL在得分上胜出。但先别急着抛弃老牌的REST。每种方法都有其陷阱,尤其是在PHP开发的背景下。

\n\n

架构对比:从理论到代码

\n\n

REST:经典之作

\n\n

在PHP中,REST通过路由实现。像Laravel或Symfony这样的框架能优雅地做到这一点。以下是Laravel中一个典型REST控制器的示例:

\n\n
<?php\n\nnamespace App\\Http\\Controllers\\Api;\n\nuse App\\Models\\User;\nuse Illuminate\\Http\\Request;\n\nclass UserController extends Controller\n{\n    public function index()\n    {\n        return User::all();\n    }\n\n    public function show($id)\n    {\n        $user = User::with('posts.comments')->findOrFail($id);\n        return response()->json($user);\n    }\n\n    public function store(Request $request)\n    {\n        $validated = $request->validate([\n            'name' => 'required|string',\n            'email' => 'required|email|unique:users',\n        ]);\n\n        $user = User::create($validated);\n        return response()->json($user, 201);\n    }\n}
\n\n

优点显而易见:缓存简单(HTTP缓存、Varnish)、URL结构清晰、工具支持广泛(Postman、Swagger)。缺点——过度获取和欠获取的问题。如果前端只需要用户名,而你在响应中返回了模型的所有字段——这就是过度获取。如果需要用户名和好友列表,而你却发出了两个请求——这就是欠获取。

\n\n

GraphQL:带有陷阱的灵活性

\n\n

要在PHP中实现GraphQL,有一些优秀的库:webonyx/graphql-php(纯PHP)和lighthouse-php/lighthouse(用于Laravel)。以下是使用graphql-php的schema和resolver示例:

\n\n
<?php\n\nuse GraphQL\\GraphQL;\nuse GraphQL\\Type\\Definition\\ObjectType;\nuse GraphQL\\Type\\Definition\\Type;\nuse GraphQL\\Type\\Schema;\n\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($postType),\n            'resolve' => function ($user) {\n                return getPostsByUserId($user['id']);\n            }\n        ],\n    ],\n]);\n\n$queryType = new ObjectType([\n    'name' => 'Query',\n    'fields' => [\n        'user' => [\n            'type' => $userType,\n            'args' => [\n                

博客

书籍推荐