我们都有许多兴趣和爱好。例如,我对 JavaScript、90 年代独立摇滚和嘻哈、冷门爵士乐、匹兹堡市、披萨、咖啡以及约翰·卢里主演的电影感兴趣。我们的家人、朋友、熟人、同学和同事也都有自己的社交关系、兴趣和爱好。其中一些关系和兴趣是重叠的,例如我的朋友 Riley 就和我一样对 90 年代嘻哈和披萨感兴趣。而另一些则没有重叠,例如我的同事 Harrison,他更喜欢 Python 而不是 JavaScript,只喝茶,并且更喜欢当前的流行音乐。总而言之,我们每个人都与生活中的人们以及我们的关系和兴趣的重叠方式有着联系的图谱。
这类相互关联的数据正是 GraphQL 最初在 API 开发中着手解决的挑战。通过编写 GraphQL API,我们能够有效地连接数据,从而降低复杂性和请求数量,同时允许我们精确地为客户端提供所需的数据。(如果您更喜欢 GraphQL 的比喻,请查看在鸡尾酒会上遇见 GraphQL。)
在本文中,我们将使用 Apollo Server 包在 Node.js 中构建一个 GraphQL API。为此,我们将探讨基本的 GraphQL 主题,编写 GraphQL 模式,开发代码来解析我们的模式函数,并使用 GraphQL Playground 用户界面访问我们的 API。
什么是 GraphQL?
GraphQL 是一种用于 API 的开源查询和数据操作语言。它的开发目标是为数据提供单一端点,允许应用程序请求所需的确切数据。这不仅有利于简化我们的 UI 代码,而且还通过限制需要通过网络发送的数据量来提高性能。
我们正在构建什么
要遵循本教程,您需要 Node v8.x 或更高版本以及一些使用命令行的经验。
我们将为书籍摘录构建一个 API 应用程序,允许我们存储我们阅读内容中令人难忘的段落。API 用户将能够对他们的摘录执行“CRUD”(创建、读取、更新、删除)操作:
- 创建新的摘录
- 读取单个摘录以及摘录列表
- 更新摘录的内容
- 删除摘录
开始
首先,为我们的项目创建一个新目录,初始化一个新的节点项目,并安装我们需要的依赖项:
<code># 创建新目录 mkdir highlights-api # 进入目录 cd highlights-api # 初始化新的节点项目 npm init -y # 安装项目依赖项 npm install apollo-server graphql # 安装开发依赖项 npm install nodemon --save-dev</code>
在继续之前,让我们分解一下我们的依赖项:
-
apollo-server
是一个允许我们在 Node 应用程序中使用 GraphQL 的库。我们将将其用作独立库,但 Apollo 团队还创建了用于在现有 Node Web 应用程序中与 Express、hapi、Fastify 和 Koa 协同工作的中间件。 -
graphql
包含 GraphQL 语言,并且是apollo-server
的必需对等依赖项。 -
nodemon
是一个有用的库,它将监视我们的项目是否有更改并自动重新启动我们的服务器。
安装完我们的包后,接下来让我们创建应用程序的根文件,名为 index.js
。现在,我们将在这个文件中使用 console.log()
输出一条消息:
<code>console.log("? Hello Highlights");</code>
为了简化我们的开发过程,我们将更新 package.json
文件中的 scripts
对象以使用 nodemon
包:
<code>"scripts": { "start": "nodemon index.js" },</code>
现在,我们可以通过在终端应用程序中键入 npm start
来启动我们的应用程序。如果一切正常,您将看到 ? Hello Highlights
记录到您的终端。
GraphQL 模式类型
模式是我们数据和交互的书面表示。通过要求模式,GraphQL 对我们的 API 实施严格的计划。这是因为 API 只能返回在模式中定义的数据并执行交互。GraphQL 模式的基本组件是对象类型。GraphQL 包含五种内置类型:
- String: 使用 UTF-8 字符编码的字符串
- Boolean: 真值或假值
- Int: 32 位整数
- Float: 浮点值
- ID: 唯一标识符
我们可以使用这些基本组件构建 API 的模式。在一个名为 schema.js
的文件中,我们可以导入 gql
库并为我们的模式语法准备文件:
<code>const { gql } = require('apollo-server'); const typeDefs = gql` # 模式将放在这里 `; module.exports = typeDefs;</code>
要编写我们的模式,我们首先定义类型。让我们考虑一下我们如何为我们的摘录应用程序定义模式。首先,我们将创建一个名为 Highlight
的新类型:
<code>const typeDefs = gql` type Highlight { } `;</code>
每个摘录都将有一个唯一的 ID、一些内容、标题和作者。Highlight 模式将如下所示:
<code>const typeDefs = gql` type Highlight { id: ID content: String title: String author: String } `;</code>
我们可以通过添加感叹号来使其中一些字段成为必需字段:
<code>const typeDefs = gql` type Highlight { id: ID! content: String! title: String author: String } `;</code>
虽然我们已经为我们的摘录定义了一个对象类型,但我们还需要描述客户端如何获取该数据。这称为查询。我们稍后将深入探讨查询,但现在让我们在我们的模式中描述某人检索摘录的方式。当请求我们所有的摘录时,数据将作为数组(表示为 [Highlight]
)返回,当我们想要检索单个摘录时,我们需要将 ID 作为参数传递。
<code>const typeDefs = gql` type Highlight { id: ID! content: String! title: String author: String } type Query { highlights: [Highlight]! highlight(id: ID!): Highlight } `;</code>
现在,在 index.js
文件中,我们可以导入我们的类型定义并设置 Apollo Server:
<code>const {ApolloServer } = require('apollo-server'); const typeDefs = require('./schema'); const server = new ApolloServer({ typeDefs }); server.listen().then(({ url }) => { console.log(`? Highlights server ready at ${url}`); });</code>
如果我们保持节点进程运行,应用程序将自动更新和重新启动,但如果不是,则在终端窗口中从项目的目录键入 npm start
将启动服务器。如果我们查看终端,我们应该看到 nodemon 正在监视我们的文件并且服务器正在本地端口上运行:
<code>[nodemon] 2.0.2 [nodemon] to restart at any time, enter `rs` [nodemon] watching dir(s): *.* [nodemon] watching extensions: js,mjs,json [nodemon] starting `node index.js` ? Highlights server ready at http://localhost:4000/</code>
在浏览器中访问 URL 将启动 GraphQL Playground 应用程序,该应用程序提供用于与我们的 API 交互的用户界面。
GraphQL 解析器
虽然我们已经使用初始模式和 Apollo Server 设置开发了我们的项目,但我们还无法与我们的 API 交互。为此,我们将介绍解析器。解析器执行其名称所暗示的确切操作;它们解析 API 用户请求的数据。我们将通过首先在我们的模式中定义它们,然后在我们的 JavaScript 代码中实现逻辑来编写这些解析器。我们的 API 将包含两种类型的解析器:查询和变异。
让我们首先添加一些要交互的数据。在应用程序中,这通常是我们从数据库中检索和写入的数据,但对于我们的示例,让我们使用对象的数组。在 index.js
文件中添加以下内容:
let highlights = [ { id: '1', content: 'One day I will find the right words, and they will be simple.', title: 'Dharma Bums', author: 'Jack Kerouac' }, { id: '2', content: 'In the limits of a situation there is humor, there is grace, and everything else.', title: 'Arbitrary Stupid Goal', author: 'Tamara Shopsin' } ]
查询
查询从 API 请求特定数据,并以其所需格式显示。然后,查询将返回一个对象,其中包含 API 用户请求的数据。查询永远不会修改数据;它只访问数据。我们已经在模式中编写了两个查询。第一个返回摘录数组,第二个返回特定摘录。下一步是编写将返回数据的解析器。
在 index.js
文件中,我们可以添加一个 resolvers
对象,其中可以包含我们的查询:
const resolvers = { Query: { highlights: () => highlights, highlight: (parent, args) => { return highlights.find(highlight => highlight.id === args.id); } } };
highlights
查询返回完整的摘录数据数组。highlight
查询接受两个参数:parent
和 args
。parent
是 Apollo Server 中任何 GraqhQL 查询的第一个参数,并提供了一种访问查询上下文的方式。args
参数允许我们访问用户提供的参数。在这种情况下,API 用户将提供 id
参数来访问特定摘录。
然后,我们可以更新我们的 Apollo Server 配置以包含解析器:
const server = new ApolloServer({ typeDefs, resolvers });
编写了我们的查询解析器并更新了 Apollo Server 后,我们现在可以使用 GraphQL Playground 查询 API。要访问 GraphQL Playground,请在您的 Web 浏览器中访问 http://localhost:4000
。
查询的格式如下所示:
query { queryName { field field } }
考虑到这一点,我们可以编写一个查询来请求我们每个摘录的 ID、内容、标题和作者:
query { highlights { id content title author } }
假设我们在 UI 中有一个页面,只列出我们突出显示文本的标题和作者。我们不需要检索每个摘录的内容。相反,我们可以编写一个只请求我们需要的数据的查询:
query { highlights { title author } }
我们还编写了一个解析器,通过在我们的查询中包含 ID 参数来查询单个注释。我们可以这样做:
query { highlight(id: "1") { content } }
变异
当我们想要修改 API 中的数据时,我们使用变异。在我们的摘录示例中,我们将想要编写一个变异来创建一个新的摘录,一个更新现有摘录,以及第三个删除摘录。与查询类似,变异也应该以对象的形式返回结果,通常是执行的操作的最终结果。
更新 GraphQL 中任何内容的第一步是编写模式。我们可以通过向我们的 schema.js
文件添加变异类型来包含模式中的变异:
type Mutation { newHighlight (content: String! title: String author: String): Highlight! updateHighlight(id: ID! content: String!): Highlight! deleteHighlight(id: ID!): Highlight! }
我们的 newHighlight
变异将采用 content
的必需值以及可选的 title
和 author
值,并返回一个 Highlight
。updateHighlight
变异将要求将 highlight id
和 content
作为参数值传递,并将返回更新的 Highlight
。最后,deleteHighlight
变异将接受一个 ID
参数,并将返回已删除的 Highlight
。
更新了模式以包含变异后,我们现在可以更新 index.js
文件中的 resolvers
来执行这些操作。每个变异都会更新我们的 highlights
数据数组。
const resolvers = { Query: { highlights: () => highlights, highlight: (parent, args) => { return highlights.find(highlight => highlight.id === args.id); } }, Mutation: { newHighlight: (parent, args) => { const highlight = { id: String(highlights.length 1), title: args.title || '', author: args.author || '', content: args.content }; highlights.push(highlight); return highlight; }, updateHighlight: (parent, args) => { const index = highlights.findIndex(highlight => highlight.id === args.id); const highlight = { id: args.id, content: args.content, author: highlights[index].author, title: highlights[index].title }; highlights[index] = highlight; return highlight; }, deleteHighlight: (parent, args) => { const deletedHighlight = highlights.find( highlight => highlight.id === args.id ); highlights = highlights.filter(highlight => highlight.id !== args.id); return deletedHighlight; } } };
编写了这些变异后,我们可以使用 GraphQL Playground 来练习变异数据。变异的结构与查询几乎相同,指定变异的名称,传递参数值,并请求返回特定数据。让我们首先添加一个新的摘录:
mutation { newHighlight(author: "Adam Scott" title: "JS Everywhere" content: "GraphQL is awesome") { id author title content } }
然后,我们可以编写变异来更新摘录:
mutation { updateHighlight(id: "3" content: "GraphQL is rad") { id content } }
以及删除摘录:
mutation { deleteHighlight(id: "3") { id } }
总结
恭喜!您现在已经成功构建了一个使用 Apollo Server 的 GraphQL API,并且可以对内存中数据对象运行 GraphQL 查询和变异。我们已经为探索 GraphQL API 开发的世界奠定了坚实的基础。
以下是一些可以提升水平的后续步骤:
- 了解嵌套的 GraphQL 查询和变异。
- 遵循 Apollo 全栈教程。
- 更新示例以包含数据库,例如 MongoDB 或 PostgreSQL。
- 探索更多优秀的 CSS-Tricks GraphQL 文章。
- 使用您新获得的 GraphQL 知识来使用 Gatsby 构建静态网站。
以上是开始使用节点构建GraphQl API的详细内容。更多信息请关注PHP中文网其他相关文章!

对于Astro,我们可以在构建过程中生成大部分网站,但是有一小部分服务器端代码可以使用Fuse.js之类的搜索功能来处理搜索功能。在此演示中,我们将使用保险丝搜索一组个人“书签”


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

mPDF
mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

SublimeText3 英文版
推荐:为Win版本,支持代码提示!

WebStorm Mac版
好用的JavaScript开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

SublimeText3 Linux新版
SublimeText3 Linux最新版