返回介绍

三、Express 中集成 GraphQl 实现 Server API

发布于 2024-01-31 23:34:12 字数 7999 浏览 0 评论 0 收藏 0

3.1 安装 mongodb 造数据

使用 mongodb 做数据库演示,mac 安装 mongodbbrew 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();

打开本地调试

http://localhost:3000/graphql

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文