graphql 有必要吗
![](https://i-blog.csdnimg.cn/blog_migrate/7d011f5651dcef791d9ea2e879528d20.png)
首先,相对于REST服务的优势
想像一下您有一个可管理人员列表的Web应用程序。 他们每个人都有几个朋友。 这将成为一个“图形”,它是具有方向性或非方向性关系的项目的CS数据结构术语。
如果这是针对REST API设计的,那么我可能不得不编写很多类似的代码,例如get-by-id和get-people-friends-by-id和get-people-Friends-details-by-id
如果要获取所有数据,则必须进行3次调用以获取所有上述信息,或者在服务器端组合所有这3件事并返回所有内容,无论用户要求什么。 这就是所谓的过度获取和不足获取
GraphQL解决方案看起来更加优雅。
对于这种情况,我们只需要不带任何详细信息的人员基本信息
query { People(id: 123){ name age } }
对于情况,我们需要更多信息
query { People(id: 123){ name age friendsCount friends{ name age } } }
更好的是,我们可以深入探讨朋友关系圈漏洞
query { People(id: 123){ name age friendsCount friends{ name age friends{ name age } } } }
GraphQL基本构建块:类型,查询,突变和订阅
类型就像人类语言中的宾语或名词一样。 在上面的示例中,“ People”只是一种类型,它应如下所示:(!表示必填)
type People { id: ID! name: String! age: Int friendsCount: Int friends: [People] }
要描述列表,请像使用javascript一样使用[]语法。 这里有更多细节
![](https://i-blog.csdnimg.cn/blog_migrate/e5cc51bf99d2cd1d0aad664d27dc3a3b.png)
上面的段落中显示了查询示例,就像使用描述方式的一种查询语言一样。
突变是根据类型更新/更改/删除/添加数据
mutation { addPeople(name: "John Doe" age:21) { id age name } }
订阅就像消息传递系统中的发布/ 订阅方式。 在大多数流行的GraphQL服务器实现中,它们是使用WebSocket和一些支持pub / sub的解决方案(例如Redis等)实现的
我们可以使用GraphQL Subscriptions构建一个聊天应用程序,而无需使用Websockets非常巧妙地在后台实现它。
以下要点很容易忽略,但非常重要
- 类型,查询,变异和订阅是在模式中定义的,就像数据库的创建模式脚本一样。
它们都以单词` Type`开头
type Subscription { messageAdded(channelId: ID!): Message } type query{ allPeople: [People] } type mutation{ addPeople(name:String! age:Int): People }
2.在您的应用程序客户端或GraphiQL或GraphQL Playground之类的客户端工具中,使用查询,变异和订阅之类的命令。
简而言之,请使用类型查询类型突变定义它们,并先进行类型订阅,然后再在客户端中使用它们
不要像以前一样被它们的客户端用法语法和架构定义语法所迷惑:)
subscription { messageAdded(channelId: 1) { id text } }
3.查询,变异和订阅都可以带有参数。
看起来像这样
query getPhotos($filter:PhotoFilter $page:DataPage $sort:DataSort) { allPhotos(filter:$filter paging:$page sorting:$sort){ ... } }
![](https://i-blog.csdnimg.cn/blog_migrate/0c1219ae3f64e50d8dcb2a437086c91e.png)
当我开始时,虽然我的那些addPeople(name:String age:Int)都是参数,但为什么我们需要这些$ xxx的东西。
难道不像一个男人穿着双袜子吗?
实际上,那些$ ..之类的东西(如上面的getPhotos命令)是用于Client的 ,而allPhotos则是用于Server的 。
这确实有助于我理解语法,并希望它也对您有意义。
allPhotos(…)将被发送到服务器,以便它可以解决答案并发送回结果。
在客户端(应用客户端代码或GraphiQL工具)上,您可以像下面这样提供参数(输入变量)
请注意,您可以在工具的左下角为上面的mutation语句中的$ input变量提供变量。
该用户输入! 是Input Type ,只是用于输入变量定义的另一种类型
![](https://i-blog.csdnimg.cn/blog_migrate/130bcd19c08ab7cc26846fcd64c785a5.png)
4.上面列出的所有参数和类型元素(例如ID,用户名,电子邮件,电话)均以空格或换行符分隔,但不以逗号分隔。
请注意下面的查询/变异语句,它是空格,而不是逗号
allPhotos(filter:$filter paging:$page sorting:$sort)
这很容易忽略,尤其是上面显示的变量部分使用逗号分隔各个变量
5.在上面列出ID,用户名,电子邮件,电话等类型的所有条目可能很繁琐,尤其是如果您必须一次又一次地指定它们的时候。 所以有一个方便的东西叫做片段
fragment userDetails on User { id username email phone ... ... }
然后,只要我们需要获取用户,就可以使用该片段
getUser(id: 123){ ...userDetails }
就像Javascript ES6…运算符
6.其他有趣的类型。
联合类型只是不同类型的组合
如果我们有两种类型,例如StudyGroup和Workout,我们可以将它们合并
union AgendaItem = StudyGroup | Workout
然后,当我们查询这种新类型时,我们可以使用特殊语法来动态获取相关属性。
query schedule { agenda { …on Workout { name reps } …on StudyGroup { name subject students } } }
接口 。 这就像片段,但片段用于查询和更改 ,接口用于类型 定义 。 它只需要来自不同类型的公共字段,以便所有这些类型可以共享公共属性
interface AgendaItem { name: String! start: DateTime! end: DateTime! }
interface AgendaItem { name: String! start: DateTime! end: DateTime! }
type StudyGroup implements AgendaItem { name: String! start: DateTime! end: DateTime! participants: [User!]! topic: String! }
type StudyGroup implements AgendaItem { name: String! start: DateTime! end: DateTime! participants: [User!]! topic: String! }
type StudyGroup implements AgendaItem { name: String! start: DateTime! end: DateTime! participants: [User!]! topic: String! }
type Workout implements AgendaItem { name: String! start: DateTime! end: DateTime! reps: Int! }
type Workout implements AgendaItem { name: String! start: DateTime! end: DateTime! reps: Int! }
GraphQL有很多术语和概念,因此这里提供了我的快速参考,希望当我开始时能了解它们。
为了使GraphQL服务器正常工作,我们需要提供Schema和Resolvers
模式只是我们上面讨论的所有类型,查询,变异和订阅。 高级类型如Enum , Scalar , List,Union,Fragment和Interface
解析程序是实现功能,可为查询和变异检索数据
对于客户端,请使用查询,变异和订阅
对于服务器端模式定义,请使用类型查询类型突变和类型订阅
这些还可以将变量作为输入,因此您可以将变量分组在一起以创建InputType ,它只是变量集合定义
请参考上面的GraphiQL屏幕截图,即UserInput! 是自定义输入类型
以下是使用App客户端代码执行类似GraphiQL示例的类似突变调用的示例
请注意,就像上面的GraphiQL示例一样,突变语句和变量是分开发送的。
import { request } from 'graphql-request'
var url = ' http://localhost:4000/graphql'
var mutation = ` mutation populate($count: Int!) { addFakeUsers(count:$count) { id name } } `
var variables = { count: 3 }
request(url, mutation, variables) .then(console.log) .catch(console.error)
我花了相当多的时间来克服这些术语,并了解服务器定义和客户端请求语法之间的细微差别。
希望所有这些对您有所帮助,并随着时间的推移使用它来刷新基础知识。 欢呼和鼓掌:)
graphql 有必要吗