Logo
Section 1 / 14

创建后端项目

学习如何使用 Apollo Server 搭建 Node.js GraphQL 后端。

导入

创建后端项目

学习如何使用 Apollo Server 搭建 Node.js GraphQL 后端。

创建 Node.js 项目

现在我们已经准备好所有前置条件,接下来创建我们的项目。GitHub 仓库中的最终项目包含服务器(后端代码)和客户端(前端代码)两个文件夹。本课程部分的所有命令都在服务器文件夹中执行。

要创建项目,可以运行以下命令:

1npm init

它会询问一些关于如何设置项目的配置问题。完成后,将生成一个 package.json 文件,其中包含项目的配置信息。

我们还需要添加两个依赖项。第一个是 Apollo Server,它允许我们实现 GraphQL API。

1npm install apollo-server

第二个是 nodemon 工具,当源文件发生变化时,它可以自动重启应用。虽然应用本身不需要 nodemon 也能正常运行,但使用它能更方便地进行开发。

1npm install --save-dev nodemon

所有代码最初都会放在 src/index.js 文件中,该文件目前为空。

执行以上所有命令后,目录结构如下:

1├── package-lock.json 2├── package.json 3└── src 4 ├── index.js

此时,我们的 package.json 文件应如下所示:

1{ 2 "name": "products-server", 3 "version": "1.0.0", 4 "description": "", 5 "main": "src/index.js", 6 "scripts": { 7 "start": "nodemon src/index.js" 8 }, 9 "author": "Ivan Mushketyk", 10 "dependencies": { 11 "apollo-server": "^3.0.2" 12 }, 13 "devDependencies": { 14 "nodemon": "^2.0.12" 15 } 16}

唯一需要手动添加的是 start 脚本,它允许我们运行应用程序。

1"scripts": { 2 "start": "nodemon src/index.js" 3}

这段代码使我们能够通过运行 npm start 命令来启动后端服务。这会进一步调用 nodemon 命令,运行 src/index.js 文件,它是后端服务器的入口点。

实现第一个 GraphQL 查询

在完成项目结构搭建后,我们可以开始编写第一个 GraphQL 查询。我们的第一个查询非常简单,仅返回一个静态字符串,表示应用名称。

我们要实现的 GraphQL Schema 如下:

1type Query { 2 appName: String 3}

接下来,我们开始编写 index.js 文件的内容,实现一个简单的 GraphQL 服务器,支持这个单一查询。

为了启动 GraphQL 服务器,我们需要从 apollo-server 库中创建一个 ApolloServer 类的实例。为此,需要提供两个参数:API 的 schema 和实现该 schema 的 resolvers。

1const { ApolloServer, gql } = require('apollo-server') 2 3const server = new ApolloServer({ 4 typeDefs: typeDefs, // GraphQL API 的 schema 5 resolvers: resolvers, // 查询和类型的实现 6})

首先,我们来看如何定义 API 的 schema。可以在 index.js 源文件中这样写:

1const typeDefs = gql` 2type Query { 3 appName: String 4} 5`

如果你不熟悉现代 JavaScript,这种语法可能看起来有些奇怪。被 “`” 包裹的字符串称为 模板字面量。它允许我们定义多行字符串,并在字符串中插入 JavaScript 表达式的值。

前面加上 gql 前缀是一种语法糖,等价于调用 gql 函数。

1gql(`...`)

虽然代码看起来不寻常,但它实际上只是将一个多行字符串传递给 gql 函数。为什么要调用这个函数?因为 gql 函数会解析我们定义的 GraphQL schema,然后将其结果传给 ApolloServer 构造函数。

接下来,我们需要定义 API 的实现方式。为此,需要指定当用户发送 appName 查询请求时应该做什么。这就是 ApolloServer 构造函数的第二个参数 resolvers 的作用,它在本例中是一个处理 appName 查询的函数。

对于 apollo-server,我们需要这样定义:

1const resolvers = { 2 Query: { 3 appName: () => 'ProductHunt clone' 4 }, 5}

这里,赋值给 resolvers 的对象提供了整个 GraphQL API 的实现。该对象只包含 Query 字段,用于实现 API 提供的查询。稍后我们会看到如何为该对象添加其他字段。

当前它只实现了 appName 查询,该查询简单地返回一个静态字符串。

1appName: () => 'ProductHunt clone'

如果上述代码看起来有些困惑,以下是 resolver 定义与 GraphQL schema 之间关系的图形化说明:

...
Resolvers and queries

最后,我们再做一点语法优化,这是 JavaScript 中常见的技巧:当对象键名与变量名相同时,可以省略键名。

1const server = new ApolloServer({ 2 typeDefs, 3 resolvers, 4})

将所有内容组合起来,最终代码如下:

1const typeDefs = gql` 2type Query { 3 appName: String 4} 5` 6 7const resolvers = { 8 Query: { 9 appName: () => 'ProductHunt clone' 10 }, 11} 12 13const server = new ApolloServer({ 14 typeDefs, 15 resolvers, 16})

最后一步是启动服务器。为此,需要调用 server.listen() 方法。该方法返回一个 Promise,代表一个尚未完成的异步操作,类似于 Java 中的 Future。如果我们对 Promise 实例调用 then() 并传入一个函数,当服务器准备就绪并可以处理请求时,该函数就会被执行。

1server.listen().then(() => { 2 console.log('Listening on port 4000') 3})

我们的简易 GraphQL 服务器已准备就绪!可以通过运行 npm start 命令来启动它。

1npm start

该命令会执行之前在 package.json 中定义的脚本,即运行 nodemon src/index.js。

1$ npm start 2 3> products-server@1.0.0 start 4> nodemon src/index.js 5 6[nodemon] 2.0.12 7[nodemon] to restart at any time, enter `rs` 8[nodemon] watching path(s): *.* 9[nodemon] watching extensions: js,graphql 10[nodemon] starting `node src/index.js` 11Listening on port 4000

看到输出后,就可以访问以下地址向我们的 GraphQL 服务器发送请求:localhost:4000/graphql。

该链接会提示你使用 Apollo 的 GraphQL 探索器。

...
A prompt to use Apollo Studio to test the GraphQL API

探索器可离线使用,打开后可以向本地开发环境发送 GraphQL 请求。默认情况下,它配置为向 localhost:4000 发送请求。

现在,是时候向我们的 GraphQL API 发送第一个查询了。

1query { 2 appName 3}

执行此查询后,应得到如下结果:

1{ 2 "data": { 3 "appName": "ProductHunt clone" 4 } 5}

在浏览器中的效果如下:

Send a GraphQL query using Apollo Studio
Send a GraphQL query using Apollo Studio

交互式演示

在课程的每节课之后,都可以使用交互式演示运行当前版本的应用程序。

要运行应用,请点击交互式演示底部的“运行”按钮,等待出现如下输出。结果可能需要一两分钟才能显示。

1Listening on the port 4000

当应用运行后,点击代码窗口底部的链接即可使用 GraphQL 探索器发送 GraphQL 查询。

No configuration found for ID: f8fb826e361b7b9711e298a0a01c40f63fde06b630960338b87a9fcb343bdfe2

至此,我们已经搭建好了 GraphQL 服务器的基础框架,可以开始构建应用了。但在继续之前,让我们对代码进行一些重构,使其更具可维护性。

源码获取

要获取本章的源代码,可以在项目仓库中运行以下命令:

1git checkout initial-version

总结

在本课中,我们学习了如何从零开始创建一个简单的 GraphQL 服务器,并使用 Apollo Studio 进行查询测试。

开始使用 GraphQL

后端项目结构组织