graphql初探

graphql

纯rest:一个endpoint对应一个资源
优点:灵活、解构
缺点:由于一个endpoint对应一个资源所以需要很多次请求

类rest:一个endpoint对应一个视图
优点:一次请求、所得即所需
缺点:不够灵活、高度耦合、很高的维护成本、迭代慢


What

GraphQL 是由 Facebook 创造的用于描述复杂数据模型的一种查询语言。这里查询语言所指的并不是常规意义上的类似 sql 语句的查询语言,而是一种用于前后端数据查询方式的规范。

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

why

Graphql VS Restfull


image.png

Rest与Graphql对比实例

应用场景一:先订购披萨,然后再超市购物,接着再打电话给干洗店上门取衣服。三个店铺,三个电话。而graphql就像一个私人助理。只需要给出三个地方的地址,然后告诉Ta你想要什么(“衣服要干洗,一个大比萨饼,两大鸡蛋”),然手就可以坐等结果了

应用场景二:在博客应用中,应用需要展示指定用户的帖子标题。同一页面里还会显示该用户的最新3个关注者的名字。
REST和GraphQL是如何解决这个业务的呢?

使用rest API

通常可以调用多个接口获取数据。这对上述场景,首先可以调用/user/:id 接口来获取用户数据。紧接着,调用/users/<id>/posts返回该用户的所有帖子。最后,第三个接口可以是/users/<id>/followers,返回该用户的关注者列表。


graphql请求方式

核心概念

