Restful

image.png
目前大多数网站都基于Restful架构,在该模式下,每个资源都有自己配套的一个API接口。用URI来定位资源,Method来描述对资源做什么操作。

现在在该模式下,我们有这样一个需求:显示一篇文章的内容,同时也要显示评论、作者信息。那么我们就需要分别调用文章接口、评论接口、用户接口。该架构就会暴露出一些缺陷:

1.多消耗客户端资源:调用多个API接口,多次发送HTTP请求,并且需要在用户端进行信息拼接。

2.冗余数据:比如我们可能只要知道用户姓名,但是用户接口可能会一起返回性别,星座等无关数据。

3.字段类型校验:由于服务端返回数据的不可控性,前端需要对某些字段做类型校验。

4.接口文档不规范:前后端分离开发约定的接口文档,可能会因为后端开发的疏忽更新不及时,引发后续问题。

而GraphQL能完美的解决上述问题。

image.png

GraphQL

官方定义

我们先来看一下GraphQL的官方定义:

image.png

简直晦涩难懂...我们还是直接来看看同一个需求,在GraphQL架构下的实现吧~

同一个需求,在GraphQL下的实现

首先我们访问GraphQL服务器,点击SCHMA查看一下它提供给前端什么资源。比如用户资源,获取时需携带用户ID,返回的User对象可取字段有id,name等。接着就可以写请求SCHEMA,获取定制化数据(项目代码在附录章节)

演示:graphql.mov

Restful vs GraphQL

image.png

GraphQL几个重要概念

操作类型 Operation Type

  • 描述客户端希望进行什么样的操作
    1.query 查询:获取数据,比如查找,CRUD 中的 R。
    2.mutation 变更:对数据进行变更,比如增加、删除、修改,CRUD 中的 CUD。
    3.substription 订阅:当数据发生更改,进行消息推送。

对象类型和标量类型 Object Type & Scalar Type

  • 定义资源
    1.对象类型:用户在 schema 中定义的 type。
    2.标量类型:GraphQL 中内置有一些标量类型 String、Int、Float、Boolean、ID,
    用户也可以定义自己的标量类型。

解析函数 Resolver

  • 服务端提供资源的方式
    前端请求信息到达后端之后,需要由解析函数 Resolver 来提供数据。

GraphQL使用流程

image.png

Describe your data - 服务端要做的事

1.定义资源结构。

image.png

2.定义每个操作类型下暴露给前端的资源或接口。

image.png

3.为每个操作类型下的资源或接口提供Resolve策略函数。

Query

image.png

Mutation

image.png

Subscription

这里的 pubsub 是 apollo-server 里负责订阅和发布的类,它在接受订阅时提供一个异步迭代器,在后端觉得需要发布订阅的时候向前端发布 payload。withFilter 的作用是过滤掉不需要的订阅消息,详细用法参照订阅过滤器

image.png

Ask for what you want - 前端如何请求资源

1.查询资源

image.png

2.更新资源

image.png

3.订阅资源

发送一个订阅请求

image.png

发送一个更新请求,触发订阅

image.png

触发之前定义的逻辑

image.png

Get predictable results - 通过HTTP协议交互

以之前的Query请求为例:

image.png

小结

image.png1.接口提供方定义好强类型的数据入参和返回的数据结构。

2.客户端发送一个带有查询语句(graphql的查询协议)的请求,请求里定义了需要哪些数据。

3.服务端返回给客户端符合客户端预期的json字符串结果。

GraphQL个人理解

对前端而言,GraphQL就是一套和GraphQL服务器上资源进行交互的语法。(即如何去写schema)

对后端而言, GraphQL就是一套提供资源的策略,告知前端每个资源的形态和操作方式,前端按需组装。(即如何为schema提供数据)

GraphQL运行机制

image.png

1.请求传输 - HTTP Request

客户端通过HTTP协议,将Schema封装在body中,传输到GraphQL服务器。

image.png

2.解析阶段 - String -> document

识别 Schema 字符串。graphql-js利用特征标识符与 AST 语法树规范,对 Schema 逐字符扫描,通过词法分析和语法分析得到节点树。

特征标识符:

image.png

AST 语法树规范,规定语法树支持以下节点:

image.png

最终解析阶段的产出物 - document:

image.png

3.校验阶段 - 检验document

验证客户端 Schema 是否按照服务端定义好的方式获取数据,比如:获取数据的方法名是否有误,必填项是否有值等。

image.png

4.执行阶段 - document -> json

执行对应的 resolve 函数,封装成json资源并输出。

每个类型的每个字段都有一个resolver函数支持,该函数由GraphQL服务器开发人员提供,当一个字段被执行时,相应的resolver被调用产生下一个值。如果字段产生标量值,则执行完成,如果产生对象,则该查询将继续执行该对象对应的解析器,直到返回标量值。

5.响应返回 - HTTP Response

image.png

GraphQL开源协议

BSD+Patents

graphql-js曾经用过BSD+Patents协议。

Patents:专利附属条款,被视为Facebook用于解决开源代码中可能出现的专利纠纷的防御措施。

大致内容是使用基于Patents协议的开源项目的开发者,未来要是因为专利问题与Facebook产生纠纷,那么Facebook将有权停止你使用该开源项目,也就是说如果你起诉Facebook,那么你所使用他们的开源技术开发的产品要么得停用,要么得用别的技术迁移重构。

MIT

在2017年移除,改为MIT并沿用至今。

事件背景:2017年7月,开源组织 Apache 软件基金会将基于Facebook BSD+Patents协议的开源软件列入黑名单,同年9月,WordPress、百度等大型公司宣布停用React(Native)开源项目以规避风险,此后,Facebook才公开发表声明,表示从 v16开始,React将不再使用BSD+Patents协议,而是采用MIT协议。

在这之后, Facebook逐渐把很多开源项目改为MIT协议。

专利

image.png

目前GraphQL的专利还在Facebook手里,要到 2034 年才过期。所以目前部门只在运营管理端接入,开发者管理端因为安全问题暂时还没有接入计划。

附录

项目地址:

Github

参考:

  1. GraphQL | 一种为你的 API 而生的查询语言
  2. GraphQL 从入门到实践
  3. GraphQL 技术浅析

Zack921
0 声望1 粉丝

一个前端。