在Express中使用GraphQL主要有以下几步:
1. 安装 graphql 和 express-graphql。
2. 引入express-graphql。
3. 引入自定义的schema,其中定义schema又分为以下几步:
(1). 定义查询字段的schema类型。
(2). 定义一个根 , 根里面定义调用schema类型的方法。
(3). 把根挂载到 GraphQLSchema。
4. 配置中间件,注意要放在实例化express之后。
下面用代码来说明具体的实现步骤:
首先是Express中的主文件app.js。
代码语言:javascript复制const express = require('express');
// const DB = require('./model/db.js');
// 1. npm install express-graphql graphql --save
// 2. 引入express-graphql
const graphqlHTTP = require('express-graphql');
// 3. 引入自定义的schema
const GraphQLDefaultSchema = require('./schema/default.js');
var app = express();
// 4. 配置中间件,要放在实例化express之后
// 配置了以后,访问这个路由就可以得到一个可视化的界面了
app.use('/graphql', graphqlHTTP({
// 自定义的schema
schema: GraphQLDefaultSchema,
// 上线改为false,调试模式时为true
graphiql: true
}));
// app.get('/', function (req, res) {
// res.send('你好 Express');
// });
// app.get('/getNavList', async (req, res) => {
// var result = await DB.find('nav', {});
// res.send(result);
// });
app.listen(3000, '127.0.0.1');
然后是app.js里引入的自定义的schema,文件名为default.js。
代码语言:javascript复制const DB = require('../model/db.js');
// 从graphql中获取所需要的子模块
const {
// schema类型
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: {
// 方法名称:定义调用导航schema类型的方法
oneNavList: {
// 方法的类型, 方法返回的参数必须和NavSchema里面定义的类型一致
type: 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) });
// 由于NavSchema的类型为一个对象,所以返回写成navList[0]的形式
return navList[0];
}
},
// 查询所有的Nav
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) });
// 要返回一个JSON对象
return articlecateList[0];
}
}
}
})
//3.把根挂载到 GraphQLSchema
module.exports = new GraphQLSchema({
query: RootSchema
})
最后是在default.js里引入的封装过的数据库。
代码语言:javascript复制var MongoDB = require('mongodb');
var MongoClient = MongoDB.MongoClient;
var ObjectID = MongoDB.ObjectID;
var Config = {
dbUrl: 'mongodb://localhost:27017/',
dbName: 'koa'
};
class DB {
static getInstance() {
if (!DB.instance) {
DB.instance = new DB();
}
return DB.instance;
}
constructor() {
this.dbClient = '';
this.connect();
}
// 连接数据库
connect() {
let that = this;
return new Promise((resolve, reject) => {
if (!that.dbClient) {
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);
}
})
}
// 查找方法
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 = json3.page || 1;
var pageSize = json3.pageSize || 20;
var slipNum = (page - 1) * pageSize;
if (json3.sortJson) {
var sortJson = json3.sortJson;
} else {
var sortJson = {}
}
} else {
console.log('传入参数错误')
}
return new Promise((resolve, reject) => {
this.connect().then((db) => {
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.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);
}
})
})
})
}
// MongoDB按ID的查询方法
getObjectId(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();