https://graphql.org/
https://graphql.org/code/#go
https://github.com/graphql-go/graphql
https://github.com/graphql-go/graphql/blob/master/examples/concurrent-resolvers/main.go
https://www.graphql-tools.com/docs/generate-schema/
https://github.com/ardatan/graphql-tools
https://www.graphql-tools.com/docs/generate-schema/
https://github.com/bhoriuchi/graphql-go-tools
https://walmartlabs.github.io/json-to-simple-graphql-schema/
https://graphqleditor.com/
https://github.com/vektah/dataloaden
graphql的方案完美的解决了以上所有问题,连大名鼎鼎GitHub也抛弃了自己非常优秀的REST API接口,全面拥抱graphql了。
GraphQL是Facebook 在2012年开发的,2015年开源,2016年下半年Facebook宣布可以在生产环境使用,而其内部早就已经广泛应用了,用于替代 REST API。facebook的解决方案和简单:用一个“聪明”的节点来进行复杂的查询,将数据按照客户端的要求传回去,后端根据GraphQL机制提供一个具有强大功能的接口,用以满足前端数据的个性化需求,既保证了多样性,又控制了接口数量。
GraphQL并不是一门程序语言或者框架,它是描述你的请求数据的一种规范,是协议而非存储,GraphQL本身并不直接提供后端存储的能力,它不绑定任何的数据库或者存储引擎,它可以利用已有的代码和技术来进行数据源管理。
一个GraphQL查询是一个被发往服务端的字符串,该查询在服务端被解释和执行后返回JSON数据给客户端。
和Rest Api的对比
RESTful:服务端决定有哪些数据获取方式,客户端只能挑选使用,如果数据过于冗余也只能默默接收再对数据进行处理;而数据不能满足需求则需要请求更多的接口。
GraphQL:给客户端自主选择数据内容的能力,客户端完全自主决定获取信息的内容,服务端负责精确的返回目标数据。
优点
能为老板节省几个亿的流量(由前端定义需要哪些字段
再也不需要对接口的文档进行维护了(自动生成文档,代码里定义的结构就是文档
再也不用加班了(真正做到一个接口适用多个场景
再也不用改bug了(强类型,自动校验入参出参类型
新人再也不用培训了(所有的接口都在一颗数下,一目了然
再也不用前端去写假数据了(代码里定义好结构之后自动生成mock接口
再不用痛苦的联调了(代码里定义好结构之后,自动生成接口在线调试工具,直接在界面里写请求语句来调试返回,而且调试的时候各种自动补全
react/vue/express/koa无缝接入(relay方案/apollo方案
更容易写底层的工具去监控每个接口的请求统计信息(都在同一个端点的请求下
不限语言,除了官方提供的js实现,其他所有的语言都有社区的实现
生态是真的好啊,有各种方便易用的开发者工具
https://xiaomingplus.com/full-stack/graphql-intro/
https://developer.github.com/v4/explorer/
https://www.ibm.com/developerworks/cn/web/wa-using-graphgl-to-customize-data-structure/index.html
与传统的客户端/服务器通信模式相比,GraphQL 的引入为整个系统增加了一个中间层,屏蔽了前后端的具体数据结构。其主要优势包括以下几点:
定制所需的数据:客户端可以定制自己想要的数据结构。通过在请求中声明所需的数据结构,从 GraphQL Service 中获取想要的数据。Service 返回的数据结构将与客户端的请求完全一致,从而减少冗余数据的传输。在不使用 GraphQL 的情况下,返回的数据格式不受客户端控制。
单个请求获取多个资源:在 GraphQL 中,客户端不再关心请求的来源,而是直接将需要的资源写入请求字段。在不使用 GraphQL 的情况下,当需要从不同的 Service 取得数据时,客户端开发者需要对不同的 Service 发起请求。
结构即文档:GraphQL 具有友好的调试界面,开发者可直接在该界面中查询 GraphQL 提供的服务。这种数据结构即文档的显示方式,使开发者能够方便快捷地查找所需要的数据类型。
订阅功能:GraphQL 提供订阅功能,使得客户端能够监听数据变化,让 GraphQL Service 能够主动将变动的数据推送至客户端,实时在界面上进行显示。
GraphQL 语法简介
GraphQL 拥有一套自己的语法规则,对用户所使用的具体开发语言并不做限制。
GraphQL 的基本类型
GraphQL 中预定义了以下几类基本类型:
Int: 有符号的 32 位整数,如 1, -3 等。
Float: 有符号的双精度浮点值,如 1.234 等。
String: 字符串,如 hello world等。
Boolean: true/false。
ID: 一个唯一标识符,如对象中的 key 等。其序列化方式与 String 相同,但定义为 ID 时通常表示该类型不需要具备可读性,如一串哈希值等。
https://juejin.im/post/5ceb1e28f265da1bb80c0b70
https://juejin.im/post/5b9b650df265da0afe62cf4e
https://github.com/APIs-guru/graphql-voyager
https://apis.guru/graphql-voyager/
https://javascript.ctolib.com/graphql-voyager.html
https://github.com/NathanRSmith/graphql-visualizer
https://github.com/sheerun/graphqlviz
https://github.com/NathanRSmith/graphql-visualizer
标量(ScalarTypeDefinition)是 GraphQL 中不可分割的原子数据类型,在服务中充当叶子节点。对于客户端而言,合法的查询集(Select Set)必须到达叶子节点,也就是到达标量类型节点。
GraphQL 规范提供了五种标量:
Int: 32 位有符号整型,超出精度范围后,引擎会抛出异常
Float: 有符号双精度浮点数,超出精度范围后,引擎会抛出异常
String: 字符串,用于表示 UTF-8 字符序列
Boolean: bool 值
ID: 资源唯一标志符
表现上 ID 类型只是一个字符串格式的值,引擎支持字符串解析值,也支持将 Int 解析值转换为字符串类型;
语义上”ID” 类型应该用于唯一标志一个资源对象,也就是说,使用相同 ID 值,无论查询多少次,结果都应该是同一对象,这一点有助于实现缓存,是 GraphQL 推荐的缓存方案;
引擎并不限制解析值的唯一性,查询结果包含多个 ID 值相同的节点是合法的。
我们来看一下例子加深印象:
[
// 字符串类型
{id: ‘1’},
// int 类型,引擎会将其转换为字符串
{id: 1},
// float 类型
// 非法值,引擎不支持float转换
// 将抛出 TypeError
错误
{id: 1.2},
// 与上面第一条重复
// 合法值,引擎并不强制 ID
值的唯一性
{id: ‘1’}
]
复制代码
scalar Datetime
复制代码
注意,这只是语义范畴定义,还需要定义序列化、反序列化函数:
new GraphQLScalarType({
name: “Datetime”,
description: “日期时间标量类型”,
// 序列化函数
serialize(value) {
return value.toString();
},
// 解析函数
parseValue(value) {
if (typeof value === “string”) {
return new Date(value);
}
throw new Error(“参数类型错误”);
},
// 解析函数
parseLiteral(ast) {
if (ast.kind === Kind.STRING) {
return new Date(ast.value);
}
throw new Error(“参数类型错误”);
}
});
复制代码
下面我们一个一个看这些配置:
name: 字段名,请保持与 schema 中定的标量类型名称保持一致
description: 类型描述,在一些诊断工具上还是很有用的
serialize: 序列化函数,用于将结果转换为适合 http 传输的数值类型
parseValue: 解析函数,用于将客户端通过 variables 参数传递的数值为 Date 类型
parseLiteral: 同样是解析函数,将客户端传递的 字面量参数 解析为 Date 类型
配置中的 parseValue、parseLiteral 两个函数功能上相似,都用于解析客户端参数,分别处理两种参数传递方式:
query (before: Datetime){
users(before: $before) {
id
name
}
}
variables {
before: “1991-02-19”
}
query {
users(before: “1991-02-19”) {
id
name
}
}
复制代码
最后说一些注意的点:
如果类型确定不会作为 InputType,可以省略 parseValue、parseLiteral。
parseValue 接收到的是 variables 对象中对应的值;而 parseLiteral 接收的则是引擎从 query 语句中解析出的 AST 节点。AST 节点内容形如:
{
// 字面量类型
“kind”: “StringValue”,
// 字面量值
“value”: “1991-02-19”,
// 指明字面量是否为 BlockStringValue 类型
“block”: false,
// token 位置
“loc”:
{
“start”: 18,
“end”: 30
}
}
复制代码
// Address 对象类型,不过这是一个标量
new GraphQLScalarType({
name: “Address”,
description: “对象类型的标量”,
serialize(value) {
// value 为对象类型
// value = { city: ‘深圳’, province: ‘广东省’, country: ‘中国’ }
return value;
}
});
复制代码
但是要注意,标量类型是 不可分割 的,不能再传入查询子集:
query {
users {
id
name
# Address 类型值
bornOrigin
}
}
复制代码
返回结果:
{
“data”: {
“users”: [
{
“id”: “1”,
“name”: “foo”,
“bornOrigin”: {
“city”: “深圳”,
“province”: “广东省”,
“country”: “中国”
}
}
]
}
}
复制代码
完整代码在 此处。 虽然合乎规则,但用 标量类型 来返回一个无法被拆解的对象,违反了 按需加载 这一重要原则,并不值得推崇,除非实在找不到更好的解决方案。 比如,有时候我们需要处理高度动态的信息结构,我们期望以结构化、可预期的形式传输信息,此时我们就不得不采用这种方案了。 以日志为例,一个稍上规模的系统,日志格式多种多样,如果要一一枚举,一一转化成 GraphQL 的 SDL,开发、维护成本都非常高,那用一个标量类型表示这多种多样的格式,性价比就很高了。
总结
标量是 GraphQL 中的原子类型,一般充当查询的叶子节点。 GraphQL 规范提供了五种标量类型,其中 ID 最为特殊,用于唯一标志一个资源实例。 在标准标量之外,也可以按需定义新的标量,规则如上。
https://blog.csdn.net/weixin_33795833/article/details/88004334
https://graphql.cn/learn/queries/#arguments
https://github.com/machinebox/graphql
https://graphql.cn/learn/
https://graphql.org/learn/
https://juejin.im/post/5ac1b03bf265da237b223e82
https://segmentfault.com/a/1190000013961872
https://linux.cn/article-8524-1.html
https://github.com/topliceanu/graphql-go-example
Go语言的GraphQL实践总结
什么是GraphQL
GraphQL官网给出定义:GraphQL既是一种用于API的查询语言 也是一个满足你数据查询的运行时 。GraphQL对你的API中的数据提供了一套易于理解的完整描述 ,使得客户端能够准确地获得它需要的数据 ,而且没有任何冗余,也让API更容易地随着时间推移而演进,还能用于构建强大的开发者工具。
API不是用来调用的吗?是的,者正是GraphQL的强大之处,引用官方文档的一句话ask exactly what you want
本质上来说GraphQL是一种查询语言
上述的定义其实很难理解,只有真的使用过GraphQL才能够理解。
在GraphQL中,通过定义一张Schema和声明一些Type来达到上述描述的功能,需要学习:
对于数据模型的抽象是通过Type来描述的 ,如何定义Type?
对于接口获取数据的逻辑是通过schema来描述的 ,如何定义schema?
https://blog.csdn.net/phantom_111/article/details/79932759
https://blog.csdn.net/weixin_33795833/article/details/88004334
https://www.infoq.cn/article/8CTAakhd*EsUtwqIcGNl
https://graphql.cn/
https://graphql.org/users/
https://graphql.org/swapi-graphql
https://www.electronjs.org/apps/graphiql
https://graphql.cn/learn/