GraphQL和RESTful的比较介绍2017年5月,Github也发布了第四版API,使用GraphQL,推荐集成商在GitHubAppAPIv4中使用最新版本的GraphQL。想想GitHub的RESTAPI是非常完备的,设计的也很好。很多公司在开发自己的RESTAPI时都会参考GitHub的实现。那么GitHub为什么选择GraphQL?RESTful缺乏可扩展性,单一RESTful接口返回的数据越来越臃肿。比如获取用户信息/users/:id,一开始可能只有id和昵称,但是随着需求的变化,user中包含的字段可能会越来越多,年龄,性别,头像,经验,级别,等等。对于特定的前端页面,可能只需要一小部分数据,这会增加网络传输量,前端会获取大量无用的数据。一个前端展示其实需要调用多个独立的RESTfulAPI来获得足够的数据。比如一个文章详情页,一开始可能只需要文章的内容,然后前端调用/articles/:aid获取文章内容并展示。但是,随着需求的发展,产品可能希望添加作者信息(昵称、头像等)。此时前端需要在获取文章详情后,根据作者id字段继续获取作者相关信息。/user/:uid然后,需求又变了,产品希望对这篇文章进行评论。这时候前端需要继续调用/comment/:aid拉取评论列表。对于web前端来说,由于ajax技术的存在,这种请求数据的方式在开发中稍微麻烦一些,不会造成太大的问题;但是对于App来说,渲染方式不一样,必须拉取所有的数据才能绘制界面,这就会导致这个界面必须等到三个RESTful接口的返回数据都获取完之后才能绘制。GraphQL的一些优点所见即所得查询的返回结果是输入查询结构的精确映射Query:{user(uid:1){uidname}}returns:{"data":{"user":{"uid":"1","name":"xxx"}}}减少网络请求次数如果设计的数据结构是从属的(比如上面文章的作者信息),可以直接指定{article(aid)in查询语句:1){titlecontentauthor{uidname}}}即使数据结构是独立的,也可以在查询语句中指定上下文。只需要一次网络请求就可以获取资源和子资源的数据(比如上面文章的评论信息){article(aid:1){titlecontentauthor{uidname}},comment{content,author{uidname}}}codeasdocumentGraphQL会将schema定义和相关注释生成可视化文档,让代码的改动直接体现在最新的文档中,避免了RESTful中手动维护可能导致的代码和文档的不一致。参数类型强校验RESTful方案本身并没有规定参数的类型,往往需要自己实现一个参数校验机制来保证安全性。但是GraphQL提供了强类型schema机制,自然保证了参数类型的合法性。从Facebook最初开发GraphQL的目的和笔者的实际使用来看,GraphQL还是有一些不足的。现在完全取代RESTful作为新的接口规范还为时过早。GraphQL是RESTfulTools的一个辅助工具,特别是对于复杂页面的前端App,当需要调用多个带上下文的RESTful请求时,使用GraphQL,只需要一个请求就可以取回所有需要的数据(有点像JSONstraightout),还是可以起到很好的效果,大大提升App的性能。
