以下是来自 Graph.cool 的 Nilan Marktanner 的客座文章。 我不知道你们怎么样,但我职业生涯中花了很多时间处理 REST API。 一直都在尝试弄清楚要访问哪个 URL、预期返回什么数据以及如何控制这些数据。 乍一看,GraphQL 似乎简化了 API 创建者和使用者双方的操作。 让我们听听 Nilan 的解释吧。
在设计各种 Web 服务的 API 架构的标准方面,REST 已经成为多年来的行业标准。 随着 REST 的广泛普及,GraphQL 替代它成为前端和后端之间 API 桥梁的说法遭到了很多质疑。 但 GraphQL 已经发展得非常成熟,正如 Facebook 宣布 GraphQL 投入生产 和 GitHub 揭示其 GitHub GraphQL API 所证明的那样。
GraphQL 所需的基础设施
与 REST 一样,在使用 GraphQL API 之前,我们需要几个组件。
- GraphQL 客户端 - 这使我们能够获取或修改存储在后端的数据。 如果您处理的是较小的项目,简单的 HTTP 请求可以很好地完成任务,因为请求和响应都以 JSON 编码。
- GraphQL 后端 - 我们必须公开一个 GraphQL 架构,该架构将我们的 API 描述为类型系统。 类型系统由称为查询(用于获取数据)和变异(用于修改数据)的不同方法组成。 这里才是真正的工作所在,因为我们必须在这些方法和数据层之间实现映射。 例如,查询
allUsers
用于获取所有用户,可能映射到类似SELECT * FROM USERS
的 SQL 查询。
在本文中,我们将探讨 Instagram 克隆的可能 GraphQL API,并重点介绍 GraphQL 带来的某些优势。
GraphQL 架构
REST API 的端点通常让人联想起数据库的实际架构。 类似 /users
或 /posts
的端点,它们允许访问数据库表 User
和 Post
,非常普遍。
然而,GraphQL 架构需要通过两步过程构建为类型系统。
步骤 1
对象类型由诸如 String 和 Boolean 等基本类型组成。 在我们的例子中,我们将使用 IDL 语法构建 User
和 Post
对象类型。
type User {
id: String!
name: String
posts: [Post]
}
type Post {
id: String!
imageUrl: String
description: String
author: User
}
我们有一个 User
对象类型,它包含类型为 String 的 name
字段和类型为 Post
列表(用 [Post] 表示)的 posts
字段,以及一个 Post
对象类型,它包含类型为 String 的 imageUrl
和 description
字段以及类型为 User
的 author
字段。
除了上面提到的字段之外,两个对象类型都具有 id
字段,它是一个必需的 String(用 String!
表示)。
步骤 2
然后使用这些类型来定义实际的查询,例如 allUsers
查询,它可以用于获取数据库中所有现有用户。 您基本上可以公开任何想到的内容,但最受欢迎的是用于获取特定类型的所有项目或一个项目的查询,以及用于创建、更新和删除特定类型项目的变异。
工具
编码在 GraphQL 架构中的类型系统为 GraphiQL 等强大工具铺平了道路,例如 GraphiQL 由 Facebook 维护。 它允许您以一种轻松的方式探索 GraphQL API。

