玩转 GraphQL yoga 和 mongoose
由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!
本文将介绍如何使用 GraphQL yoga,它是一个基于 Express 的 GraphQL 服务器。
如果你还不了解 GraphQL,建议你先看看我之前的教程,里面我用 Express 和 GraphQL 做了演示。这应该能帮你快速入门。之后你可以学习如何用 GraphQL 和 React 创建一个电影网站,但这并非理解本文的必要条件。我们只是用不同的工具重新演示了之前的教程。
开始使用
让我们来搭建基本项目。在一个空目录中运行以下命令行
npm init -y
npm i -S graphql-yoga mongoose
touch index.js
第一行代码创建了 npm 项目,第二行代码安装了我们需要的两个包,为了简单起见,所有代码都将放在一个单独的文件中index.js。让我们创建一个非常基本的结构:
const { GraphQLServer } = require('graphql-yoga');
const typeDefs = `
type Query {
Greeting: String
}
`
const resolvers = {
Query: {
Greeting: () => `Hello World`
}
}
const server = new GraphQLServer({
typeDefs,
resolvers
})
server.start({port: 7777}, () => console.log(`The server is running on port 7777`))
我们graphql-yoga在顶部定义了需求,并在底部运行了服务器。GraphQL 服务器需要我们定义它将运行的查询类型,以及每个查询将返回的数据类型。
在我们的简化版本中,我们有一个查询,Greeting它会返回一个字符串。我们指定当调用该Greeting查询时Hello World,将返回该字符串。
现在,我们只需要在终端运行这个命令即可node index.js。我强烈建议你安装它,nodemon但这已经不是重点了。
现在你需要运行http://localhost:7777在GraphQL Playground中,或者使用在线 GraphQL Playground。然后只需运行以下查询:
{
Greeting
}
你会得到回复Hello World。
再深入一点
让我们添加一个对象数组
const typeDefs = `
type Query {
People: [PeopleObject]!
Greeting: String
}
type PeopleObject {
id: ID
first: String!
last: String!
}
`
const resolvers = {
Query: {
Greeting: () => `Hello World`,
People: () => [{first: 'Aurel', last: 'Kurtula'}]
}
}
我们已将其添加People为一个可能的查询。它必须返回一个对象数组,对象的属性在 `<object>` 中定义PeopleObject。请注意,`<object>` 的使用!使得这些属性成为必需的——这意味着我们必须返回这些内容。
然后我们硬编码了一个将要返回的数组。
在操场上,我们可以跑这个
{
Greeting
People{
first
last
}
}
正在连接到 MongoDB 数据库
在之前的教程中,我讲解了如何使用 mlab 创建 MongoDB 数据库。如果您尚未在本地安装 MongoDB,或者不知道如何设置 MongoDB 数据库,请先按照之前的教程操作。然后返回,在index.js页面顶部添加以下代码。
const mongoose = require('mongoose');
const db = mongoose.connect('mongodb://localhost:27017/population');
const Schema = mongoose.Schema;
const peopleSchema = new Schema({
first: { type: String },
last: { type: String}
})
const People = mongoose.model('people', peopleSchema)
如果您已在本地安装并运行 MongoDB,则上述步骤可以直接执行;否则,您需要更改 Mongoose 连接的 URL。MongoDB 数据库会population自动创建。接下来,我们创建一个模式。与 GraphQL 类似,我们需要告诉 Mongoose 将向模型添加什么类型的内容,然后指定模型。
从现在开始,您将会看到,我们只会与People模型进行交互,而数据库people中的模型population将受到影响。
Mongo 和 GraphQL
当我们People在 GraphQL Playground 中查询时,我们希望数据来自 MongoDB 数据库,而不是我们硬编码的数组。所以让我们来修改一下……resolvers
const resolvers = {
Query: {
Greeting: () => `Hello World`,
People: () => People.find({}),
}
}
这里我们返回数据库中模型的所有条目。
显然,如果我们在 playground 中重新运行查询,我们会得到一个空数组作为People查询结果,因为数据库中没有任何内容。
现在我们需要通过 GraphQL 向数据库添加数据。为此,我们需要使用 mutations:
const typeDefs = `
type Query {
people: [People!]!
person(id: ID!): People
}
type People {
id: ID
first: String
last: String
}
type Mutation {
createPerson(first: String!, last: String!): People
}
`
首先,我们指定类型;一个名为createPerson`it` 的 mutation 需要两个属性,并将返回一个People对象。和往常一样,我们需要指定运行该 mutation 的结果。resolvers
const resolvers = {
Query: {....},
Mutation: {
createPerson: async (parent, args) =>{
const newPerson = new People({
first: args.first,
last: args.last
})
const error = await newPerson.save()
if(error) return error
return newPerson
}
}
}
与其他解析器类似,我们希望在createPerson运行时执行某些操作。这次我们需要访问用户传递的变量,因此args(parent超出了本教程的范围)。
首先,我们创建newPerson要添加到数据库的对象;然后,我们创建一个新People模块,并将该对象填充到该newPerson模块中;最后,我们将该对象保存到数据库;然后,我们只需将新创建的对象返回给 GraphQL 服务器。
返回 GraphQL Playground
query people {
Greeting
People{
first
last
}
}
mutation addingPerson{
createPerson(first: "Gregor", last: "Samsa"){
first
last
}
}
在那里,如果你想运行 mutation,就addingPerson点击下拉菜单运行它。当然,添加 Gregor 之后,运行people查询时你就能看到这个小家伙了 :)
最后,让我们按照同样的逻辑,添加从数据库中删除人员的功能。
首先,指定类型deletePerson:
type Mutation {
createPerson(first: String!, last: String!): PeopleObject
deletePerson(id: ID!): PeopleObject
}
那么我们就把它归结为另一种突变吧:
const resolvers = {
...
Mutation: {
createPerson: (parent, args) =>{...},
deletePerson: (parent, args) => {
return new Promise( (resolve, reject) => {
People.findOneAndDelete(args.id, function(err, result){
if (err) return err;
resolve(result)
})
})
}
}
}
逻辑完全相同,Mongoose 允许我们通过 ID 删除对象findOneAndDelete。你可以deletePerson按如下方式进行测试:
mutation deleting{
deletePerson(id: "5c1ccc3de652317c2c79d4ee"){
first
last
}
}
本教程到此结束。
你可以在GitHub上找到代码。代码像一个完整的项目一样,被分成了不同的文件。
文章来源:https://dev.to/aurelkurtula/playing-with-graphql-yoga-and-mongoose-f4f