# Graphql **Repository Path**: wei13013451000/graphql ## Basic Information - **Project Name**: Graphql - **Description**: graphqlgraphqlgraphql - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2022-02-18 - **Last Updated**: 2024-11-22 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README [B站视频学习地址](https://www.bilibili.com/video/BV1C64y197gZ?p=1) # 1.初探![image-20220218215846811](README_files/image-20220218215846811.png) ![image-20220218220008965](README_files/image-20220218220008965.png) ```cmd //安装依赖 code\helloworld> npm i apollo-server-express express graphql -S ``` ```js // helloworld/index.js // 官方代码 const express = require('express'); const { ApolloServer, gql } = require('apollo-server-express'); const typeDefs = gql` type Query { hello: String } `; const resolvers = { Query: { hello: () => 'Hello world!', }, }; const server = new ApolloServer({ typeDefs, resolvers }); const app = express(); server.applyMiddleware({ app }); app.listen({ port: 4000 }, () => console.log('Now browse to http://localhost:4000' + server.graphqlPath) ); ``` ```cmd // 运行服务 node index ``` ```json //package.json // 注意依赖版本,不然node启动出错 { "name": "helloworld", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "apollo-server-express": "^2.4.8", "express": "^4.16.4", "graphql": "^14.2.1" } } ``` ![image-20220218223006449](README_files/image-20220218223006449.png) # 2.基于apollo-serve开发服务端 ## 1.ES6标签模板 ```js function foo(param) { console.log(param) } foo`
你好
你好
你好
` // 标签模板可以作为函数的参数传递 ``` ## 2.开发步骤 ```js // 1.导入相关依赖包 const express = require('express') const { ApolloServer, gql } = require('apollo-server-express') // 2.定义数据类型 /** * query类型是默认客户端查询的类型 * 该类型在服务端必须存在且唯一 */ const typeDefs = gql` type Query { hello: String } ` // 3.解析数据类型对应的具体数据 const resolvers = { Query: { hello: () => 'Hello World!' } } // 4.整合apollo-server和express /** * typeDefs,resolvers 属性名是固定的 */ const server = new ApolloServer({ typeDefs, resolvers }) const app = express() server.applyMiddleware({ app }) // 5.监听启动 app.listen({ port: 4000 }, () => console.log('running...')) ``` ![image-20220218231136384](README_files/image-20220218231136384.png) ## 3.类型定义 ```js // 1.导入相关依赖包 const express = require('express') const { ApolloServer, gql } = require('apollo-server-express') // 2.定义数据类型 /** * query类型是默认客户端查询的类型 * 该类型在服务端必须存在且唯一 */ const typeDefs = gql` # 课程类型 type Course { cname: String score: Float } #学生类型 type Student { sname: String scores: [Course] } #查询类型 type Query { hello: String stu: Student } ` // 3.解析数据类型对应的具体数据 const resolvers = { Query: { hello: () => 'Hello World!', stu: () => { // 这里提供学生相关的数据 let data = [ { cname: '数学', score: 99 }, { cname: '英语', score: 94 } ] return { sname: '张三', scores: data } } } } // 4.整合apollo-server和express /** * typeDefs,resolvers 属性名是固定的 */ const server = new ApolloServer({ typeDefs, resolvers }) const app = express() server.applyMiddleware({ app }) // 5.监听启动 app.listen({ port: 4000 }, () => console.log('Now browse to http://localhost:4000' + server.graphqlPath)) ``` ![image-20220218233108633](README_files/image-20220218233108633.png) ## 4.基本类型 ```js // 1.导入相关依赖包 const express = require('express') const { ApolloServer, gql } = require('apollo-server-express') // 2.定义数据类型 /** * query类型是默认客户端查询的类型 * 该类型在服务端必须存在且唯一 */ const typeDefs = gql` #学生类型 type Student { sname: String age: Int } #查询类型 type Query { hello: String # 参数可以指定默认值 stu(n: Int = 11): Student } ` // 3.解析数据类型对应的具体数据 const resolvers = { Query: { hello: () => 'Hello World!', stu: (obj, args) => { console.log(args.n) // 这里提供学生相关的数据 return { sname: '张三', age: args.n } } } } // 4.整合apollo-server和express /** * typeDefs,resolvers 属性名是固定的 */ const server = new ApolloServer({ typeDefs, resolvers }) const app = express() server.applyMiddleware({ app }) // 5.监听启动 app.listen({ port: 4000 }, () => console.log('Now browse to http://localhost:4000' + server.graphqlPath)) ``` ![image-20220218232958958](README_files/image-20220218232958958.png) ![image-20220218234014066](README_files/image-20220218234014066.png) ## 5.标量类型 ```js // 1.导入相关依赖包 const express = require('express') const { ApolloServer, gql } = require('apollo-server-express') const { v4: uuidv4 } = require('uuid') // 2.定义数据类型 /** * query类型是默认客户端查询的类型 * 该类型在服务端必须存在且唯一 */ const typeDefs = gql` #学生类型 type Student { id: ID sname: String age: Int gender: Boolean score: Float } #查询类型 type Query { hello: String # 参数可以指定默认值 stu(n: Int = 11): Student } ` // 3.解析数据类型对应的具体数据 const resolvers = { Query: { hello: () => 'Hello World!', stu: (obj, args) => { // 这里提供学生相关的数据 return { sname: '张三', age: 12, gender: true, score: 99.5, id:uuidv4() } } } } // 4.整合apollo-server和express /** * typeDefs,resolvers 属性名是固定的 */ const server = new ApolloServer({ typeDefs, resolvers }) const app = express() server.applyMiddleware({ app }) // 5.监听启动 app.listen({ port: 4000 }, () => console.log('Now browse to http://localhost:4000' + server.graphqlPath)) ``` ![image-20220218234419735](README_files/image-20220218234419735.png) **安装uuid生成随机字符串** `cnpm install uuid -S` ```js const { v4: uuidv4 } = require('uuid') ``` ![image-20220219000131375](README_files/image-20220219000131375.png) ## 6.枚举类型 ```js const express = require('express') const { ApolloServer, gql } = require('apollo-server-express') const typeDefs = gql` #枚举类型 只能拿到定义的三种类型之一 enum Favour { SWIMMING DANCEING CODING } #查询类型 type Query { hello: String info: Favour } ` const resolvers = { Query: { hello: () => 'Hello world!111', info: () => { return 'CODING' } } } const server = new ApolloServer({ typeDefs, resolvers }) const app = express() server.applyMiddleware({ app }) app.listen({ port: 4000 }, () => console.log('Now browse to http://localhost:4000' + server.graphqlPath)) ``` ![image-20220219000314311](README_files/image-20220219000314311.png) ## 7.列表和非空 ```js const typeDefs = gql` #类型后面加!号,返回的时候该数据不能为空 type Student{ sname:String! age:Int } type Query { hello: String stu: Student } ` ``` ![image-20220219001017592](README_files/image-20220219001017592.png) ![image-20220219003345799](README_files/image-20220219003345799.png) ## 8.输入类型 ![image-20220219003439930](README_files/image-20220219003439930.png) ![image-20220219003449857](README_files/image-20220219003449857.png) ```js const express = require('express') const { ApolloServer, gql } = require('apollo-server-express') const typeDefs = gql` #输入类型 input UesrInfo { uname: String pwd: String } #用户类型 type User { id: ID uname: String pwd: String } #变更类型 type Mutation { addUserByInput(userInput: UesrInfo): User } #查询类型 type Query { hello: String } ` const resolvers = { Query: { hello: () => 'Hello world!111' }, Mutation: { addUserByInput: (obj, args) => { return { id: 123, uname: args.userInput.uname, pwd: args.userInput.pwd } } } } const server = new ApolloServer({ typeDefs, resolvers }) const app = express() server.applyMiddleware({ app }) app.listen({ port: 4000 }, () => console.log('Now browse to http://localhost:4000' + server.graphqlPath)) ``` ```js // 查询语法 mutation{ addUserByInput(userInput:{ uname:"李四11", pwd:"12311" }){ id uname pwd } } // 返回值 { "data": { "addUserByInput": { "id": "123", "uname": "李四11", "pwd": "12311" } } } ``` ## 9.数据解析规则详解 ![image-20220219005656673](README_files/image-20220219005656673.png) ![image-20220219005836504](README_files/image-20220219005836504.png) ```js const express = require('express') const { ApolloServer, gql } = require('apollo-server-express') const typeDefs = gql` type Student { sname: String age: Int favour: String } type Query { hello: String stu: Student } ` const resolvers = { Student: { sname: parent => { // 对子节点来说,parent起作用 console.log(parent, '1') return '张三' }, favour: parent => { if (parent.favour === 'swimming') { return '游泳' } else { return parent.favour } } }, Query: { hello: () => 'Hello world!111', stu: parent => { console.log(parent, '2') // 对根节点来说,parent不起作用 return { sname: '李四', age: 12, favour: 'swimming' } } } } const server = new ApolloServer({ typeDefs, resolvers }) const app = express() server.applyMiddleware({ app }) app.listen({ port: 4000 }, () => console.log('Now browse to http://localhost:4000' + server.graphqlPath)) ``` ![image-20220219011700074](README_files/image-20220219011700074.png) ![image-20220219012010277](README_files/image-20220219012010277.png) ![image-20220219012058065](README_files/image-20220219012058065.png) ## 10.context实际应用 ![image-20220219020157451](README_files/image-20220219020157451.png) ```js // index.js const express = require('express') const { ApolloServer, gql } = require('apollo-server-express') const db = require('./db.js') const typeDefs = gql` type Student { sname: String age: Int } type Query { hello: [Student!]! } ` const resolvers = { Query: { hello: async (parent, args, context) => { let res = await context.db.getData() // 这里获取到数据源对象之后就可以非常方便的获取需要的数据,从而返回给客户端 console.log(JSON.parse(res)) return JSON.parse(res) } } } const context = () => { return { db: db } } const server = new ApolloServer({ typeDefs, resolvers, context }) const app = express() server.applyMiddleware({ app }) app.listen({ port: 4000 }, () => console.log('Now browse to http://localhost:4000' + server.graphqlPath)) ``` ```js // db.js // 操作数据源 const path = require('path') const fs = require('fs') module.exports.getData = () => { // 读取文件 let filePath = path.join(__dirname, 'data.json') return new Promise((resolve, reject) => { fs.readFile(filePath, (err, data) => { if (err) { // 读取失败 reject('error') } // 读取成功 resolve(data.toString()) }) }) } ``` ```json [ { "sname":"李四", "age":14 }, { "sname":"张三", "age":18 }, { "sname":"王五", "age":19 }, { "sname":"赵柳", "age":16 } ] ``` # 3.客户端开发 ## 1.基本查询 ![image-20220219020354798](README_files/image-20220219020354798.png) ```js // 1.导入相关依赖包 const express = require('express') const { ApolloServer, gql } = require('apollo-server-express') // 2.定义数据类型 /** * query类型是默认客户端查询的类型 * 该类型在服务端必须存在且唯一 */ const typeDefs = gql` # 课程类型 type Course { cname: String score: Float } #学生类型 type Student { sname: String scores: [Course] } #查询类型 type Query { hello: String stu: Student } ` // 3.解析数据类型对应的具体数据 const resolvers = { Query: { hello: () => 'Hello World!', stu: () => { // 这里提供学生相关的数据 let data = [ { cname: '数学', score: 99 }, { cname: '英语', score: 94 } ] return { sname: '张三', scores: data } } } } // 4.整合apollo-server和express /** * typeDefs,resolvers 属性名是固定的 */ const server = new ApolloServer({ typeDefs, resolvers }) const app = express() server.applyMiddleware({ app }) // 5.监听启动 app.listen({ port: 4000 }, () => console.log('Now browse to http://localhost:4000' + server.graphqlPath)) /** * 客户端查询规则 * { hello stu{ sname scores{ cname score } } } */ ``` ## 2.操作名称 ![image-20220219021110406](README_files/image-20220219021110406.png) ![image-20220219022541323](README_files/image-20220219022541323.png) ```js // 1.导入相关依赖包 const express = require('express') const { ApolloServer, gql } = require('apollo-server-express') // 2.定义数据类型 /** * query类型是默认客户端查询的类型 * 该类型在服务端必须存在且唯一 */ const typeDefs = gql` # 输入类型 input UserInfo { uname: String pwd: String } #用户类型 type User { id: ID uname: String pwd: String } #变更类型 type Mutation { addUser(userInfo: UserInfo): User } #查询类型 type Query { hello: String msg: String } ` // 3.解析数据类型对应的具体数据 const resolvers = { Query: { hello: () => 'Hello World!', msg: () => 'msg' }, Mutation: { addUser: (obj, args) => { return { id: 123, uname: args.userInfo.uname, pwd: args.userInfo.pwd } } } } // 4.整合apollo-server和express /** * typeDefs,resolvers 属性名是固定的 */ const server = new ApolloServer({ typeDefs, resolvers }) const app = express() server.applyMiddleware({ app }) // 5.监听启动 app.listen({ port: 4000 }, () => console.log('Now browse to http://localhost:4000' + server.graphqlPath)) /** * 客户端查询规则 * query info{ hello } query msg{ msg } mutation addUser{ addUser(userInfo:{ uname:"李四" pwd:"abs" }){ uname pwd id } } */ ``` ## 3.查询参数 ```js const express = require('express') const { ApolloServer, gql } = require('apollo-server-express') const typeDefs = gql` #学生类型 type Student { sname: String age: Int gender: Boolean } #查询类型 type Query { hello: String stu(id: Int, sname: String): Student } ` const resolvers = { Query: { hello: () => 'Hello world!111', stu: (parent, args) => { console.log(parent, args) let stu = null if (args.id === 1 && args.sname === '李四') { stu = { sname: 'lisi', age: 12, gender: true } } else { stu = { sname: '---', age: 0, gender: false } } return stu } } } const server = new ApolloServer({ typeDefs, resolvers }) const app = express() server.applyMiddleware({ app }) app.listen({ port: 4000 }, () => console.log('Now browse to http://localhost:4000' + server.graphqlPath)) /** query param{ hello stu(id:2,sname:"李四"){ sname age gender } } */ ``` ![image-20220219022709742](README_files/image-20220219022709742.png) ![image-20220219131655019](README_files/image-20220219131655019.png) ![image-20220219131709822](README_files/image-20220219131709822.png) ## 4.变量 ```js ``` ![image-20220219023022981](README_files/image-20220219023022981.png) ![image-20220219134756007](README_files/image-20220219134756007.png) ![image-20220219134813655](README_files/image-20220219134813655.png) ## 5.指令 ```js // 1.导入相关依赖包 const express = require('express') const { ApolloServer, gql } = require('apollo-server-express') // 2.定义数据类型 /** * query类型是默认客户端查询的类型 * 该类型在服务端必须存在且唯一 */ const typeDefs = gql` #学生类型 type Student { id: ID sname: String gender: Boolean } #查询类型 type Query { hello: String stu(id: Int): Student } ` // 3.解析数据类型对应的具体数据 const resolvers = { Query: { hello: () => 'Hello World!', stu: (parent, args) => { console.log(args) if (args.id === 1) { return { id: 11, sname: '李素', gender: true } } else { return { id: 0, sname: '--', gender: false } } } } } // 4.整合apollo-server和express /** * typeDefs,resolvers 属性名是固定的 */ const server = new ApolloServer({ typeDefs, resolvers }) const app = express() server.applyMiddleware({ app }) // 5.监听启动 app.listen({ port: 4000 }, () => console.log('Now browse to http://localhost:4000' + server.graphqlPath)) /** * query param($id:Int,$gender:Boolean!){ hello stu(id:$id){ id sname gender @skip(if: $gender) } } query param($id:Int,$gender:Boolean!){ hello stu(id:$id){ id sname gender @include(if: $gender) } } { "id": 1, "gender": true } */ ``` ![image-20220219135040029](README_files/image-20220219135040029.png) ![image-20220219140317329](README_files/image-20220219140317329.png) ![image-20220219140435440](README_files/image-20220219140435440.png) ## 6.别名 ```js // 1.导入相关依赖包 const express = require('express') const { ApolloServer, gql } = require('apollo-server-express') // 2.定义数据类型 /** * query类型是默认客户端查询的类型 * 该类型在服务端必须存在且唯一 */ const typeDefs = gql` #课程类型 type Course { cname: String score: Float } #学生类型 type Student { id: Int sname: String age: Int scores(cname: String): [Course] } #查询类型 type Query { hello: String stu: Student } ` // 3.解析数据类型对应的具体数据 const resolvers = { Student: { scores: (parent, args) => { console.log(args.cname) if (args.cname === '数学' || args.cname === '英语') { return parent.scores.filter(item => { return item.cname === args.cname }) } else { return parent.scores } } }, Query: { hello: () => 'Hello World!', stu: (parent, args) => { return { id: 1, sname: '张三', scores: [ { cname: '数学', score: 88 }, { cname: '语文', score: 65 }, { cname: '英语', score: 45 } ] } } } } // 4.整合apollo-server和express /** * typeDefs,resolvers 属性名是固定的 */ const server = new ApolloServer({ typeDefs, resolvers }) const app = express() server.applyMiddleware({ app }) // 5.监听启动 app.listen({ port: 4000 }, () => console.log('Now browse to http://localhost:4000' + server.graphqlPath)) /** query param{ hello stu{ id sname age math:scores(cname:"数学"){ cname score } english:scores(cname:"英语"){ cname score } } } */ ``` ![image-20220219140718610](README_files/image-20220219140718610.png) ![image-20220219142223445](README_files/image-20220219142223445.png) ![image-20220219142344238](README_files/image-20220219142344238.png) ## 7.变更 ```js // 1.导入相关依赖包 const express = require('express') const { ApolloServer, gql } = require('apollo-server-express') // 2.定义数据类型 /** * query类型是默认客户端查询的类型 * 该类型在服务端必须存在且唯一 */ const typeDefs = gql` #输入类型 input UserInfo { uname: String pwd: String } #用户类型 type User { id: ID uname: String pwd: String } #变更类型 type Mutation { addUserByInput(userInput: UserInfo): User addUserByParam(uname: String, pwd: String): User } #查询类型 type Query { hello: String } ` // 3.解析数据类型对应的具体数据 const resolvers = { Query: { hello: () => 'Hello World!' }, Mutation: { addUserByParam: (obj, args) => { return { id: 123, uname: args.uname, pwd: args.pwd } }, addUserByInput: (obj, args) => { return { id: 456, uname: args.userInput.uname, pwd: args.userInput.pwd } } } } // 4.整合apollo-server和express /** * typeDefs,resolvers 属性名是固定的 */ const server = new ApolloServer({ typeDefs, resolvers }) const app = express() server.applyMiddleware({ app }) // 5.监听启动 app.listen({ port: 4000 }, () => console.log('Now browse to http://localhost:4000' + server.graphqlPath)) ``` ![image-20220219145441961](README_files/image-20220219145441961.png) ![image-20220219150117085](README_files/image-20220219150117085.png) # 4.留言板案例 ![image-20220219152520713](README_files/image-20220219152520713.png) ![image-20220219152536011](README_files/image-20220219152536011.png) ![image-20220219152548856](README_files/image-20220219152548856.png) ![image-20220219154957311](README_files/image-20220219154957311.png) ![image-20220219160239340](README_files/image-20220219160239340.png) ![image-20220219161215780](README_files/image-20220219161215780.png) ![image-20220219160105712](README_files/image-20220219160105712.png) ![image-20220219160334313](README_files/image-20220219160334313.png) ![image-20220219160417959](README_files/image-20220219160417959.png) ![image-20220219160806965](README_files/image-20220219160806965.png) ![image-20220219160959147](README_files/image-20220219160959147.png) ![image-20220219160941677](README_files/image-20220219160941677.png) # 11.nodemon ## nodemon nodemon是一种工具,可以自动检测到目录中的文件更改时通过重新启动应用程序来调试基于node.js的应用程序。 ## 安装 ```cpp npm install -g nodemon //或 npm install --save-dev nodemon ``` ## 使用 ```cpp nodemon ./main.js // 启动node服务 ``` ```cpp nodemon ./main.js localhost 6677 // 在本地6677端口启动node服务 ``` ```bash "start": "ts-node -r tsconfig-paths/register nodemon src/main.ts", ``` ## 延迟重启 ```css nodemon -delay10 main.js nodemon --delay 2.5 server.js nodemon --delay 2500ms server.js ``` 这个就类似于js函数中的函数节流,只在最后一次更改的文件往后延迟重启.避免了短时间多次重启的局面. ## 配置文件 nodemon支持本地和全局配置文件。这些通常是命名的nodemon.json,可以位于当前工作目录或主目录中。可以使用该--config 选项指定备用本地配置文件。 ```json { "verbose": true, "ignore": ["*.test.js", "fixtures/*"], "execMap": { "rb": "ruby", "pde": "processing --sketch={{pwd}} --run" } } ``` 作者:大月山 链接:https://www.jianshu.com/p/f60e14db0b4e 来源:简书 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 # 12.时间格式化包 ![image-20220219161323477](README_files/image-20220219161323477.png)