自动完成功能(如 GIF 中所示)和自动生成的文档大大提高了开发人员体验,通常足以开始使用 GraphQL API。 现在,让我们仔细看看一些查询和变异!
GraphQL 查询
GraphQL 中的查询是声明性的和分层的。 我们将在片刻后看到这到底意味着什么,但前端应用程序中快速变化的数据需求使这成为 GraphQL 最大的卖点之一。
查询基础
假设我们只对所有用户的 id
和 name
感兴趣。 声明性意味着我们准确地声明了我们感兴趣的内容。
query {
allUsers {
id
name
}
}
查询响应仅包含我们刚刚声明的字段。
{
"data": {
"allUsers": [
{
"id": "some-id",
"name": "Nilan"
},
{
"id": "another-id",
"name": "Chris"
}
]
}
}
我们可以看到查询响应的结构与查询结构非常接近。 如果我们想通过查询获取更多数据,只需包含更多字段即可。
query {
allUsers {
id
name
posts {
imageUrl
}
}
}
这里我们看到了分层意味着什么。 该查询遵循架构的关系层次结构,我们可以为所有帖子选择我们感兴趣的字段。 响应可能是。
{
"data": {
"allUsers": [
{
"id": "some-id",
"name": "Nilan",
"posts": [
{
"imageUrl": "https://unsplash.it/200/300?image=31"
},
{
"imageUrl": "https://unsplash.it/200/300?image=38"
}
]
},
{
"id": "another-id",
"name": "Chris",
"posts": [
{
"imageUrl": "https://unsplash.it/200/300?image=99"
}
]
}
]
}
}
同样重要的是要注意,我们只是更改了查询,而没有触碰 GraphQL 后端,它仍然有效! 一旦我们想出了一个可靠的类型系统,并在 GraphQL 架构中公开它,我们就可以在前端动态更改查询,而 GraphQL 服务器会立即给出正确的响应。 这也意味着不再需要像 REST 中那样费心处理多个端点或 API 版本。
像我们之前那样组合分层字段也会减少前端和后端之间的 HTTP 请求数量。 使用 REST 获取用户及其所有朋友通常至少需要两个请求,而我们只需要一个请求。
高级查询功能
GraphQL 查询接受通常用于提供高级功能(例如过滤或分页)的查询参数。 我们这里不会深入探讨,但让我们看几个快速示例。
过滤非常灵活且强大。 例如,我们只能显示名为 Chris
的用户。
query {
allUsers(filter: {name: "Chris"}) {
id
name
}
}
不出所料,查询响应仅包含一个用户。
{
"data": {
"allUsers": [
{
"id": "another-id",
"name": "Chris"
}
]
}
}
使用分页,我们可以表示我们感兴趣的连续数据项的数量。 如果我们想构建一个类似于 Google 搜索结果的包含多个页面的提要,这尤其有用。
让我们只查询第一个用户。 我们可以使用 first
参数来完成此操作。
query {
allUsers(first: 1) {
id
name
}
}
正如预期的那样,我们只得到了第一个用户。
{
"data": {
"allUsers": [
{
"id": "some-id",
"name": "Nilan"
}
]
}
}
现在,如果我们想查询第二个用户,我们可以跳过第一个用户,并通过将 first
与 skip
相结合来仅获取下一个用户。
query {
allUsers(first: 1, skip: 1) {
id
name
}
}
这将返回第二个用户。
{
"data": {
"allUsers": [
{
"id": "another-id",
"name": "Chris"
}
]
}
}
这些只是我们可以使用查询参数的一些方法。 如果我们想提供另一个类似的功能,例如按字段对查询响应进行排序,我们必须在 GraphQL 架构中定义一个新的查询参数,并在后端相应地实现该功能。
变异
变异是查询的对应物。 虽然我们可以使用查询获取数据,但变异允许我们创建新数据或更新或删除现有数据项。 相应的变异可以分别称为 createPost
、updatePost
和 deletePost
。
新数据项的字段值通过查询参数提供。 变异也需要选择将作为查询响应返回的字段。 用于创建新帖子的变异可能如下所示。
mutation {
createPost(imageUrl: "https://unsplash.it/200/300?image=27", description: "#random", authorId: "some-id") {
id
}
}
响应将包含新创建的 id
。
{
"data": {
"createPost": {
"id": "some-newly-generated-id"
}
}
}
结论
本文概述了 GraphQL 作为 REST 的替代方案。
我们了解到,GraphQL 客户端需要连接前端和后端,以及 Instagram 克隆的 GraphQL 架构示例。我们学习了如何使用查询和变异来获取和修改数据,以及 GraphQL API 如何让我们以声明式和分层的方式精确地选择所需的字段。我们还简要了解了过滤和分页这两个强大的概念,同时 GraphiQL 展示了依赖于定义类型系统的工具的强大功能。
如果您想了解更多关于 GraphQL 的信息,您可以查看 GraphQL 网站的学习部分 和 学习 GraphQL,这两个都是非常容易理解的资源。
Relay 和 Apollo Client 是两个流行的 JavaScript GraphQL 客户端。如果您对 Relay 感兴趣,请访问 学习 Relay,获得一个交互式和全面的 Relay 入门指南。
graphql-js 和 Sangria 是两个流行的库,分别用于在 JavaScript 和 Scala 中构建 GraphQL 后端。
要快速开始使用 GraphQL,您可以查看 Graphcool,它允许您以图形方式定义模型和字段,自动生成 GraphQL 后端,并提供其他功能,如高级权限系统和开箱即用的文件管理。


感谢这篇文章。我是一个初学者,所以我需要更多简短的信息。你能帮助我吗?