什么是 GraphQL 以及为什么我应该使用它?
我为什么要使用 GraphQL?以及不使用 GraphQL 的理由。
你肯定看过我之前的帖子,我滔滔不绝地讲述了我是如何搞乱我的 Rest API 的。我绝对不会满足于只针对单一技术栈做这样的事情。
因此,GraphQL。
为什么需要 GraphQL?
Google GraphQL并参考文档- 有比我更聪明的人给出更好的答案。
但是,由于互联网可能是一个可怕的地方,而且我喜欢写一些我不擅长的东西——以下是我的想法的要点。
回到故事...
GraphQL 是 API 的 SQL。
在您说“啊……我现在知道一切了!”之前,请继续阅读。
您会发现 - 网络上的大多数交易都涉及获取某些数据。
客户端需要经过身份验证和授权,然后请求数据才能进行交易。提供数据的服务器将根据预定义的规则执行客户端请求。
Rest 是一种架构风格,它允许你标准化和简化客户端-服务器请求。你可以控制资源(账户、联系人等)和操作(GET、STORE 等)。
到目前为止一切都很好。你甚至可能认为你已经达到了涅槃境界,但想象一下,如果你发起一系列请求,会发生什么——
You: Give me contacts
Server: Here are 100 contacts with 501 fields per contact
You: Give me contacts and activities for each contact
Server: Here are 1000 contacts and 1 million activities per contact
You: Give me contact detail
Server: Here you go - 1000 fields of the contact
You: Give me address for the same contact
Server: Oh God, you again? Here's the address. And, can you please stop this madness?
您将在现实世界中看到这样的例子 - 所描述的问题被称为“过度获取”(获取比我需要的更多的数据)和“获取不足”(获取比我需要的更少的数据)。
过度获取的属性 -
- 服务器从数据库获取更多数据(或者可能查询并不总是需要的相关实体)
- 更多数据通过管道推送
- 客户端获得的数据超出了所需,并且必须处理数据以有选择地挑选和显示数据。
还有那些因为获取不足而
- 客户端不需要一次性获取所有数据,而是请求相关实体或字段
- 额外的网络请求和更多不必要的流量
- 有更多时间渲染具有完整数据的 UI
服务器和客户端之间的来回交互使服务器感到沮丧 - 如上面的对话所示,更重要的是,影响客户端的性能。
多次来回的请求使得 Rest 变得“喋喋不休”。
因此,GraphQL。
(我向你保证 - Matrix 与我一直使用“ergo”几乎没有关系。)
但实际上,我为什么要使用 GraphQL?
我当然不会使用 GraphQL,因为它 -
- 是当今 Web 开发的流行趋势
- 受到所有人的崇敬,他们说没有什么比这更美妙的了
- 是打字的,这让它如此神奇
- 提供了一个非常好看的 IDE,使开发查询变得非常简单
- 使服务编码变得非常容易(只需要一个手势,所有的小东西就会完美地排列在一起)
- 大幅减少网络流量,并在点火前将速度提高到“烧胎”水平
- 使用内置安全规则,可以轻松提供基于角色的授权
- 受到服务器和客户端技术栈的同等喜爱
- 为数据库指定一个良好的抽象层
- 有订阅,这些订阅太棒了
- 是由 Facebook 开发的。我碰巧崇拜扎克伯格
或者,我可能正在使用 GraphQL 来实现上面提到的几个点,而承认这一点很尴尬(或者说很愚蠢)。
我使用 GraphQL 的主要原因是 -
- 它减少了服务器端的工作量(惊喜吧?!)。我不需要为每个请求编写 API,也不需要为了应对所有可能的情况而过度设计 API。由于我的大多数服务都是数据密集型的,我特别喜欢不需要维护十几个端点。
- 客户端的开发迭代更容易。我可以调整客户端代码来获取更多或更少的数据
- 仅在客户端和服务器之间传递所需的数据
但另一方面——
- GraphQL 使得编写服务器端服务变得更加困难(这只是我的看法,而不是 GraphQL 本身的错)。
- 我还发现,当客户端在后台窃笑时,控制客户端请求的查询变得更加困难(所述客户端的开发人员,而不是客户端用户。由于我是许多应用程序中唯一的开发人员,所以我对自己窃笑。我需要帮助!)。
我发现先启用标准 Rest 模式(大多数情况下都是搭建的)会更方便。然后,我会为特定事务启用 GraphQL 服务,并以此为基础继续操作。
呃..你到底在说什么?
让我们看几个例子。
如果我需要获取特定的联系人,我会在 REST 中执行以下事务 -
GET https://api.com/contact
答案将是——
data: {
contacts: [
{
planet: "earth",
name: "Rama",
age: 42
},
{
planet: "mercury",
name: "Kris",
age: 21
},
{
planet: "mars",
name: "Joe",
age: 63
}
];
}
我可以在 GraphQL 中执行以下操作并将其作为 POST 请求发送到服务器 -
query {
contacts(name: "Rama") {
name
age
}
}
响应将是这样的 -
data: {
contacts: [
{
name: "Rama",
age: 42
}
];
}
两笔交易的回应不言而喻!
什么是 GraphQL 操作?以及,我为什么要关心它?
无论我们在客户端-服务器世界中做什么 - 我们都试图做一件简单的事情 -
在服务器和客户端之间共享数据和业务逻辑
用户可以查询、插入、更新或删除数据,并可以从客户端发起这些事务。以下情况可能发生:
- 服务器不关心客户端的“状态”。即,客户端发送请求(如果需要,包括身份验证作为请求的一部分),然后服务器应答调用
- 服务器牢记客户端的兴趣,与客户端保持开放的渠道,并跟踪数据,以便客户端能够及时获取变化
GraphQL 在数据库之上构建了一个层来帮助您在两种情况下传输数据。
询问
GraphQL 查询可帮助您仅获取所需的记录和属性 - 我们之前已经看到过示例。
您还可以在请求中包含不同的实体(可以类比为“表”)。使用 GraphQL 获取具有指定关系的记录,而无需针对不同的实体分别发出请求。
突变
GraphQL 突变用于插入/更改数据。
mutation createContact {
addContact(name: "Joe", age: 100) {
id
}
}
上述查询提供了使用名为 的突变的指令,createContact
该突变又用于addContact
添加具有姓名Joe
和年龄的联系人记录100
。
订阅
订阅在服务器和客户端之间建立了一个通道。客户端可以订阅记录更新,并在发生变更时收到通知(通过简单的通知,或通过服务器实际“推送”数据)。
订阅功能在底层使用了“Web 套接字”。这是一项久经考验的技术,能够实时向客户端更新数据。
例如 - 客户可以使用以下订阅来获取中彩票的联系人列表。
subscription listenWonLottery {
wonLottery {
name
deals
}
}
让我们看看流程 -
- 客户订阅联系人
- 中奖后,一个或多个联系人的信息会在数据库中更新
- 数据库更新时,会向客户端触发通知
- 通知包含联系人的姓名以及与联系人相关的交易
- 客户端可以显示带有联系人姓名的弹出窗口,并显示飞行气球以达到效果
实现 GraphQL 需要哪些不同的组件?
GraphQL 只是 API 和执行查询的运行时语言。它并非与数据库硬连接,也不指定如何执行数据库操作。
实现 GraphQL 堆栈的不同组件如下。这些组件并非 GraphQL 规范的一部分,而只是支持使用 GraphQL 进行事务处理的堆栈的一部分。
服务器
实现/技术栈决定了 GraphQL 如何融入到事务中。服务器接收来自客户端的 GraphQL 请求,建立与数据库的连接,将图形查询转换为数据库可以理解的语言,获取结果并将响应发送回客户端。
服务器还可以包括“普通”服务器所期望的功能 -
- 将业务逻辑应用于数据
- 在指定的网络端口上监听支持的请求类型
- 负责处理向客户端请求所需的所有支持基础设施。
数据库
存储数据并维护数据的原子性、一致性等。它是一个优秀的文件系统,支持独立事务,不会因为网络故障或客户端玩游戏而导致数据混乱。
客户
可以是浏览器、移动应用,或者任何向服务器请求数据并接收服务器响应来执行“某事”的东西。我们创建 GraphQL 查询、变更等,并通过简单的 POST 请求发送它们。
我应该熟悉哪些术语?
架构
Schema 是 GraphQL 的基石。它使用我们能够理解的语言来描述——可以是任何语言,但在标准实现中使用了一种名为“Schema 定义语言”的简单语言。
请考虑以下示例 -
type Contact {
name: String
deal: Deal
}
type Deal {
description: String
value: String
}
模式定义可帮助客户端开发人员查看和理解数据实体之间的关系,并在此基础上构建 GraphQL 查询。
解析器
解析器是一个返回按照模式指定的形状的数据的函数。
例如-
const resolvers = {
Query: {
contact(root, args) {
return contacts.filter(contact => contact.id === args.id)[0];
},
deals(root, args) {
return deals.filter(deal => deal.id === args.id)[0];
}
},
Contact: {
deals: contact => {
return deals.filter(deal => deal.contactId === contact.id);
}
}
};
我们使用解析器来编写查询、变异和订阅。
对象类型/字段
在上面概述的 GraphQL 查询中 -
- 对象类型为“联系人”和“交易”
- 字段包括
name
、description
和value
这太酷了,我睡着了都没看完这篇文章。直接告诉我——我应该使用 GraphQL 吗?
并非所有地方都如此。
当你需要获取大量具有不同形状/多种关系的数据时,请使用 GraphQL。使用 GraphQL 可以简化客户端和服务器之间的数据传递。
同时 -
- 请记住,普通的 Rest API 实现更简单
- 即使在数据量很大的应用中,我也不认为在所有情况下都应用 GraphQL 有什么大的优势(或许除了架构统一性/标准化之外)。例如,如果实体之间的关系比较狭窄,并且不需要始终使用相关的数据视图
- 跟踪客户端如何使用 GraphQL - 疯狂的查询可能会导致性能问题
为什么我发现 Rest 服务更简单?
- 在服务器上设置端点很简单。只需暴露一两个 API,然后使用 ORM 即可在一两步内获取/更新数据 - 除非您自己处理,否则不会在任何地方看到字段和相关实体。
- 除了前一点,或者补充一下,事实上,这个工具非常棒——这项技术非常古老,支持得很好,大多数时候只需要点击几下(或几行代码)就可以完全设置
- 我在后端控制查询——更容易控制谁访问数据以及如何访问。由于我在服务器上控制筛选和排序,我也发现更容易解决潜在的性能问题。
- 但总而言之,我可能会发现 Rest 更容易了,因为我已经花了这么多时间在它上面 :)
好的,我加入。我应该从哪里开始呢?
我发现以下技术栈易于理解,并且对长期学习很有帮助。由于我一直使用 Vue,并且坚信 Vue 对初学者来说更容易上手,因此我更推荐 Vue。
启用 GraphQL 服务器端
自己创建一个服务器并真实地查看后端的 GraphQL 流是一个好主意。
类别 | 受到推崇的 | 评论 |
---|---|---|
我懂 SQL 并且了解 DB | PostGraphile | 参考这个 |
我想了解更多无服务器知识 | AppSync | 在 Amazon AppSync 上注册 1 年有限免费服务器 |
我想通过 CMS 学习 GraphQL | StrapiJS | 处于测试阶段,但适合生产 |
我想尝试静态网站 + GraphQL | 格里索姆 | 新颖,但很有前景。 |
我懂 PHP | Laravel + Lighthouse | |
我期待长期的合作关系 | NestJS | 良好的服务器功能 + 良好的 GraphQL |
我是大师 | 引导我走向启蒙,也许 | 你到底在这里干什么? |
在客户端上使用 GraphQL
- Vue + Vue-Apollo
- Svelte + Apollo。
另请参阅:使用 Svelte + GraphQL 创建简单的待办事项
菲尼斯
到此结束:)
文章来源:https://dev.to/prashanth1k/what-is-graphql-and-why-i-should-use-it-20kn