REST 并不是在 web 上发送信息的第一种协议。但十多年来,它一直主宰着 API 领域。
最近,由 Facebook 设计的新手 GraphQL 变得越来越流行。它的目的是纠正REST的一些缺点,但没有一项技术是完美的。
与 REST 相比,GraphQL 有哪些优点?为什么要在项目中使用其中一种?
REST Api 存在的问题
首先,让我们讨论一下 REST 的一些弱点以及 GraphQL 如何试图解决它们。主要有三个原因:
- 到服务器的次数过多
- 抓取过度/抓取不足
- 缺乏灵活性
使用 REST Api 访问服务器的次数太多
假设我们正在创建一个社交媒体应用程序。它可能会显示所有用户最近的帖子,以及用户名和个人资料照片。
例如,在 REST 中,您需要向 /api/posts
发送 GET
请求来获取帖子,该请求可能会返回一个 JSON
对象,其中包含帖子标题、内容、标记、日期,可能还有用户 ID。
然后,您可能需要为每个帖子发送一个 GET 请求到 /api/users/:id/
,以便获得关于用户的用户名、头像和任何其他相关信息的信息。
当您考虑到您可能会为每个用户发出GET请求时,对于一个页面来说,这是大量的来回操作!
使用 GraphQL ,你可以一次访问服务器并获得你需要的一切:
query { posts { title, content, tags, date, user { username, avatar, catchphrase, favorite_dog } } }
在小范围内,多次访问服务器并不是什么大问题。但是,一旦要处理大量数据,将 API 调用减少到最少显然会对您有好处。 GraphQL 使得这一点很容易实现。
抓取过度/抓取不足
另一个存在的问题是过多抓取和抓取不足。在 REST API 中,当您到达一个端点时,总是会得到相同的数据,无论您是否需要它。
假设我们只需要某人的用户名和头像。如果 /user/:id
返回他们的用户名、头像、标语和最喜欢的狗的品种,你就会得到所有这些信息,不管你是否愿意。
在另一端,您可能会出现抓取不足的情况,这就需要返回到服务器以获取更多信息。
要显示单个用户的帖子,我们需要用户信息和帖子的内容。如果我从用户端点获取用户,我仍然需要点击 posts 端点,并使用 userid
检索 posts。
// 首先获取用户信息数据 GET /api/users/42 { "username": "Mr. T", "avatar": "http://example.com/users/42/pic.jpg", "catchphrase": "I pity the fool", "favorite_dog": "beagle" } // 接着,获取用户的帖子 GET /api/users/42/posts { "posts": [{ "title": "Hello World", "content": "Hi everyone!" "tags": "first post" "date": "July 1, 2020" }] }
正如我们在前面的例子中看到的,GraphQL 解决了这个问题,它允许用户使用一个端点,只获取他们需要的内容。
缺乏灵活性
在前一点的基础上进一步扩展,REST 依赖于创建符合前端需求的api。如果您能够预测前端在碰到特定端点时需要什么,就可以精确地调整检索到的数据,以匹配该视图。
当视图是相对静态的时候,这种方法工作得很好。但如果你的前端经常变化,你就需要一个 API,它可以更灵活地返回数据。
类似地,如果你的 API 被具有不同需求的各种不同客户端使用,那么 REST API 的灵活性将不适合您的目的。
GraphQL 允许检索不同配置的数据,从而提供了这种灵活性。
query { users { username, avatar } } // 如果想要获取用户最喜欢的宠物狗 query { users { username, avatar, favorite_dog } }
应该使用 REST 还是 GraphQL ?
从本文来看,GraphQL 似乎总是比 REST 好,但事实并非如此。在构建应用程序时,你所做的每一个架构决策都有其优缺点,这也不例外。
以下是一些需要考虑的事情:
如果您需要一些易于使用的工具,请选择 GraphQL 。
正确使用 REST 有一个学习曲线,如果你还不知道它,你可以使用 GraphQL 更轻松地创建一个优秀的 API。
如果使用GraphQL,请决定如何处理错误
REST Api 能够更好地利用 HTTP 的错误报告特性。如果您不想为客户端错误返回 200 OK 状态(这在 GraphQL 中很常见),则需要更多地考虑错误处理。
REST 可能更适合微服务
如果您在后端使用微服务,REST 可能更适合您的目的,因为它是为了将关注点分开。
如果您不需要使用可能用不同编程语言编写的不同的、完全不同的资源,那么GraphQL 的统一数据 “图” 是非常棒的,但如果您有一个更分布式的后端,就没有那么有用了。
缓存问题
缓存是 REST 内置的功能,但你必须使用 GraphQL 来管理缓存。如果你没有在适当的地方构建缓存,那么你从 GraphQL 更有针对性的获取中获得的所有提高的效率都可能被抹去。
总结
和所有事情一样,在决定 REST 和 GraphQL 之间的取舍时需要考虑一些折衷。你为项目选择什么将取决于你的需求和资源。