文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
三、Express 中集成 GraphQl 实现 Server API
3.1 安装 mongodb 造数据
使用 mongodb
做数据库演示,mac 安装 mongodb
, brew install mongodb-community
# 进入 mongo shell mongo # 创建数据库 use graphql (graphql 数据库不存在会自动创建) # 创建 nav、articlecate 集合插入数据 db.nav.insert({name: "标题 1", url: "/", sort: 1, add_time: "2022-06-30"}) db.nav.insert({name: "标题 2", url: "/", sort: 1, add_time: "2022-06-30"}) db.nav.insert({name: "标题 3", url: "/", sort: 1, add_time: "2022-06-30"}) db.articlecate.insert({name: "分类 1", description: "描述", keywords: "关键词", status: 1}) db.articlecate.insert({name: "分类 2", description: "描述", keywords: "关键词", status: 1}) db.articlecate.insert({name: "分类 3", description: "描述", keywords: "关键词", status: 1})
或者导入数据库数据
下载数据库文件解压并导入 mongodb 即可 https://blog.poetries.top/db/koa.zip
导入 mongodb 数据库
mongorestore -h localhost:27017 -d koa-demo(数据库名称,不存在会自动创建) ./dump(本地数据文件路径)
3.2 express 集成 GraphQl
https://github.com/graphql/express-graphql
npm install express-graphql graphql--save
引入 express-graphql 配置中间件
app 完善配置
// app.js var express=require('express'); var DB=require('./model/db.js'); const graphqlHTTP = require('express-graphql'); const GraphQLDefaultSchema = require('./schema/default.js'); var app=express(); // 配置中间件 app.use('/graphql', graphqlHTTP({ schema: GraphQLDefaultSchema, graphiql: true // 线上环境关闭,开发环境开启 })); //配置路由 app.get('/',function(req,res){ res.send('hello express'); }) app.listen(3000,()=>console.log("http://localhost:3000"));
定义 GraphQLSchema 模型
- 新建
schema/default.js
- 定义
Schema
const DB=require('../model/db.js'); /*引入 DB 库*/ const { GraphQLObjectType, GraphQLString, GraphQLInt, GraphQLSchema, GraphQLList } =require('graphql') //1、获取导航列表 定义导航的 schema 类型 var NavSchema=new GraphQLObjectType({ name:'nav', fields:{ _id:{ type:GraphQLString }, title:{ type:GraphQLString }, url:{ type:GraphQLString }, sort:{ type:GraphQLInt }, status:{ type:GraphQLInt }, add_time:{ type:GraphQLString } } }) var ArticleCateSchema=new GraphQLObjectType({ name:'articlecate', fields:{ _id:{ type:GraphQLString }, title:{ type:GraphQLString }, description:{ type:GraphQLString }, keywords:{ type:GraphQLString } , status:{ type:GraphQLInt } } }) //2、定义一个跟 根里面定义调用导航 Schema 类型的方法 var RootSchema=new GraphQLObjectType({ name:'root', fields:{ oneNavList:{ //方法名称:定义调用导航 Schema 类型的方法 type:NavSchema, //方法的类型, 方法返回的参数必须和 NavSchema 里面定义的类型一致 args:{id:{type:GraphQLString}}, //参数 async resolve(parent,args){ //执行的操作 // args.id 获取调用方法传入的值 var id=args.id; var navList=await DB.find('nav',{"_id":DB.getObjectId(id)}); return navList[0]; } }, navList:{ type:GraphQLList(NavSchema), async resolve(parent,args){ var navList=await DB.find('nav',{}); return navList; } }, articleCateList:{ type:GraphQLList(ArticleCateSchema), async resolve(parent,args){ var articlecateList=await DB.find('articlecate',{}); return articlecateList; } }, oneArticleCateList:{ type:ArticleCateSchema, args:{id:{type:GraphQLString}}, async resolve(parent,args){ var id=args.id; var articlecateList=await DB.find('articlecate',{"_id":DB.getObjectId(id)}); return articlecateList[0]; //要返回一个 json 对象 } } } }) //3、把根挂载到 GraphQLSchema module.exports=new GraphQLSchema({ query:RootSchema })
编写数据库操作方法
/** * http://mongodb.github.io/node-mongodb-native * http://mongodb.github.io/node-mongodb-native/3.0/api/ */ //DB 库 var MongoDB=require('mongodb'); var MongoClient =MongoDB.MongoClient; const ObjectID = MongoDB.ObjectID; var Config= { dbUrl: 'mongodb://localhost:27017/', dbName: 'graphql' // 数据库名 } class Db { static getInstance(){ /*1、单例 多次实例化实例不共享的问题*/ if(!Db.instance){ Db.instance=new Db(); } return Db.instance; } constructor(){ this.dbClient=''; /*属性 放 db 对象*/ this.connect(); /*实例化的时候就连接数据库*/ } connect(){ /*连接数据库*/ let _that=this; return new Promise((resolve,reject)=>{ if(!_that.dbClient){ /*1、解决数据库多次连接的问题*/ MongoClient.connect(Config.dbUrl,{ useNewUrlParser: true },(err,client)=>{ if(err){ reject(err) }else{ _that.dbClient=client.db(Config.dbName); resolve(_that.dbClient) } }) }else{ resolve(_that.dbClient); } }) } /* DB.find('user',{}) 返回所有数据 DB.find('user',{},{"title":1}) 返回所有数据 只返回一列 DB.find('user',{},{"title":1},{ 返回第二页的数据 page:2, pageSize:20, sort:{"add_time":-1} }) js 中实参和形参可以不一样 arguments 对象接收实参传过来的数据 * */ find(collectionName,json1,json2,json3){ if(arguments.length==2){ var attr={}; var slipNum=0; var pageSize=0; }else if(arguments.length==3){ var attr=json2; var slipNum=0; var pageSize=0; }else if(arguments.length==4){ var attr=json2; var page=parseInt(json3.page) ||1; var pageSize=parseInt(json3.pageSize)||20; var slipNum=(page-1)*pageSize; if(json3.sort){ var sortJson=json3.sort; }else{ var sortJson={} } }else{ console.log('传入参数错误') } return new Promise((resolve,reject)=>{ this.connect().then((db)=>{ //var result=db.collection(collectionName).find(json); var result =db.collection(collectionName).find(json1,{fields:attr}).skip(slipNum).limit(pageSize).sort(sortJson); result.toArray(function(err,docs){ if(err){ reject(err); return; } resolve(docs); }) }) }) } update(collectionName,json1,json2){ return new Promise((resolve,reject)=>{ this.connect().then((db)=>{ //db.user.update({},{$set:{}}) db.collection(collectionName).updateOne(json1,{ $set:json2 },(err,result)=>{ if(err){ reject(err); }else{ resolve(result); } }) }) }) } insert(collectionName,json){ return new Promise((resolve,reject)=>{ this.connect().then((db)=>{ db.collection(collectionName).insertOne(json,function(err,result){ if(err){ reject(err); }else{ resolve(result); } }) }) }) } remove(collectionName,json){ return new Promise((resolve,reject)=>{ this.connect().then((db)=>{ db.collection(collectionName).removeOne(json,function(err,result){ if(err){ reject(err); }else{ resolve(result); } }) }) }) } getObjectId(id){ /*mongodb 里面查询 _id 把字符串转换成对象*/ return new ObjectID(id); } //统计数量的方法 count(collectionName,json){ return new Promise((resolve,reject)=> { this.connect().then((db)=> { var result = db.collection(collectionName).count(json); result.then(function (count) { resolve(count); } ) }) }) } } module.exports=Db.getInstance();
打开本地调试
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论