前端应该知道的GraphQL

本文主要结合GitHub GraphQL API,从前端使用者的角度来谈GraphQL,没有GraphQL项目的同窗能够拿GitHub GraphQL API练手,具体代码可参见个人GitHub Blog,欢迎star、fork。javascript

为何须要GraphQL?

以个人博客为例,目前列表页,每篇文章须要的数据结构以下:前端

{
    "title": "前端应该知道的GraphQL",
    "updatedAt": "2018-04-22T03:46:34Z",
    "bodyText": "本文主要结合...",
}

而文章详情页的数据结构为:java

{
    "title": "前端应该知道的GraphQL",
    "updatedAt": "2018-04-22T03:46:34Z",
    "bodyHTML": "<p>本文主要结合...",
}

又想记录下文章的浏览量,往后成为大V,再展现出来 hhh~node

{
    "title": "前端应该知道的GraphQL",
    "updatedAt": "2018-04-22T03:46:34Z",
    "bodyHTML": "<p>本文主要结合...",
    "view": "29898",
}

那么问题来了:两个页面的数据结构title和updateAt的数据是重复的,而body是不一样的,而且还有一个但愿如今就设计好之后须要的时候再用到的view字段。若是为了方便,只写一个接口,同时返回bodyText和bodyHTML,那总有数据是多余的,这样也不合理。但若是分两个接口,又显的有点麻烦和浪费。git

这还只是一个简单的例子,平时开发过程当中,需求变化特别频繁,遇到的问题也会更复杂,目前主流的RESTful API所暴露出来的问题也愈来愈明显。github

若是能从源头出发,接口返回的数据不是由生产方(后端),而是由使用方(前端)来决定,就能够达到所见即所得的效果,这时候GraphQL也就应运而生了。json

什么是GraphQL?

先贴官网:英文 | 中文segmentfault

GraphQL 既是一种用于 API 的查询语言,也是一个知足你数据查询的运行时。 GraphQL 对你的 API 中的数据提供了一套易于理解的完整描述,使得客户端可以准确地得到它须要的数据,并且没有任何冗余,也让 API 更容易地随着时间推移而演进,还能用于构建强大的开发者工具。

也就是说,GraphQL可以在你调用api的时候来决定api返回的数据结构,以此达到精准、没有冗余的拿到所须要的数据。GraphQL这么厉害,是如何作到的呢?咱们先从个人博客文章详情页接口入手来揭示GraphQL的庐山真面目:后端

let data = {
  query: `query {
      repository(owner:"simbawus", name: "blog") {
        issue(number: ${articleId}) {
          title
          updatedAt
          bodyHTML
        }
      }
    }`
};

Actions.getIssues(data).then((res) => {
  let issue = res.data.data.repository.issue;

  this.setState({
      title: issue.title,
      updatedAt: new Date(issue.updatedAt).format('yyyy-MM-dd'),
      bodyHTML: issue.bodyHTML
  })
})

这就是一个基于GitHub GraphQL API的请求,跟普通请求惟一的区别就在请求参数data,并非 JSON 对象,而是一个字符串,这个字符串描述了客户端但愿服务端返回数据的具体结构,以下JSON:api

{
    "data": {
        "repository": {
            "issue": {
                "bodyHTML": "<p>本文主要结合...",
                "title": "前端应该知道的GraphQL",
                "updatedAt": "2018-04-22T03:46:34Z",
            }
        }
    }
}

结合这个例子,我来介绍GraphQL的几个核心概念:

query & mutation

query的中文意思是查询,也就对应RESTful标准中的get,而mutation的意思是变动,对应post、delete、patch和put。

connection

connection让你能在同一个请求中查询关联的对象。经过connection,你只须要一个GraphQL请求就能够完成RESTful API中多个请求才能作的事。

好比,GitHub GraphQL API文档中,咱们在查询issue对象的同时,还能够查labels对象。

let data = {
  query: `query {
      repository(owner:"simbawus", name: "blog") {
        issue(number: ${articleId}) {
          title
          updatedAt
          bodyHTML
        }
        labels(first: 100){
          nodes{
            name
          }
        }
      }
    }`
};

field

field是你能够从对象中获取的数据单元。正如GraphQL官方文档所说:“GraphQL查询语言本质上就是从对象中选择field”。全部的GraphQL操做必须指明到最底层的field,而且返回值为标量,以确保响应结果的结构明白无误。

argument

argument跟RESTful API标准中一致,表示咱们在请求该接口是传的参数,好比上面issue的number 参数,表示请求的第${articleId}个issue。

对于前端来讲,在查询GraphQL API的时候基本都要了解上面说的这几个概念,具体应用可参见个人这篇文章如何利用GitHub GraphQL API开发我的博客?。详情代码可查看个人github:simbawus/blog,欢迎star、fork。

GraphQL的将来

GraphQL的优点想必你们都了解了,但为什么这么好的技术并无获得普遍的应用和推广呢?

  1. 要在前端爽爽地使用 GraphQL,必须得在服务端搭建符合 GraphQL spec 的接口,基本上是整个改写服务端暴露数据的方式。痛点是前端的,却要后端来改造,谁会去作?
  2. 改为GraphQL对用户体验来讲并无什么提高,并且对后端水平要求也高,改起来不简单,须要花费大量的时间,老板不用付你工资的吗?
  3. GraphQL意味着一个中心化的API网关,中心化流量要求巨大的中心化集群,技术上运维上又是一个难题。

基于以上,GraphQL目前基本也就一些比较有技术追求和实力的创业公司和一线大厂在使用,但愿Facebook能更进一步,给出一个基于云端的解决方案,解放前端。

欢迎讨论,点个赞再走吧~

文章同步于如下社区,能够选一个关注我噢 。◕‿◕。

simbawu | github | segmentfault | 知乎 | 简书 | 掘金

相关文章
相关标签/搜索