65.9K
CodeProject 正在变化。 阅读更多。
Home

GraphQL:现代数据库管理系统的演进

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.67/5 (3投票s)

2019年8月21日

CPOL

6分钟阅读

viewsIcon

5849

GraphQL:现代数据库管理系统的演进

引言

GraphQL” 这个词在网络上经常出现。在许多技术活动中也被提及,最近一次是 2017 年的 AWS re:Invent 大会,会上他们宣布了 AppSync,一个完全托管的 GraphQL 服务。

为什么 GraphQL 突然在开发者社区引起轰动?它的崛起如何影响科技世界?

虽然这个名字可能会误导您认为它是一种查询语言,但它实际上是 REST(及其变体)的替代品。我整理了关键要点,供任何想了解 GraphQL 的人参考。

为了帮助您更好地理解并突出差异,我包含了使用 REST 和 HTTP 的图示示例。

什么是 GraphQL?

GraphQL 由 Facebook 于 2012 年内部开发,并于 2015 年 10 月公开发布。在 Facebook 的术语中:GraphQL 是一种查询语言,旨在通过提供描述其数据需求和交互的直观、灵活的语法和系统来构建客户端应用程序。它提供了一种从后端查询数据和更改数据的语言。

简而言之,GraphQL 是一种由 Facebook 创建的查询语言,它指定了如何从 API 获取数据。

GraphQL 基础知识

GraphQL 有 3 种高级操作

  1. Queries(查询)- 用于获取数据,类似于 REST 中的 GET 方法
  2. Mutations(变更)- 用于创建/修改数据后进行获取,类似于 REST 中的 POSTPUTDELETE 方法
  3. Subscriptions(订阅)- 长连接,用于接收服务器上数据的更新,类似于 WebSocket

这些操作通过一个定义 API 功能的 schema(模式)暴露。Schema 由类型(types)组成。开发人员定义的 schema 决定了 GraphQL API 的功能。

每个 GraphQL API 可以有两种类型

  1. 根类型(Root types),例如:query、mutation、subscription
  2. 用户定义类型(User-defined types),例如:todo、human、animal 等。

每个 GraphQL API 都会有一个 query 类型,并且可能有一个或没有 mutation 和 subscription 类型。根类型决定了 GraphQL 查询的入口点。

示例查询

{
human(id: 101) {
name
age
}
}

上述查询执行以下操作:

  1. root 对象开始
  2. 我们选择 id 为 101 的 human 字段
  3. 对于返回的 hero 对象,我们选择 nameage 字段

查询结果将是

{
"data": {
"human": {
"name": "John Doe",
“age”: 20
}
}
}

为了使上述查询能够正常工作,我们必须在 schema 中添加一个 human 类型,该类型包含它可以返回的字段。根查询类型和 human 类型的定义如下:

type Human {
name: String!
age: Int!
}
type Query {
human(id: ID!): Human
}

类型的字段需要返回一些数据。在 GraphQL API 中,这通过一个称为 GraphQL resolver(解析器)的概念来实现。解析器是一个函数,它会调用数据源或触发一个操作来返回某个值(例如单个记录或记录列表)。

解析器可以有多种数据源,例如 NoSQL 数据库、关系数据库或 REST API。我们可以从多个数据源聚合数据,并返回相同的类型,混合搭配以满足您的需求。

一旦 schema 连接到解析器函数,客户端应用程序就可以发出 GraphQL 查询,或者选择性地发出变更或订阅。我相信您已经开始看到 GraphQL 与其前身和其他常用数据库的区别了。

但是,它有实际的好处吗?让我们来看看。

GraphQL 的好处

更好的数据检索

查询数据非常简单,并且减少了与服务器的往返次数。考虑一个包含内容、评论等的博客。每个评论可以包含描述和用户,每个用户会有姓名、电子邮件、博客列表。

假设我需要博客内容及其评论、评论用户以及该用户的博客。为了实现这一点,我们将不得不进行以下 REST 调用:

GET - api/vi/blogs/101/ -> will return the blog with its contents
GET - api/v1/blogs/101/comments -> will return the comments of the blog
GET - api/v1/users/30/blogs -> will return the blogs of the user

假设我们有 4 条评论,那么 N = 4,需要的调用次数是:步骤 1 + 步骤 2 + 步骤 3 x 4,计算结果为 6 次调用。我们需要所有评论过该博客的用户博客,所以步骤 3 将根据用户数量进行多次 N 次执行。

现在,使用 GraphQL 和以下查询,完全相同的事情可以在 1 次调用中完成:

{
blog(id: 101) {
content
comments {
content
users {
name
email
blog {
content
}
}
}
}
}

您注意到我们如何用一个简单的逻辑替换了几行代码吗?

更好的版本控制

在 REST API 中,如果有一个新字段或资源发生了一些更改,就必须创建一个新版本的端点。这会增加管理更多代码、另一个端点的负担,并在旧端点弃用后将其删除。

GraphQL 通过允许用户保持相同的端点,同时动态地向类型添加新字段而不破坏任何现有内容来解决这个问题。

更好地控制响应数据

考虑我们有一个被响应式 Web 应用程序使用的 API。根据应用程序打开的设备,屏幕上显示的数据会有所不同,某些字段在小屏幕设备上可能会隐藏,而在大屏幕设备上可能会显示所有字段。

以下信息图解释了在使用 REST 时管理返回数据所涉及的各种痛点。

使用 GraphQL,只需根据设备查询所需的字段即可。前端可以控制其请求的数据,并且相同的原则可以用于任何 GraphQL API。

聚合数据

通过 GraphQL,我们可以轻松地从不同来源聚合数据,并将它们整合到一个统一的 API 中提供给用户,而不是从前端或后端进行多次 REST 调用。我们可以通过统一的 API 来暴露遗留系统。

如上所述,每个 GraphQL API 都由类型、schema 和解析器组成。为了创建 API,我们需要用某种语言创建一个 GraphQL 服务器。正如您现在所知,GraphQL 本身是一种语言,并且有一个规范,该规范必须在编程语言中实现才能使用。

几乎所有现代编程语言现在都有 GraphQL 规范的实现,您可以利用这些实现,从而使集成和迁移极其顺畅和简单。

重要资源

作为一名程序员,我相信您渴望尝试 GraphQL。我整理了一些有用的工具和库,您可以利用它们使您的 GraphQL 之旅更加有趣。

  • graphql - GraphQL 在 JS 中的实现
  • Apollo - GraphQL 工具包。它为多个平台提供了服务器实现
  • Prisma - 一个将您的数据库转换为 GraphQL API 的工具。它支持多种数据库
  • Scaphold - 一个托管的 GraphQL 后端
  • AWS AppSync - 一个完全托管的 AWS GraphQL 服务器,连接到多个数据源

结论

GraphQL 非常强大,潜力巨大,但仍处于起步阶段。然而,在很短的时间内,它已经获得了极大的关注,并被社区广泛采用。

其受欢迎程度清楚地表明了 GraphQL 的易用性和重要性。我在这里讨论的好处只是我亲身使用时所体验到的一些。

随着系统的发展,我相信会有更多的好处涌现——GraphQL 有一个巨大的生态系统可以被利用。

观看关于 GraphQL 的完整视频:https://youtu.be/vr2PiivOPZQ

历史

  • 2019 年 8 月 21 日:初始版本
© . All rights reserved.