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

来自菜鸟教程
跳转至:导航、​搜索

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

graphql-yoga 是一款功能齐全的 GraphQL 服务器,专注于易用性、性能和出色的开发人员体验。 此外,它支持所有 GraphQL 客户端,例如 Apollo。

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

创建新项目

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

npm init

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

touch index.js

这负责设置您的应用程序。

安装所需的依赖项

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

在您的终端内运行以下命令:

npm install graphql-yoga mongoose

定义用户模型

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

index.js 中键入以下代码行:

const { GraphQLServer } = require('graphql-yoga')
const mongoose = require('mongoose');
mongoose.connect("mongodb://localhost:27017/UserApp");


const User= mongoose.model("User",{
    fullname: String,
    username: String,
    phone_number: String,
    city: String
});

我们已经成功地定义了我们的用户模型并建立了一个猫鼬连接,是时候进入 GraphQL Schemas 了。

定义 GraphQL 模式

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

将以下这些代码行添加到您的 index.js 文件中:

const typeDefs = `type Query {
    getUser(id: ID!): User
    getUsers: [User]
  }
  type User {
      id: ID!
      fullname: String!
      username: String!
      phone_number: String!
      city: String!
  }
  type Mutation {
      addUser(fullname: String!, username: String!, phone_number: String!, city: String!): User!,
      deleteUser(id: ID!): String
  }`

我们的 Schema 中有三种类型,让我们分解它们。

使用查询类型

GraphQL 查询用于获取数据并与基于 REST 的 API 中的 GET 动词进行比较。 为了定义服务器上可能的查询,在模式定义语言中使用查询类型。 Query 类型是一种根级别的类型,它为客户端定义功能并充当模式中其他更具体类型的入口点。

type Query {
    getUser(id: ID): User
    getUsers: [User]
}

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

如果您熟悉基于 REST 的 API,您通常会发现它们位于不同的端点上,但 GraphQL 允许同时查询并立即返回它们。

注意:方括号表示您期望 JSON 响应中有一个可迭代对象或数组。 您将只为 getUser 返回一个 User 对象,为 getUsers 返回一个数组。

使用用户类型

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

type User {
    id: ID!
    fullname: String!
    username: String!
    phone_number: String!
    city: String!
}

id、fullname、username、phone_number 和 city 是 User 类型的字段。

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

使用突变类型

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

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

这实现了两个突变:

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

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

添加解析器

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

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

const resolvers = {
    Query: {
      getUsers: ()=> User.find(),
      getUser: async (_,{id}) => {
        var result = await User.findById(id);
        return result;
    }
},
    Mutation: {
        addUser: async (_, { fullname, username, phone_number, city }) => {
            const user = new User({fullname, username, phone_number, city});
            await user.save();
            return user;
        },
        deleteUser: async (_, {id}) => {
            await User.findByIdAndRemove(id);
            return "User deleted";
        }
    }
  }

设置 GraphQL 服务器

构建 Schema 和 Resolver 之后,是时候设置服务器来处理请求了。 graphql-yoga是启动和运行 GraphQL 服务器的最简单方法,它是一个功能齐全的 GraphQL 服务器,专注于用户友好的配置、性能和出色的开发人员体验。

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

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

至此,您已经从头构建了一个功能强大的 GraphQL 服务器,是时候发出一些请求了。 打开终端并运行以下命令来启动服务器:

node index.js

打开您的 Web 浏览器并导航到 http://localhost:4000/ 一个不错的 GraphQL 游乐场将出现在您的浏览器上,您可以在其中运行示例查询。

添加新用户

在 Playground 中运行以下查询以添加新用户:

mutation{
  addUser(fullname:"Ibe Ogele",username:"ibesoft",phone_number:"2348102331921",city:"Enugu"){
    id
    fullname
    username
    phone_number
    city
  }
}

获取用户信息

运行以下查询以获取特定用户的信息:

query{
  getUser(id:"user_id"){
    id
    fullname
    username
    phone_number
    city
  }
}

要让所有用户运行:

query{
  getUsers{
    id
    fullname
    username
    phone_number
    city
  }
}

删除用户

您可以通过运行以下查询来删除特定用户:

mutation{
  deleteUser(id: "user_id")
}

结论

使用 GraphQL,您可以向您的 API 发送查询,并准确获得您需要的内容,不多也不少。 GraphQL 查询总是返回可预测的结果。