GraphQL这个坑可以入了 (1)RESTful API痛点

分享 未结
1 1 0 3
小编 2019-06-13发布
收藏 点赞
来源: 编程还真是个事儿

如果你现在才开始注意GraphQL,我得说,这已经不是早班车了。从我最近道听途说到的一些消息,硅谷大量的一线,准一线,二线公司都已经开始接受GraphQL了,那这东西到底有什么好,又该怎么用呢?且听我慢慢道来。

(这玩意实在是太新,而且我更多是从后端API设计和高并发的角度,要是我有哪里说错了,请给位一定指正,我及时更新)

GraphQL是由Facebook搞出来的,现在已经形成标准,他们自己用的非常欢,很快就完成了前后端的换代。他们的实践也给我们提供了很多宝贵经验,比如说我们知道GraphQL和React可以结合的非常好(都是他家的技术),这一点让很多已经归顺React的前端程序员非常欢欣鼓舞,成为推动GraphQL革命的主力。要说Facebook那异常复杂的前端界面,没点这种革命性的技术,还真不行。Facebook用的好之后呢,很多硅谷公司也就跟进了,比如说,现在如果大家开发Github的应用,会发现他家也用上了,这一版的API就是GraphQL的: https://developer.github.com/v4/

我不是给他家打广告哦,把它列在这里,主要是应为这套API也是学习GraphQL的好资料。

当然,这技术要说什么大厂(Facebook)驱动,大腕跟进(github),我觉得还都是次要,咱们不是那种跟风的人啊。那为啥要用GraphQL? 再介绍GraphQL 的特点前,我们先来说说我们一直在用的RESTful API (以下简称rest)有什么痛点。因为你要是开始用GraphQL,难免就得要现有的Rest下岗。

Rest现在已经是Web服务最主要的架构方式,对,他其实是种系统设计的模式,并没有形成一种数据传输的协议,他对URL的形式提出了一些规范,但实际运用中,还是很自由的,你可以/user/1 也可以/user.php?id=1 ,这两种形式都是很RESTful的。然后Rest就不管了,你可以用各种协议传输数据,当然我们最主要的还是用Http,你可以装载任何的数据,如果是API,现在装Json的比较多,以前装Xml的也不少,不过你也可以返回一个Html页面,返回一张图片,这些都不破坏Rest。一般来说,我们把Rest映射到一系列资源,比如说用户、帖子、回复、图片等,那我们的API就是对这些资源进行增删改查(CRUD)。我得说这是一种异常强壮的设计,你再结合使用一些扩展性非常强的数据格式,例如Json,足可以应付各种现在和将来的需求变化。如果你开发了这么一套API,可能十年八年都不用推倒重来,比如说我们Twitter 的Web API。

但这种资源的表达,带来几个问题:

  1. 数据定制的问题:我们的应用数据现在越来越丰富,已经不是10年前可以相比的了,也就是说数据的返回可能很丰富,非常大,而我这次可能只要其中一小部分,比如说我请求一个用户的数据/user/1,我只要他的名字和头像,而并不需要他几千个好友。传统的Rest,你可以加个Mask参数,例如/user/1?friend=false 这种方式无疑增大了前后端的代码复杂度,增加了开发的强度,而且也不够灵活,难道我要给每个字段都加个Mask?后端要依赖各种可能的Mask组合来生成查询也是个麻烦事儿,这种代码写出来也是难维护。
  2. 多次请求的问题:类似上面提到的灵活性问题,上面说我们要少要点数据,那我们这次想多要些数据。比如说我想要一个用户的所有好友,还没完,再加上每一个好友的所有好友。这在传统Rest里面,往往我们就使用多次的请求,拿到1度好友的列表,然后写个循环,依次拿到所有2度好友。这当然不够优化,于是可能你会再设计一个专门的API去一次性拿到所有2度好友。同样的问题,这增大了前后端的代码复杂度,不够灵活,万一下次我要3度好友呢?
  3. 异常处理的问题:这个很多朋友都会有自己的办法,有些朋友会返回特定的http response code: 4XX, 5XX,有些朋友可能会返回特定的Json消息。比如说/get/user/8527, 如果这个用户不存在,你可以返回404,你也可以返回自定义消息{msg:“user not found”}。这很多时候也不是问题,但我觉得如果使用更结构化的异常处理方式,应该会好些。
  4. 发出一个请求,我不知道会得到啥:结合上面几点,其实你会发现,如果你请求一个资源,例如/user/1,你并不知道结果里具体会有什么,你可能需要查阅文档,但文档可能已经过期。你可以自己实验,但你不知道是否覆盖了全部可能的情况。这是一个很痛苦的过程。
  5. PUT和DELETE也是个坑:这需要前后端框架的支持,如果不支持怎么办?其实我也不知道,我这么多年一直尽量避免使用PUT和DELETE来设计API。
  6. 每个resource都有自己的一组end point或者说URL,这会带来管理和维护的麻烦。
  7. 安全问题:Rest难以避免的从URL上接受各种参数(parameter),不严格的使用Get等都会造成安全的隐患。有些问题GraphQL上也有,而且我不是这方面的专家,就不细说了。

一下就说这么多吧,这些问题,如果你肯用GraphQL,那么都能得到不错解决。怎么解决,GraphQL又有哪些特点,且看我下回分解。

回帖
  • 消灭零回复