这篇文章主要分享的是 GraphQL 的核心概念,主要分为:Type System(类型系统), Query Language(查询语言), static Validation(静态验证) 和 type Introspection(类型检查) 四部分
(更多Schema和类型,请查看官网http://graphql.org

GraphiQL 是用于查询 GraphQL 端点的非常方便的浏览器端 IDE。

Type System

类型系统是整个Graphql的核心,它用来定义每个查询对象和返回对象的类型,将所有定义的对象组合
起来就形成了一整个Graphql Shema
还是以博客系统的例子来说明:我们首先建立一个文章的类型

type Post {
     id: String,
     name: String, 
    createDate: String, 
    title: String, 
    subtitle: String, 
    content: String
 }

文章类型就定义好了,包含了一系列的字段,字段的类型正好都是String,String是Graphql支持的Scalar type(标量类型),默认的标量类型还包括: Int,Float, Boolean和ID。

许多博客网站都支持给每篇文章打标签,那么我们再建立一个标签的类型

type Tag {
     id: String, 
    name: String,
     label: String, 
    createDate: String
 }

标签类型怎么与文章类型整合在一起呢?
GraphQL 不单单支持简单类型,还支持一些其他类型,如 Object, Enum, List, NotNull 这些常见的类型,还有 Interface, Union, InputObject 这几个特殊类型。
再修改一下之前的文章类型,使一个文章可以包含多个标签。
文章类型就定义好了,包含了一系列的字段,字段的类型正好都是String,String是Graphql支持的Scalar type(标量类型),默认的标量类型还包括: Int,Float, Boolean和ID。

许多博客网站都支持给每篇文章打标签,那么我们再建立一个标签的类型

type Tag {
     id: String, 
    name: String,
     label: String, 
    createDate: String
 }

标签类型怎么与文章类型整合在一起呢?
GraphQL 不单单支持简单类型,还支持一些其他类型,如 Object, Enum, List, NotNull 这些常见的类型,还有 Interface, Union, InputObject 这几个特殊类型。
再修改一下之前的文章类型,使一个文章可以包含多个标签。

type Post {
     id: String, 
    name: String, 
    createDate: String, 
    title: String, 
    subtitle: String, 
    content: String, 
    tags: [Tag] 
}

通常在博客网站的标签列表中会显示该标签下的一些文章,由于Graphql是以产品为中心的,那么在标签类型下也可以有文章类型。于是,标签类型修改为:

type Tag {
     id: String, 
    name: String,
     label: String, 
    createDate: String,
    post: [Post]
 }

最后,根据整个博客网站的需求,组合嵌套刚刚定义的文章类型和标签类型,建立一个根类型作为查询的schema。

type Blog { 
    post: Post, // 查询一篇文章 
    posts: [Post], // 用于博客首页,查询一组文章
    tag: Tag, // 查询一个标签 
    tags: [Tag], // 用于博客标签页,查询所有标签
 }

Ok!我们的类型和schema都定义好了,就可以开始查询了,怎么查呢,接下来我们看一下Graphql 的查询语法

QUERY Language(查询语言)

GraphQL 的查询语法同我们现在所使用的有一大不同是,传输的数据结构并不是 JSON 对象,而是一个字符串,这个字符串描述了客户端希望服务端返回数据的具体结构。

知道了概念,那么一个 GraphQL 的查询到底长什么样哪?继续我们的例子,假设,我们现在要查询一篇文章,那么,GraphQL 的查询语句就可以是这样。

query RootQuery { 
    blog {
            posts {
                id,
                name,
                createDate,
                title,
                subtitle,
                content
          }
    }
}

返回结果:

返回的结果是和之前的一样。查询关键字只有在多个查询时才必须,在单个查询时可以省略。同时,也可以对查询的返回起别名,再来看看看博客的首页希望展示一个粗略的文章列表,那么这样的一个查询语句可以是:

query FetchPostQuery {   
    blog {    
    postList: posts {        
        id,        
        name,       
        createDate,       
        title,       
        subtitle,       
        tags {            
            name,            
            label        
        }    
    }  
      }
}

返回的结果:



从中我们可以看到,数据返回了整个文章的属性以及部分的标签属性。其中,标签属性并没有返回全部的字段,而是只返回了 name 和 label 字段的属性,做到了返回数据的结构完成同请求数据的结构相同,没有冗余的数据。
查询添加参数的需求也非常基本,在 GraphQL 的查询语法中也相当简单,就拿刚刚的例子,要查询特定的文章就可以把它改成这样。

Query RootQuery {   
     blog {     
    post(name: "graphql-core-concepts") { 
            id,        
        name,        
        createDate,       
        title,        
        subtitle,        
        content,       
     tags {            
        name,           
        label        
    }   
     } 
 }

返回的结果:


STATIC VALIDATION

由于 GraphQL 是一个强类型语言,所以它可以在执行查询之前检查每个查询语句是否满足事先设定的 schema,符合则合法,如果查询语句不合法则不进行查询。
以上所举的都是合法的例子,官网上举了一些例子,这里就不贴了,我们就总结看看要注意的有哪几点。

  1. fragment 不能引用自己从而形成一个循环
  2. 不能查询类型中不存在的字段
  3. 查询的字段如果不是 scalar type(标量类型)或 enum type(枚举类型),则需要明确该字段下所包含的字段
  4. 同上一条相对,如果查询字段是 scalar type(标量类型),那么它就不能再有子字段

TYPE INTROSPECTION

在Graphql中Introspection是一个非常有用的功能,它可以用来查询当前Graphql的schema,从而得
知服务器端支持何种类型的查询。
这是一个非常强大且有用的功能,现在公司的开发基本是前后端分离的,客户端并不知道服务端提供的
Schema结构,但可以通过查询__schema字段来获得当前所支持的查询类型。

query RootQuery {  
     __schema {    
        types {     
             name   
         }  
    }
}

返回的结果:



从返回的数据中可以看到,我们自定义的BlogType,PostType和TagType,剩下的都是Graphql内部类
型,其中又分为两类:一类是ID,String和Boolean所表示的标量类型,另一类以双下划线开头的是用于
自我检查的类型。

知道了自定义了,假设,还想知道自定义类中包含那些属性以及属性的类型,就可以这样查询:

query RootQuery {   
    __type(name: "PostType") {   
    name    
    fields {      
        name   
        type {        
            name        
            kind 
            }    
    }  
     }
}

返回的结果:


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容