API接口架构REST vs GraphQL
无论是创建网站,还是移动应用程序,我们都需要通过 API 来传递数据,通过 API 我们可以获取到数据库中的数据,可以操作数据库,可以处理一些业务逻辑。现在最流行的 API 架构是 REST。但是,GraphQL 正在逐渐追赶着它。
GraphQL 是一种新型的 API 架构,它比 REST 更灵活、更高效,并且具有声明式数据获取等功能。虽然 GraphQL 正在变得非常流行,但它并没有取代 REST,因为一些用户发现它更难使用,并认为它是一个过度设计的解决方案,尤其是对于一些小型项目。
REST
现代应用程序开发中 API 的主要架构是 REST。大多数后端框架可以非常容易地实现 REST。REST API 通常通过 HTTP 方法被调用。通过访问一个 URL, 就实现了对接口的调用处理。
REST 案例
假设你正在创建一个博客站点, 在首页上,你会显示最新文章的摘要,包括标题、图片和简短描述。为了提供这些数据,你需要在后端服务器上查询数据库或者缓存来获取结果。然后一个 REST API 就完成了 GET/api/articles
,它以 JSON 数组的形式返回所需的数据,如下例所示:
// GET /articles
[
{
"id": 1,
"title": "REST is Awesome",
"image": "https://restblog.com/img/dsh9a89.png",
"description": "The benefits of REST"
},
{
"id": 2,
"title": "How REST Works",
"image": "https://restblog.com/img/33szad2.png",
"description": "Learn about REST"
}
]
REST 的优点
方便实现
在 Web 服务器应用程序中设置 REST 很简单,尤其是当我使用一些框架的时候。比如laravel
,express
,django
,springboot
等,它们都提供了非常方便的方法来实现 REST 接口。
例如,/api/articles
使用 MongoDB 在 Express 应用程序中设置 REST 接口非常简单:
app.get('/api/articles', async (req, res) => {
try {
const articles = await db.articles.find() res.json(articles)
} catch (err) {
res.status(500).send(err)
}
})
通俗易懂
REST 很好理解,基本上通过请求方法和请求参数还有接口名称,我们就知道这个接口的作用,并且无论是前端人员还是后台人员都可以非常容易地通过接口文档进行数据的交互。
REST 的缺点
冗余数据
回到博客的例子,假设我们在创建 PC 站点的同时,也创建了一个移动网站。和桌面版本一样,在移动端的首页我们也要显示文章摘要。由于手机屏幕尺寸较小,这里的摘要只需要标题和图片,可以省略描述。
但不幸的是,由于/api/articles
接口是固定的,所以移动端的 description
在调用 API 时仍然会收到该字段。
这些冗余数据在频繁调用和发送大量数据的时候会造成服务器的资源浪费。
嵌套数据
有些时候我们通过一个接口要返回更多的数据的时候,我们就会使用嵌套数据。
例如,我们可能需要一个带有嵌套评论的文章。我们在获取到文章的时候,还需要再通过文章id获取评论信息。这就会导致请求时间的延长。
GraphQL
REST 的数据冗余和低效率,促使 Facebook 工程师在 2015 年创建了一种新的 API 设计模式,称为 GraphQL。与 REST 一样,GraphQL 不是特定的软件,而是 API 设计的规范。
GraphQL 的工作原理
为了了解 GraphQL 的优势,我们将快速概述它的工作原理。与 REST 不同,GraphQL 需要一个模式来告诉客户端和服务器通过 API 允许哪些数据和操作。这些是用 GraphQL 模式语言定义的,它是一种与语言无关的具有强大的类型系统的格式。
GraphQL 例子
让我们回到获取文章和评论的例子中。在我们的 GraphQL 模式中,我们将定义Article类型,该类型具有必需的整数id字段和用于title、image和可选字符串字段description,如下所示:
type Article {
id: Integer!
title: String
image: String
description: String
}
除了基本的标量类型之外,模式对象还可以相互引用。我们可以在类型和类型之间创建一对多的关系Comment,如下所示:
type Article {
id: Integer!
title: String
image: String
description: String
comments: [Comment]
}
type Comment {
content: String
article: Article
author: Author
}
定义操作
GraphQL 模式的另一个重要用途是定义操作,包括读取数据的查询和写入数据。在这里,我们提供了一个查询Articles:
type Article {
id: Integer!
title: String
image: String
description: String
comments: [Comment]
}
type Comment {
content: String
article: Article
author: Author
}
type Query {
articles: [Article]
}
GraphQL 的优点
声明式数据获取
GraphQL 的杀手级功能是声明式数据获取,客户端可以在其中准确指定它需要的数据。这可以包括特定字段,甚至在嵌套对象中。我们之前看到必须在模式上定义操作。但是,在这些操作中,我们可以指定我们希望查询返回到模式限制的哪些字段。
例如,我们可以创建一个查询,Articles只获取我们想要的字段,无论是否嵌套Comments。请参见下面的示例:
query {
articles {
id
title
image
description
comments {
content
}
}
}
这是将从该查询返回的数据结构。请注意,在 GraphQL 响应中接收到的数据将与请求它的查询具有相同的结构。
{
"data": {
"articles": [
{
"id": 1,
"title": "REST is Awesome",
"image": "https://restblog.com/img/dsh9a8.png",
"description": "An article about REST",
"comments": [
{
"content": "GraphQL is better!"
}]
}
}
通过这种方式,GraphQL 消除了冗余数据和嵌套数据问题。
健壮性
由于强类型和预定义查询的要求,GraphQL 可以提供开箱即用的验证和类型检查。反过来,这意味着 GraphQL 本质上是自记录的。一旦字段、类型或查询发生更改,基于架构的文档可以自动更新。
没有版本控制的 API
每次应用更改时,API 可能也需要更改。例如,假设我们决定将实体中的description字段重命名的时候.
REST 通过提供多个版本来处理这个问题,这对于 API 开发人员来说是很麻烦的。
使用 GraphQL,可以从模式中删除不推荐使用的字段,而不会影响现有查询。这为应用程序提供了对新功能的持续访问,并鼓励更清洁、更可维护的代码。
GraphQL 的缺点
矫枉过正
一些开发人员认为 GraphQL 解决的问题通常被夸大了。例如,对于大多数小型应用程序来说,因为几个字节的冗余数据而设计的更加复杂,这可能并不划算。
难于学习
GraphQL 比 REST 更难于实现,它为新用户提供了更难的学习曲线。
难以缓存
GraphQL 经常被批评为更难缓存。REST 客户端受益于 HTTP 缓存,因为所有端点都是 URL,而 GraphQL 客户端需要实现自己的自定义解决方案。
总结
虽然 REST 架构在过去十年中主导了 Web 开发,但它对接口调用的的使用使其在某些情况下有些不灵活且效率低下。GraphQL 通过提供严格类型化的模式语言来解决这些问题,接口调用者可以根据自己的需要进行查询。
如果未来能有更好的设计将两者的优点结合,我相信会是最佳的解决方案。
相关文章
- 一文吃透 VS Code+Git 操作(vs code中git的相关配置与使用)
- Ruby vs Elixir | 2022 该选哪个?
- 重识Nginx - 06 搭建静态资源Web服务器(alias VS root)
- 开源编辑器 VS Code 被倒卖,微软和谷歌看了都要沉默
- [Python人工智能] 二十.基于Keras+RNN的文本分类vs基于传统机器学习的文本分类
- STM32高级开发——使用VS Code搭建STM32开发环境
- VS Code配置snippets代码片段快速生成html模板,提高前端编写效率
- Wordpress vs Blogger:那个更好?
- 比较MySQL与VS的使用技巧(vs使用mysql)
- 使用VS连接 SQL Server数据库的简单指南(vs连接sqlserver)
- Hana VS Oracle: 新生代与旧物种的对抗(hana与oracle)
- VS连接Oracle数据库:一步搞定(vs连oracle数据库)
- FPGA vs. ASIC,你更看好谁?
- VS中使用MySQL:获取最佳性能(vs和mysql)
- Visual Studio Code (简称 VS Code ) 是一个轻量但功能强大的跨平台源代码编辑器。
- VS 开发 SQL Server 数据库应用实践(vs的sqlserver)
- VS整合SQLServer,实现数据库管理无忧(vs和sqlserver)
- Redis VS 内存 一场谁为赢家的你我争锋(放Redis还是内存)
- 比较VS Code使用Redis管理数据(vs使用redis)
- VS中使用Redis 一步一步搭建简易高效开发环境(vs中使用redis)