当前位置: 首页 > 后端技术 > Node.js

从零开始写一个Koa+graphQL的案例

时间:2023-04-03 20:51:21 Node.js

看到Nest.js文档中关于集成GraphQL的指导,于是尝试在本地用Koa写一个DEMO,然后再与Nest.js集成。先把数据库模型写出来(这个文件之前就有,没做任何改动,文件名改成models.ts):/***2018/4/13由w创建。*/constmongoose=require('mongoose');mongoose.Promise=global.Promise;mongoose.connect('mongodb://localhost/ticket',{server:{socketOptions:{keepAlive:1}}});constmodels={users:{username:{type:String,required:true},password:{type:String,required:true},description:{type:String},createTime:{type:Date,默认值:newDate()}},tickets:{name:{type:String,required:true},price:{type:Number,required:true},holdTime:{//持有时间type:Date,required:true},count:{//剩余数量type:String,required:true},place:{type:String,required:true},img:{type:String},description:{type:String},publicTime:{type:Date,default:新达te()},}};for(letminmodels){mongoose.model(m,mongoose.Schema(models[m]));}module.exports={getModules:(name)=>{returnmongoose.型号名称);}};之后编写各个模型的GraphQL查询文件(user.ts))://@ts-ignoreconst{//@ts-ignoregraphql,GraphQLSchema,GraphQLObjectType,GraphQLString,GraphQLID,GraphQLList,GraphQLNonNull,GraphQLInt,isOutputType,}=require('graphql');//@ts-ignoreconstUser=require('../db/model').getModules('users');constuserType=newGraphQLObjectType({name:'User',fields:{用户名:{type:GraphQLString,},密码:{type:GraphQLString,},描述:{type:GraphQLString,},createTime:{type:GraphQLString,}}});module.exports={query:{type:新的GraphQLList(userType),args:{username:{username:'username',type:GraphQLNonNull(GraphQLString)}},resolve(root,params,options){if(params.username==='$all'){returnUser.find().exec()}returnUser.find({username:params.username}).exec();}},mutate:{type:newGraphQLList(userType),args:{operate:{name:'operate',type:GraphQLString},username:{name:'username',type:GraphQLNonNull(GraphQLString)},possword:{name:'price',type:GraphQLNonNull(GraphQLString)},createTime:{name:'createTime',type:GraphQLString,},description:{name:'description',type:GraphQLString}},resolve:异步(root,params,options)=>{try{if(params.operate==='$delete'){awaitUser.delete({username:params.username});returnUser.find().exec()}if(params.operate==='$update'){awaitUser.update({username:params.username});返回User.find({用户名:params.username}).exec()}letuser=newUser({username:params.username,password:params.password,description:params.description,createTime:params.createTime});等待user.save();returnuser.find({username:params.username}).exec()}catch(e){console.error("保存数据时出错:",e);}}}}ticket.ts://@ts-ignoreconst{//@ts-ignoregraphql,GraphQLSchema,GraphQLObjectType,GraphQLString,GraphQLID,GraphQLList,GraphQLNonNull,GraphQLInt,isOutputType,}=require('graphql');//@ts-ignoreconstTicket=require('../db/model').getModules('tickets');constticketType=newGraphQLObjectType({name:'Ticket',fields:{name:{type:GraphQLString},price:{type:GraphQLInt},holdTime:{type:GraphQLString},计数:{type:GraphQLInt},place:{type:GraphQLString},img:{type:GraphQLString},description:{type:GraphQLString},publicTime:{type:GraphQLString}}});module.exports={query:{type:newGraphQLList(ticketType),args:{name:{name:'name',类型:GraphQLNonNull(GraphQLString)}},resolve(root,params,options){if(params.name==='$all'){returnTicket.find().exec()}returnTicket.find({name:参数名称}).exec();}},mutate:{type:newGraphQLList(ticketType),args:{operate:{name:'operate',type:GraphQLString},name:{name:'name',type:GraphQLNonNull(GraphQLString)},价格:{name:'price',type:GraphQLInt},holdTime:{name:'holdTime',type:GraphQLNonNull(GraphQLString)},count:{name:'count',type:GraphQLNonNull(GraphQLInt)},place:{名称:'请ace',类型:GraphQLNonNull(GraphQLString)},img:{名称:'img',类型:GraphQLString},描述:{名称:'description',类型:GraphQLString},publicTime:{名称:'publicTime',类型:GraphQLString}},解析:async(root,params,options)=>{try{if(params.operate==='$delete'){awaitTicket.findOneAndRemove({name:params.name});返回Ticket.find().exec();}if(params.operate==='$update'){awaitTicket.findByIdAndUpdate({name:params.name},{name:params.name,price:params.price,holdTime:params.holdTime,count:params.count,place:params.place,img:params.img,description:params.description,publicTime:params.publicTime});返回Ticket.find().exec();}letticket=newTicket({name:params.name,price:params.price,holdTime:params.holdTime,count:params.count,place:params.place,img:params.img,description:params.description,publicTime:参数.publicTime});等待票证。保存();returnTicket.find({name:params.name}).exec()}catch(e){console.error("保存数据时出错:",e);}}}}接下来编写用于查询或修改数据的Schema.ts:const{//@ts-ignoreGraphQLSchema,GraphQLObjectType,}=require('graphql');//@ts-ignoreconstTicket=require('./ticket');//@ts-ignoreconstUser=require('./user');module.exports=newGraphQLSchema({query:newGraphQLObjectType({name:'Queries',fields:{Ticket:Ticket.query,User:User.query,}}),mutation:newGraphQLObjectType({name:'Mutations',fields:{Ticket:Ticket.mutate,User:User.mutate,}})})编写服务端(server.ts):constKoa=require('koa');constapp=newKoa();constkoaBody=require('koa-body');constCombileRouter=require('./combineRouter');app.使用(koaBody({multipart:true,formidable:{keepExtensions:true,},})).use(CombileRouter.routes()).use(CombileRouter.routes());app.listen(5000,()=>{console.log('Apprunning~');})确定票据路由的ticket.router.ts:constKoaRouter=require('koa-router');constticketRouter=newKoaRouter();//@ts-ignoreconst{graphqlKoa,graphiqlKoa}=require('graphql-server-koa');//@ts-ignoreconstTicket=require('../db/model').getModules('tickets');constticketSchema=require('../graphql/schema');ticketRouter.get('/ticket/all',async(ctx)=>{try{letresult=awaitTicket.find({});ctx.body={data:Object.assign({},result),code:'0'};}catch(e){console.error("Gettingallticketerror:",e);}});ticketRouter.post('/graphql',async(ctx,next)=>{console.log('graphql',ctx.request.body);awaitgraphqlKoa({schema:ticketSchema})(ctx,next)}).get('/graphql',async(ctx,next)=>{awaitgraphqlKoa({schema:ticketSchema})(ctx,next)}).get('/graphiql',async(ctx,next)=>{awaitgraphiqlKoa({endpointURL:'/graphql'})(ctx,next)})module.exports=ticketRouter;和之前定义的user.router.ts(测试用户路由是否可达):constRouter=require('koa-router');constuserRouter=newRouter();//@ts-ignoreconst{graphiqlKoa}=require('graphql-server-koa');userRouter.get('/user/all',async(ctx)=>{ctx.body={code:'0',msg:'OK',info:{data:[{username:'a',id:0,desc:'ok',},{username:'d',id:1,desc:'ok',},{username:'c',id:2,desc:'ok',},{用户名:'b',id:3,desc:'ok',}]}}});module.exports=userRouter;两个路由文件合并(combineRouter.ts):constUserRouter:object=require('./koa-router/user.router');constTicketRouter:object=require('./koa-router/ticket.router');constcombiner=(routers:object[]):对象=>{让arr=[];routers.forEach(v=>{//@ts-ignorearr.push(...v.stack)});returnObject.assign(routers[0],{stack:arr});}constres=combiner([UserRouter,TicketRouter]);module.exports=res;OK,这部分写完了基本的query和mutation函数,以及删除功能稍后添加tsconfig.jsonfile:{"compilerOptions":{"module":"commonjs","target":"es6","sourceMap":true,"experimentalDecorators":true,},"exclude“:[“节点模块”]}