GraphQL.js的schema,如何用js定义取代文本?如何接收返回数据?
发布于 作者:苏南大叔 来源:程序如此灵动~在GraphQL.js
中,定义schema
结构是非常重要的工作内容。在前几个例子中,苏南大叔都是采用默认的文本的形式定义这个schema
的。其实,这个schema
和root
的定义,还可以合并到一起,用传统的js
的形式来定义。具体是如何使用js
对schema
和root
进行定义的呢?请参考本文的内容。
大家好,这里是苏南大叔的“程序如此灵动”博客,这里记录苏南大叔和计算机代码的故事。本文介绍在nodejs
和graphql
代码结合的时候,定义schema
的有一种新的方式。本文测试环境:node@16.14.0
,graphql@16.3.0
。
如何发送和返回数据
GraphQL
大概的流程就是:schema
(编写人员定义结构)=>query
(调用人员传递参数)=>root
/resolve
(编写人员接收和返回匹配结果)。
要查询(发送)的数据来自query
:
对于查询的内容,大概就是这样:
执行的查询名称 ( 查询的字段名1:字段值1 , 查询的字段名2:字段值2 ) {
返回的数据字段1
返回的数据字段2
}
而root
/resolve
来负责接收处理数据:
root
的话,通过args
来接收参数。resolve
的话,也是通过args
来接收参数。但是,args
是第二个参数。
数据发送返回实例
graphql
程序的正确运行,需要定义两个部分:
- 一部分是数据定义。
schema
,提供数据结构参考。由接口开发人员定义,由接口调用人员使用。 - 另外一部分是数据处理。
root
/resolve
,提供数据。由接口开发人员实现具体逻辑。
本文范例的查询语句是:
{
hello
hi(name:"sunan")
hola(name:"simon",id:8)
bonjour(name:"sunan",id:5) {
name
title
}
}
查询结果是:
{
"data": {
"hello": "Hello world!",
"hi": "hi sunan!",
"hola": "?Hola simon8!",
"bonjour": {
"name": "sunan",
"title": "manager"
}
}
}
文本定义方案:SDL
实体描述
下面是使用文本方式进行定义的schema
例子:
type Query {
hello: String,
hi(name:String):String,
hola(name:String,id:Int):String,
bonjour(name:String,id:Int):human,
}
type human{
name:String,
title:String
plus:String
}
这里的结构定义方法,GraphQL
的官方说明如下:
下面是对应的root
的例子:
{
hello: () => 'Hello world!',
hi: (args) => 'hi ' + args.name + '!',
hola: (args) => '?Hola ' + args.name + '' + args.id + '!',
bonjour: (args) => {
return { 'name':args.name,'id':args.id,'title':'manager','plus':'wonderful' }
}
}
下面的文章中,是这种定义方式的例子。例如:
- https://newsn.net/say/graphql-node.html
- https://newsn.net/say/graphql-express.html
- https://newsn.net/say/graphql-koa.html
- https://newsn.net/say/graphql-import-schema.html
代码定义方案:使用js
代码定义
个人觉文本形式定义不是很好,可能还会多一个遍历匹配解析的过程。这种直接使用后端相关语言直接定义的方式更好。
本方案中,需先导入GraphQL
的各种常见数据类型。然后定义schema
(字段的类型定义及root
逻辑)。
也就是说,在本方案中,数据结构和数据处理,是合二为一的,并且root
部分被描述为resolve
。
范例代码:
const {
GraphQLSchema,
GraphQLObjectType,
GraphQLString,
GraphQLInt,
versionInfo
} = require('graphql');
const RootQueryType = new GraphQLObjectType({
name: 'Query',
description: 'Root Query',
fields: () => ({
hello: {
type: GraphQLString,
resolve() {
return 'hello world';
},
},
hi: {
type: GraphQLString,
description: 'hi query',
args: {
name: { type: GraphQLString }
},
resolve: (parent, args) => {
return 'hi,' + args.name
}
},
hola: {
type: GraphQLString,
description: 'hola query',
args: {
name: { type: GraphQLString },
id: { type: GraphQLInt }
},
resolve: (parent, args) => {
return '?Hola ' + args.name + '' + args.id + '!'
}
},
bonjour: {
type: human,
description: 'human bonjour',
args: {
id: { type: GraphQLInt },
name: { type: GraphQLString }
},
resolve: (parent, args) => {
return { id: args.id, name: args.name, title: "manager", plus:"plus" };
}
}
})
});
const human = new GraphQLObjectType({
name: 'human',
description: 'human',
fields: () => ({
id: { type: GraphQLInt },
name: { type: GraphQLString },
title: { type: GraphQLString },
plus: { type: GraphQLString },
})
})
const schema = new GraphQLSchema({
query: RootQueryType
})
代码说明:
- 文本方式中的
root
定义里面,参数直接就是args
。 - 代码方式定义里面的
resolve
定义里面,参数是parent,args
。 - 传入
graphqlHTTP
的就只有一个schema
,没有root
。
测试环境:koa@2.13.4
,koa-graphql@0.12.0
,koa-mount@4.0
。完整代码:
相关文章:
在这里,
schema
的类型定义,都被使用GraphQL
字样进行了包装。比如:String
变成了GraphQLString
。root
定义被打散编程了schema
的resolve()
部分了。
相关文献
- https://newsn.net/say/graphql.html
- https://newsn.net/say/graphql-node.html
- https://newsn.net/say/graphql-import-schema-node.html
总结
苏南大叔目前不会详细阐述GraphQL
的SDL
语言的逻辑,如果您熟悉一种后端语言的话,这些schema
定义是非常简单的。为了苏南大叔的文章逻辑内容进化方向,GraphQL
的内容可能还有几篇内容就要暂结了。
文本定义的方式,比较简单明了。代码定义的方式,比较复杂强大。总结:费脑细胞。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。