REST 与 GraphQL:主要区别
2000 年,计算机科学家 Roy Fielding 凭借其博士学位论文提出了一种新的软件架构风格:表述性状态转移(Representational State Transfer,简称 REST)。
RESTful API 允许 Web 客户端通过一组预定义的无状态操作访问资源。由于对资源 URI 的请求可以以 JSON 格式返回,因此 REST 是一种比当时主流协议 SOAP 更简单的解决方案,因为 SOAP 的请求会以难以解析的 XML 格式返回。
RESTful API 迅速成为 Web API 的事实标准。直到最近几年,才出现了一个强有力的竞争对手。自 2012 年以来,Facebook 一直在使用一种新的查询语言来构建其移动应用程序:GraphQL。该语言于 2015 年开源,自此以后,其受欢迎程度不断增长。
本文将探讨 REST 和 GraphQL 之间的主要区别。正如您将看到的,GraphQL 相比 REST 具有一些明显的优势,尽管您需要哪种 API 最终取决于您正在构建的具体应用。
此外,本文描述的 GraphQL 的优势主要在于其优于“所谓的 REST” API(Zdenek Nemec 在这篇博文中将其称为REST API)。REST 和 HTTP 协议有很多内容。只要有足够的时间和知识,你就能创建一个与 GraphQL API 一样优秀,甚至可能更灵活的 REST API。
话虽如此,考虑到开发人员已经够忙了,而且真正的 REST API 很难实现(正如 Nemec 在他的博客文章中所说的那样),我们将讨论当今大多数配置的 REST API。
多个端点 vs. 一个端点
REST API 有多个端点(也可以称为路径)。这意味着它会暴露多个 URI,用于响应不同的 HTTP 方法。开发人员定义哪些路径可以向客户端开放。REST API 最常用的 HTTP 方法是 GET、POST、PUT、PATCH 和 DELETE。
例如,POST /user {name: 'Thomas'}
是针对一个路径的请求。它由 HTTP 动词POST
、路径/user
和请求主体{name: 'Thomas'}
(可选,取决于 HTTP 动词)组成。
然而,GraphQL API 只有一个端点,通常为/graphql
。所有针对给定资源的 GraphQL 请求都应定向到此端点。此外,GraphQL API 仅接受一种 HTTP 方法:POST(可以选择启用 GET 查询)。以下是 GraphQL GET 请求查询的示例:/graphql?query={user{name}}
。
query
是操作类型,user
是操作端点,name
是您希望返回的请求字段。请求主体在这里是必需的,它允许您非常具体地指定您希望返回的内容,这就引出了 REST 和 GraphQL 之间的第二个重大区别。
获取过多或不足 vs 获取所需信息
REST API 容易出现数据获取过度和不足的情况。过度获取是指 REST API 会将所有数据发回单个端点,无论你是否需要。在以下示例中,你将收到与该/movies/12
端点关联的所有字段:
然而,使用 GraphQL,你可以构建模式,以便客户端可以更加具体。你可以这样为上面的示例构建 GraphQL 模式:
以下是使用 GraphQL 请求数据的方法以及结果:
如您所见,您得到的正是您想要的内容。没有过度获取,因为客户端在查询的请求正文中明确指定了它想要的内容。
REST API 也容易出现资源不足的情况,因为它通常需要多次往返获取相关资源。例如,查找博客文章及其作者的信息可能需要通过 REST API 发出两次 HTTP GET 请求,因为有两个端点:/posts/1
和/users/1
。
使用 GraphQL,您可以在单个请求中获取这些信息。这种精确性的缺点是 GraphQL 增加了额外的复杂性,因为开发人员必须在前端管理架构类型和查询。
关于版本控制
由于时间和资金的限制,任何 API 的第一个版本有时都会有些粗糙。让我们想象一下 REST API 的 v1 版本,其/user
端点返回以下结果:
当开发人员查看 API 时,他们意识到这role
不太符合语义。很难理解数字 3 的实际含义。他们想澄清这个字段,并且有两个选择。首先,他们可以向端点添加一个新字段,如下所示:
虽然这不会破坏任何客户端,但会导致 REST API 中出现更多过度获取的情况。这并非理想情况。开发人员还可以决定更改实际role
字段,如下所示:
但这需要创建 API 的 v2 版本,并且需要向公众发布。你也不会为了这么小的改动就创建新的 API 版本。你会等到 v1 版本的 API 有了足够多的改动,才有资格发布 v2 版本。所以你无法像你希望的那样快速更新 API。
另一方面,GraphQL 是无版本的。假设你在 GraphQL 中定义了一个类型,其行为类似于上面的示例,包含两个整数:
返回的结果与 REST API v1 版本相同,开发人员也得出了相同的结论。该role
字段使用整数表示语义不通。他们想修改它。
开发者可以选择添加一个新字段,与 REST API 开发者的第一个解决方案相同。然而,这里的区别在于 GraphQL 不会过度获取数据,因此这样做没有任何坏处:
最终,您可以弃用该role
字段,以便让客户端开发者知道不应使用它。此外,由于 GraphQL 会让您确切地知道客户端正在寻找什么信息,因此您可以只针对请求弃用字段的客户端并通知他们这一变化,而不是针对所有请求特定端点的客户端。
综上所述
REST 使用多个端点,而 GraphQL 只使用一个。此外,REST 容易出现数据过度获取或获取不足的情况,而 GraphQL 则不会出现这种情况,而且 REST 的更新也不像 GraphQL 那样容易。
话虽如此,REST API 可以利用 HTTP 内容类型、缓存、状态码和超媒体控件。正如我在文章开头所说,REST 有很多功能,如果你非常熟悉它如何通过 HTTP 接收和发送数据,它会非常强大。
无论如何,我认为可以肯定地说,除非您非常熟悉 REST 和 HTTP,否则 GraphQL 相对于 REST 的优势使其成为构建 API 的首选方式。
鏂囩珷鏉ユ簮锛�https://dev.to/x-team/rest-vs-graphql-the-main-differences-4nm1