(三)搭建graphql项目, 前端可随意指定接口返回的数据

前言

上节课,我提到想直接使用线上mlab搭建数据库,但线上mlab一直没法正常登陆(或者好不容易登陆进去,却是cloud mongodb,收费的),所以耽误了这些天,只能选择本地安装mongodb。简单介绍下mongodb本地的安装步骤

  • 去官网下载mongodbmsi包(我的电脑是Win10)
  • 安装成功之后,它会自动在C盘Program Files创建含bin文件的目录,将其添加到系统环境变量里(我选择将datalog文件存储在D盘

image.png

image.png

  • 在命令行终端,输入mongod,有输出信息,或者浏览器地址栏输入http://127.0.0.1:27017,看到如下信息,都表明安装已成功
It looks like you are trying to access MongoDB over HTTP on the native driver port.

连接mongodb

app.js里,添加如下代码

const mongoose = require('mongoose');

mongoose.connect('mongodb://localhost/admin') // 我使用了本地mongodb的默认admin数据库
mongoose.connection.once('open', () => {
    console.log('connected to database')
})

在命令行终端输入$ nodemon server/app.js,看到如下信息,则表明已成功连接数据库

image.png

models

之前我们将personsjobs直接存储在内存中,现在我们需要将它们存储在mongodb里,基于此,我们在项目根目录下创建models文件夹,在该文件夹下,创建两个js文件->person.js以及job.js

person.js的代码如下所示:

const mongoose = require('mongoose')
const Schema = mongoose.Schema;

const personSchema = new Schema({
    name: String,
    sex: String,
    age: String,
    jobId: String
})

module.exports = mongoose.model("Person", personSchema)

module.exports = mongoose.model("Person", personSchema):创建名为PersonCollection,它里面的数据结构为personSchema对象

我们不需要在里面定义id,因为数据库会自动为每条数据生成id

job.js的代码如下所示:

const mongoose = require('mongoose')
const Schema = mongoose.Schema;

const jobSchema = new Schema({
    name: String,
    department: String
})

module.exports = mongoose.model("Job", jobSchema)

mutation

搭建完models之后,我们需要创建mutation对数据库实现增删改操作,与vuex里的mutation原理类似。我们需要修改schema.js,部分代码如下所示:

const Person = require('../models/person')
const Job = require('../models/job')

const Mutation = new GraphQLObjectType({
    name: 'Mutation',
    fields: {
        addPerson: {
            type: PersonType,
            args: {
                name: {type: GraphQLString},
                sex: {type: GraphQLString},
                age: {type: GraphQLInt}
            },
            resolve(parent, args) {
                // Person对应上面的model
                let person = new Person({
                    name: args.name,
                    sex: args.sex,
                    age: args.age
                })
                person.save() // 这是mongoose提供的便利,实例直接调用save方法,可将数据存储在我们指定的数据库内
            }
        },
        addJob: {
            type: JobType,
            args: {
                name: {type: GraphQLString},
                department: {type: GraphQLString}
            },
            resolve(parent, args) {
                let job = new Job({
                    name: args.name,
                    department: args.department
                })
                return job.save()
            }
        },
    }
})

module.exports = new GraphQLSchema({
    query: RootQuery,
    mutation: Mutation
})

刷新页面http://localhost:4000/graphql,在左侧输入下图命令并运行

image.png

很明显,数据已经成功插入,可为何右侧显示"addPerson": null,这是因为我们需要在resolve里返回数据,修改resolve里的代码

resolve(parent, args) {
    let person = new Person({
        name: args.name,
        sex: args.sex,
        age: args.age
    })
    return person.save()
}

再次运行命令,界面如下所示:

image.png

执行addJob命令,如下所示:

image.png

关联PersonJob

从前文我们可以得知,Person可以关联Job,是通过里面的jobId,现在我们需要知道我们刚刚插入的job数据对应的id是多少,我推荐安装mongodb的图形化管理工具,即MongoDBCompass(官方提供的),方便查看管理数据

MongoDBCompass我下载的是zip压缩文件,解压之后,直接打开.exe文件,连接本地数据库之后,进入到admin数据库,可看到我们刚创建的jobs数据

image.png

新建person数据,将上图中的id:61f0bd5de1db61c31d991977与该人关联,修改schema.js,部分内容如下所示:

const Mutation = new GraphQLObjectType({
    name: 'Mutation',
    fields: {
        addPerson: {
            type: PersonType,
            args: {
                ...,
                jobId: {type: GraphQLID}
            },
            resolve(parent, args) {
                let person = new Person({
                    ...,
                    jobId: args.jobId
                })
                return person.save()
            }
        },
    }
})
       

刷新页面,执行命令

image.png

查看数据库界面,可看到新增后的数据

image.png

查询Person所在的Job

为此,我们需要修改Person结构体,代码如下所示:

const Job = require('../models/job')
const PersonType = new GraphQLObjectType({
    name: 'Person',
    fields: () => ({
        id: {type: GraphQLID},
        name: {type: GraphQLString},
        sex: {type: GraphQLString},
        age: {type: GraphQLInt},
        job: {
            type: JobType,
            resolve(parent, args) {
                // return _.find(jobs, {id: parent.jobId})
                // mongoose提供的model,内置findById、find方法
                return Job.findById(parent.jobId)
            }
        }
    })
})

刷新页面,左侧输入以下命令,查询到对应的结果

image.png

查询Job所有的persons

我们需要查询某个岗位所有人员,为此,需要重构JobType,代码如下所示:

const JobType = new GraphQLObjectType({
    name: 'Job',
    fields: () => ({
        id: {type: GraphQLID},
        name: {type: GraphQLString},
        department: {type: GraphQLString},
        persons: {
            type: new GraphQLList(PersonType),
            resolve(parent, args) {
                return Person.find({
                    jobId: parent.id
                })
            }
        }
    })
})

通过mutation addPerson增加lisi人员,并将他与jobId: "61f0bd5de1db61c31d991977"关联

image.png

再次执行查询,可见该Job岗位有两位人员

image.png

schema

schema.jsRootQuery也应做相应的更改,此时查询都应基于model进行find(若参数为空,则查询所有数据)或findById(根据id进行查询),完整的代码如下所示:

const graphql = require('graphql')
const { 
    GraphQLObjectType,
    GraphQLString,
    GraphQLSchema,
    GraphQLID,
    GraphQLInt,
    GraphQLList
} = graphql
const _ = require('lodash')
const Person = require('../models/person')
const Job = require('../models/job')

// 创建Person结构体
const PersonType = new GraphQLObjectType({
    name: 'Person',
    fields: () => ({
        id: {type: GraphQLID},
        name: {type: GraphQLString},
        sex: {type: GraphQLString},
        age: {type: GraphQLInt},
        job: {
            type: JobType,
            resolve(parent, args) {
                return Job.findById(parent.jobId)
            }
        }
    })
})

const JobType = new GraphQLObjectType({
    name: 'Job',
    fields: () => ({
        id: {type: GraphQLID},
        name: {type: GraphQLString},
        department: {type: GraphQLString},
        persons: {
            type: new GraphQLList(PersonType),
            resolve(parent, args) {
                return Person.find({
                    jobId: parent.id
                })
            }
        }
    })
})


const RootQuery = new GraphQLObjectType({
    name: 'RootQueryType',
    fields: {
        person: {
            type: PersonType,
            args: {
                id: {type: GraphQLID}
            },
            resolve(parent, args) {
                return Person.findById(args.id)
            }

        },
        job: {
            type: JobType,
            args: {
                id: {type: GraphQLID}
            },

            resolve(parent, args) {
                return Job.findById(args.id)
            }

        },
        persons: {
            type: new GraphQLList(PersonType),
            resolve(parent, args) {
                return Person.find({})
            }

        },

        jobs: {
            type: new GraphQLList(PersonType),
            resolve(parent, args) {
                return Job.find({})
            }
        }

    }

})

const Mutation = new GraphQLObjectType({
    name: 'Mutation',
    fields: {
        addPerson: {
            type: PersonType,
            args: {
                name: {type: GraphQLString},
                sex: {type: GraphQLString},
                age: {type: GraphQLInt},
                jobId: {type: GraphQLID}
            },
            resolve(parent, args) {
                let person = new Person({
                    name: args.name,
                    sex: args.sex,
                    age: args.age,
                    jobId: args.jobId
                })
                return person.save()
            }
        },
        addJob: {
            type: JobType,
            args: {
                name: {type: GraphQLString},
                department: {type: GraphQLString}
            },
            resolve(parent, args) {
                let job = new Job({
                    name: args.name,
                    department: args.department
                })
                return job.save()
            }
        },
    }
})
module.exports = new GraphQLSchema({
    query: RootQuery,
    mutation: Mutation
})

结语

今天的课程先到这里,下节课我将为大家介绍,如何在mutation时,限制用户必须传入某些参数才能成功等等其他相关知识

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值