每一个GraphQL服务都会定义一套类型,用来描述你查询的数据。每个查询到来,服务器会根据schema进行验证并执行查询。
Query类型
- 严格来说Query是一种对象类型
- Query是所有查询的入口点
-
标量类型(Scalar Types)
在Graphql中自带了一组标量类型:
Int:有符号32为整数
- Float:有符号双精度浮点值
- String:UTF-8字符序列
- Boolean:True或False
- ID:表示一个唯一标识符,通常用以重新获取对象或作为缓存中的键。使用String一样的方式进行序列化
数组类型
使用[]来表示列表,如: ```javascript type Job { title: String salary: Float }
type user { name: String age: Int hobbies: [String] jobs: [Job] }
其中hobbies是String列表,jobs是Job类型的列表。注意查询jobs必须指定Job的字段,如:```javascript{user {namehobbiesjobs {titlesalary}}}
对象类型(Object Types)
我们可以在Graphql定义类型:
type Character {name: String!appearsIn: [Episode!]!}
Character 就是一个GraphQL对象类型,其中 name 和appearsIn是Character类型上的字段。并且name字段是String非空的,appearsIn是一个非空的Episode数组,并且数组Episode元素不为空。
⚠️对象查询时,必须指定查询的字段(不能只写变量名直接查询),如:
{character {nameappearsIn}}
非空类型
默认情况下,每种类型都可以为空。如果指定类型不能为空,可以加 ! 。如 String! 表示非空字符串。
查询参数
在GraphQL中,Schema类型查询支持指定参数,如下:
// 定义数据 文章列表const articles = [{id:1, title: 'Java编程思想', publish:'2001-10-01'},{id:2, title: 'React编程指南', publish:'2003-05-01'},{id:3, title: 'GraphQL使用教程', publish:'2010-10-01'}]// 定义schemaconst schema = buildSchema(`type Article {id: ID!title: String!publish: String!}type Query {articles: [Article]article(id: ID!): Article}`)// 定义 resolverconst rootValue = {// 无参函数articles() {return articles}// 有参函数article({id}) {return articles.find(article => article.id === id)}}
修改 & 输入类型
GraphQL支持定义输入类型,对数据进行修改,如下:
// 定义schema (修改)// 修改类型 关键字为 type Mutationconst schema = buildSchema(`type Mutation {deleteArticle(id: ID!): Article}`)// 定义 resolverconst rootValue = {deleteArticle({id}) {const article = articles.find(article => article.id === id)const i = articles.indexOf(article)if (-1 === i) {console.log("删除文章不存在");return null;}console.log("删除文章:" + i);articles.splice(i, 1)return article}}
客户端查询如下:
mutation {deleteArticle(id: "1") {idtitle}}
需要显示指定mutation执行。 {}等价于 query {} 操作还可以定义名称: mutation delete { deleteArticle(id: “1”) { id title } }
对于参数列表很多时,我们可以定义 input 输入对象,如下:
// 定义schema (修改)// 修改类型 关键字为 type Mutationconst schema = buildSchema(`input ArticleInput {title:String!publish:String!}type Mutation {addArticle(article:ArticleInput):[Article]}`)// 定义 resolverconst rootValue = {addArticle({article}) {article.id = uuidv4()articles.push(article)return articles}}
客户端查询如下:
mutation add {addArticle(article: {title:"SQL教程", publish:"2021-01-01"}) {idtitle}}
完整脚本如下:
const {buildSchema} = require('graphql')const express = require('express')const { graphqlHTTP } = require('express-graphql')const cors = require('cors')const {v4: uuidv4} = require('uuid')const app = express()// 允许客户端进行跨域请求app.use(cors())// 定义数据 文章列表const articles = [{id:'1', title: 'Java编程思想', publish:'2001-10-01'},{id:'2', title: 'React编程指南', publish:'2003-05-01'},{id:'3', title: 'GraphQL使用教程', publish:'2010-10-01'}]// 定义schemaconst schema = buildSchema(`type Article {id: ID!title: String!publish: String!}type Query {articles: [Article]article(id:ID!):Article}input ArticleInput {title:String!publish:String!}type Mutation {deleteArticle(id: ID!):ArticleaddArticle(article:ArticleInput):[Article]}`)// 定义 resolverconst rootValue = {articles() {return articles},article({ id }) {console.log(id);return articles.find(article => article.id === id)},deleteArticle({id}) {const article = articles.find(article => article.id === id)const i = articles.indexOf(article)if (-1 === i) {console.log("删除文章不存在");return null;}console.log("删除文章:" + i);articles.splice(i, 1)return article},addArticle({article}) {article.id = uuidv4()articles.push(article)return articles}}app.use('/graphql', graphqlHTTP({schema,rootValue,graphiql: true // 开启浏览器 Graphql IDE 调试工具}))app.listen(4000, () => {console.log('Graphql Server is running at http://localhost:4000/graphql')})
客户端查询:
通过 variables 传递参数进行 query 查询
axios({method; 'POST',url: 'http://localhost:4000/graphql',data: {query: `query getArticle($id: ID!) {article(id: $id) {idtitlepublish}}`,variables: {id : 2}}}).then(res => {console.log(res.data)})
