每一个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 {
name
hobbies
jobs {
title
salary
}
}
}
对象类型(Object Types)
我们可以在Graphql定义类型:
type Character {
name: String!
appearsIn: [Episode!]!
}
Character
就是一个GraphQL
对象类型,其中 name
和appearsIn
是Character
类型上的字段。并且name
字段是String
非空的,appearsIn
是一个非空的Episode
数组,并且数组Episode
元素不为空。
⚠️对象查询时,必须指定查询的字段(不能只写变量名直接查询),如:
{
character {
name
appearsIn
}
}
非空类型
默认情况下,每种类型都可以为空。如果指定类型不能为空,可以加 !
。如 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'}
]
// 定义schema
const schema = buildSchema(`
type Article {
id: ID!
title: String!
publish: String!
}
type Query {
articles: [Article]
article(id: ID!): Article
}
`)
// 定义 resolver
const rootValue = {
// 无参函数
articles() {
return articles
}
// 有参函数
article({id}) {
return articles.find(article => article.id === id)
}
}
修改 & 输入类型
GraphQL支持定义输入类型,对数据进行修改,如下:
// 定义schema (修改)
// 修改类型 关键字为 type Mutation
const schema = buildSchema(`
type Mutation {
deleteArticle(id: ID!): Article
}
`)
// 定义 resolver
const 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") {
id
title
}
}
需要显示指定mutation执行。 {}等价于 query {} 操作还可以定义名称: mutation delete { deleteArticle(id: “1”) { id title } }
对于参数列表很多时,我们可以定义 input
输入对象,如下:
// 定义schema (修改)
// 修改类型 关键字为 type Mutation
const schema = buildSchema(`
input ArticleInput {
title:String!
publish:String!
}
type Mutation {
addArticle(article:ArticleInput):[Article]
}
`)
// 定义 resolver
const rootValue = {
addArticle({article}) {
article.id = uuidv4()
articles.push(article)
return articles
}
}
客户端查询如下:
mutation add {
addArticle(article: {title:"SQL教程", publish:"2021-01-01"}) {
id
title
}
}
完整脚本如下:
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'}
]
// 定义schema
const 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!):Article
addArticle(article:ArticleInput):[Article]
}
`)
// 定义 resolver
const 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) {
id
title
publish
}
}
`,
variables: {
id : 2
}
}
}).then(res => {
console.log(res.data)
})