如何使用 GraphQL-yoga 和 MongoDB 在 Node.js 中构建 GraphQL 服务器

如今,大多数应用程序都需要从服务器获取数据,而这些数据都存储在数据库中。GraphQL 是一种新的 API 标准,它为 REST 提供了一种更高效、更强大、更灵活的替代方案。它允许客户端只从服务器获取所需的数据。 GraphQL 经常被混淆为一种数据库技术,但这是一种误解,GraphQL 是一种 API 查询语言,而不是数据库。从这个意义上说,它与数据库无关,可以有效地用于任何使用 API 的环境。

graphql-yoga 是一款功能齐全的 GraphQL 服务器,注重易用性、性能和良好的开发人员体验。此外,它还支持 Apollo 等所有 GraphQL 客户端。

现在,您已经了解了 GraphQL 是什么,可以学习在 Nodejs 应用程序中使用它来代替 REST。

创建新项目

新建一个名为 UsersAPI 的文件夹,打开终端并导航到该文件夹,然后运行以下命令:

1npm init

在项目文件夹中创建名为 index.js 的文件:

1touch index.js

这就完成了应用程序的设置。

安装所需的依赖项

您需要安装 graphql-yoga 来帮助设置 GraphQL 服务器,然后安装 mongoose 来帮助连接 Mongo 数据库。

在终端中运行以下程序:

1npm install graphql-yoga mongoose

定义用户模型

模型负责从底层 MongoDB 数据库中创建和读取文档。在此,我们将为 GraphQL 应用程序创建一个用户模型。

index.js 中键入以下代码:

 1const { GraphQLServer } = require('graphql-yoga')
 2const mongoose = require('mongoose');
 3mongoose.connect("mongodb://localhost:27017/UserApp");
 4
 5const User= mongoose.model("User",{
 6    fullname: String,
 7    username: String,
 8    phone_number: String,
 9    city: String
10});

我们已经成功定义了用户模型并建立了 mongoose 连接,现在是时候进入 GraphQL 模式了。

定义 GraphQL 模式

GraphQL 模式描述了连接到该模式的客户端可用的功能。它使用模式定义语言构建。

在您的 index.js 文件中添加以下代码行:

 1const typeDefs = `type Query {
 2    getUser(id: ID!): User
 3    getUsers: [User]
 4  }
 5  type User {
 6      id: ID!
 7      fullname: String!
 8      username: String!
 9      phone_number: String!
10      city: String!
11  }
12  type Mutation {
13      addUser(fullname: String!, username: String!, phone_number: String!, city: String!): User!,
14      deleteUser(id: ID!): String
15  }`

我们的模式中有三种类型,让我们对它们进行细分。

使用查询类型

GraphQL 查询用于获取数据,与基于 REST 的应用程序接口中的 GET 动词类似。 为了定义服务器上可以进行哪些查询,在模式定义语言(Schema Definition Language)中使用了查询类型。查询类型是一种根级类型,它为客户端定义了功能,并充当模式中其他更具体类型的入口点。

1type Query {
2    getUser(id: ID): User
3    getUsers: [User]
4}

在此查询类型中,我们定义了两种可在 GraphQL 服务器上使用的查询类型: getUser:返回与所提供 ID 匹配的特定用户对象。 getUsers:返回一个用户对象列表。

如果您熟悉基于 REST 的应用程序接口,通常会发现这些应用程序接口位于不同的端点上,但 GraphQL 允许同时对它们进行查询,并一次性返回结果。

注意:方括号表示您希望在 JSON 响应中得到一个可迭代对象或数组。您只会为 getUser 返回一个用户对象,为 getUsers 返回一个数组。

使用用户类型

用户是一种 GraphQL 对象类型,这意味着它是一种包含某些字段的类型。对象类型是模式中最常用的类型,代表一组字段。

1type User {
2    id: ID!
3    fullname: String!
4    username: String!
5    phone_number: String!
6    city: String!
7}

id、全名、用户名、电话号码和城市是用户类型的_____________________________________字段。

String 是内置标量类型之一。它指定了字段的数据类型。 String 表示字段不可为空。在模式定义语言中,我们用感叹号来表示。 ID 是唯一标识符,通常用作缓存的键。

使用突变类型

突变被发送到服务器以创建、更新或删除数据,这与 RESTful API 上的 PUT、POST、PATCH 和 DELETE 动词类似。 就像查询类型定义了 GraphQL 服务器上数据获取操作的入口点一样,根级突变类型也指定了数据操作的入口点。

1type Mutation {
2    addUser(fullname: String!, username: String!, phone_number: String!, city: String!): User!,
3    deleteUser(id: ID!): String
4}

这实现了两个突变:

  • addUser: 接受全名、用户名、电话号码和城市作为参数,称为 "输入类型",突变将返回新创建的用户对象。
  • deleteUser: 接受一个有效的用户 ID,并返回一个字符串信息,说明删除操作是否成功。

让我们继续为我们定义的模式编写解析器。

添加解析器

解析器是在 GraphQL API 中对数据执行业务逻辑的实际函数。每个查询和突变都有相应的解析器函数来执行逻辑。

在您的 index.js 文件中添加以下代码行:

 1const resolvers = {
 2    Query: {
 3      getUsers: ()=> User.find(),
 4      getUser: async (_,{id}) => {
 5        var result = await User.findById(id);
 6        return result;
 7    }
 8},
 9    Mutation: {
10        addUser: async (_, { fullname, username, phone_number, city }) => {
11            const user = new User({fullname, username, phone_number, city});
12            await user.save();
13            return user;
14        },
15        deleteUser: async (_, {id}) => {
16            await User.findByIdAndRemove(id);
17            return "User deleted";
18        }
19    }
20  }

设置 GraphQL 服务器

构建模式和解析器之后,就该设置服务器来处理请求了。graphql-yoga "是启动和运行 GraphQL 服务器的最简单方法,它是一个功能齐全的 GraphQL 服务器,注重用户友好的配置、性能和良好的开发人员体验。

index.js 中,添加以下代码行以设置服务器:

1const server = new GraphQLServer({ typeDefs, resolvers })
2mongoose.connection.once("open", function(){
3    server.start(() => console.log('Server is running on localhost:4000'))
4});

这样,你就从零开始构建了一个功能强大的 GraphQL 服务器,现在是提出一些请求的时候了。打开终端,运行以下命令启动服务器:

1node index.js

打开网络浏览器并导航至 http://localhost:4000/,浏览器上就会出现一个漂亮的 GraphQL 游戏场地,您可以在此运行示例查询。

添加新用户

在 playground 中运行以下查询,添加一个新用户:

1mutation{
2  addUser(fullname:"Ibe Ogele",username:"ibesoft",phone_number:"2348102331921",city:"Enugu"){
3    id
4    fullname
5    username
6    phone_number
7    city
8  }
9}

获取用户信息

运行下面的查询,获取某个用户的信息:

1query{
2  getUser(id:"user_id"){
3    id
4    fullname
5    username
6    phone_number
7    city
8  }
9}

让所有用户运行:

1query{
2  getUsers{
3    id
4    fullname
5    username
6    phone_number
7    city
8  }
9}

删除用户

您可以通过运行下面的查询删除某个用户:

1mutation{
2  deleteUser(id: "user_id")
3}

结论

使用 GraphQL,您可以向您的应用程序接口发送查询,并准确获得您所需的信息,不多也不少。GraphQL 查询总是返回可预测的结果。

Published At
Categories with 技术
comments powered by Disqus