API,AJAX,REST,后端分离,前端三大框架,在单页应用成为主流的今天,基本上无人不知。相比起传统的MVC架构,带来的好处也是显而易见的。实现简单,方便灵活,对用户非常友好。
Restful
大量使用AJAX进行异步数据请求是现在单页应用获取数据的主要方法,对此也有一套专门的方案(Restful)虽然基本上满足大部分操作,但还是有很多不足的地方。
在这样的风格下,每个版本,每个对象都有特定的url,往往一个项目中会有成堆的url。对于前端开发人员来说,很多时候要求返回特定格式的数据。为了节约网络资源,加快访问速度,有时候需要要求返回指定的字段。等等等等。。
这些功能当然都可以实现,因为在restful风格下,查询(query)操作使用get的方式进行请求,与服务器的交互仅通过url携带参数,多少都很别扭。如果能把这样的操作都进行函数化,那就再好不过了。
Graphql很好的规避了这些问题,一个url,全部的操作都以函数为中心,使用起来非常方便灵活。
GraphQL
本文将以Github的API为例,说明Graphql的基本使用方法,更全面的使用教程请参阅GraphQL。
GraphiQL
GraphQL自带了强大的自省功能,类似于传统restful API的自动化文档。引入GraphiQL即可在页面中直接进行各种操作,在右侧的边栏中可以查看当前可进行的各种操作以及具体的返回数据。打开github提供的资源管理器,开始愉快的进行吧!
Query
通俗的讲,在Graphql中只有两类操作,一种是只读型的query,另外一种是对服务器资源造成修改的mutation。
登录后在explorer中输入
query {
viewer {
login
}
}
得到返回数据
{
"data": {
"viewer": {
"login": "myWsq"
}
}
}
一次愉快的查询就这样完成了。当然可以指定要查询的字段,打开explorer的右侧Doc边栏,在query中找到viewer对象:
viewer: User!
这意味着viewer必须返回一个user实例,同样的,打开user的定义,看到很多字段。我们在查询语句中加入其它字段:
query {
viewer {
login
name
bio
}
}
得到返回数据
{
"data": {
"viewer": {
"login": "myWsq",
"name": "WangSQ",
"bio": "洋码子工作者"
}
}
}
带参数的查询
query {
user(login: "myWsq") {
name
}
}
{
"data": {
"user": {
"name": "WangSQ"
}
}
}
嵌套查询
query {
user(login: "myWsq") {
name
repositories(last:1) {
edges {
node {
name
}
}
}
}
}
{
"data": {
"user": {
"name": "WangSQ",
"repositories": {
"edges": [
{
"node": {
"name": "blog.mywsq.cn"
}
}
]
}
}
}
}
多个对象同时查询
query {
user(login: "myWsq") {
name
}
viewer{
login
}
}
{
"data": {
"user": {
"name": "WangSQ"
},
"viewer": {
"login": "myWsq"
}
}
}
mutation
github提供的explorer不支持mutation,可以在自己的GraphiQL实例中使用,但是我们能从Doc中看出,mutation的使用与query非常相似。
Input
找到一个mutation操作
addStar(input: AddStarInput!): AddStarPayload
可以将addStar
看做一个对象,实际上,在GraphQL服务端编程时,它确实是一个对象。加上参数便成为了函数。带有input后缀的是服务端定义的输入对象,使用起来与普通对象并无差别。只是服务器在处理时为了处理数据,方便区分。
可以看出,GraphQL的风格比较符合一般的函数式语言的规范,上手非常迅速。使用query操作时,并非必须携带query前缀
{
user(login: "myWsq") {
name
}
viewer{
login
}
}
但进行mutation操作时必须注明
mutation {
addStar(input:{
starrableId:"xxx"
clientMutationId:"xxx"
}) {
clientMutationId
}
}