https://github.com/APIJSON/APIJSON
https://github.com/graphql-go/graphql
目前项目的接口都是基于 RESTful 规范设计的,这个时候如果想使用 GraphQL,不可能说根据 RESTful 提供的接口用 GraphQL 再实现一遍,这个代价太大了,时间和人力成本各方面都不允许。这个时候如果能直接基于 RESTful API 设计的接口来实现一套 GraphQL 接口是非常好的。RESTful API 接口可以保留且不影响它的后端开发,同时又可以对外提供 GraphQL 的服务,方便前端的使用。
要实现这个功能,其实也不难,使用 GraphQL 的自定义 Directive[7] (指令)就可以完成。自定义指令特性非常实用和便捷,通过编写自定义指令来转换 Schema 的 types、fields 和 arguments,扩展 Schema 字符串所能描述的逻辑。关于自定义指令的介绍,具体可以去看 GraphQL Tools 上关于它的介绍,其中就介绍了怎么样去获取 REST API 的数据( Fetching data from a REST API[8])。
https://www.imooc.com/article/291926
几种前后端接口的对比:RESTful,GraphQL,APIJSON
REST
核心理念是资源。服务端定义资源形式。资源的类型和获取资源的方法是紧密相关的。
REST 是多入口的,每个资源对应一个 URL,例如:http://api.test.com/books/,http://api.test.com/users/。
每个资源由后台定义好后,通过指定的一个 URL 访问(每个 URL 访问到不同的控制器)。通过向指定 URL发送 GET 请求来获取资源,或发送 POST 请求来创建或操作资源。
大部分 API 会返回 JSON 响应。
// 请求
GET /books/1
GET /users/250
// 响应
{
“title”: “Black Hole Blues”,
“author”: {
“firstName”: “Janna”,
“lastName”: “Levin”
}
// … more fields here
}
GraphQL
GraphQL 中需要定义所有资源的类型,但是不会指定对应的方法。只需要改变查询内容,前端就能定制服务器返回的响应内容。
GraphQL 是单入口的,所有的请求通过同一个 URL 进入服务器,例如:http://api.test.com/graphql。
在服务端,必须定义 Schema(模式)作为 GraphQL 请求的入口,用户的 GraphQL 请求在服务端解析后,会对应到具体的 Schema。
GraphQL 请求是这样的:query getHightScore { score } 可以获取 getHightScore 的 score 值。
也可以加上查询条件,例如:query getHightScore(limit: 10) { score }。
客户端示例:
// 查询,不加任何前缀时,默认是 query 查询。
{
user(id: 3500401) {
name,
profilePicture(size: 50) {
uri,
width,
height
}
}
}
// 响应,返回 JSON 格式的数据
{
“user” : {
“name”: “Jing Chen”,
“profilePicture”: {
“uri”: “http: //someurl.cdn/pic.jpg”,
“width”: 50,
“height”: 50
}
}
}
服务端示例(协议实现起来挺复杂,最好直接安装现成的库,各种语言版本的服务端库在这里http://graphql.cn/code/#c-net。)
APIJSON
APIJSON 的 GitHub 地址 https://github.com/TommyLemon/APIJSON/blob/master/Document.md
什么是GraphQL?
GraphQL是Facebook开源的API查询语言,类似于数据库中的SQL。作为比较,RESTful API依赖于后端隐式的被动的数据约定,GraphQL更加显式,在获取数据和更新数据时更加主动,所见即所得。GraphQL官方网址
RESTful的一些不足
比如获取用户信息/users/:id,最初可能只有id、昵称,但随着需求的变化,用户所包含的字段可能会越来越多,年龄、性别、头像、经验、等级,等等。
而具体到某个前端页面,可能只需要其中一小部分数据,这样就会增加网络传输量,前端获取了大量不必要的数据。
比如一个文章详情页,最初可能只需要文章内容,那么前端就调用/articles/:aid获取到文章内容来展现就行了
但随着需求的演进,产品可能会希望加上作者信息(昵称、头像等),这时前端又需要在获取文章详情后,根据其中的作者id字段继续获取作者相关的信息,/user/:uid
然后,需求又变化了,产品希望在加上这篇文章的评论,这时前端需要继续调用/comment/:aid来拉取评论列表
对于Web前端而言,由于ajax技术的存在,这种的请求数据方式,也就开发上稍微麻烦些,并不会造成太大的问题;但对于App来说,渲染的方式不同,必须要拉取的全部的数据之后,才能绘制界面,就会导致这个界面必须要等到所有3个RESTful接口的返回数据都拿到,才能进行绘制。
GraphQL优点
查询的返回结果就是输入的查询结构的精确映射
如果设计的数据结构是从属的,直接就能在查询语句中指定;即使数据结构是独立的,也可以在查询语句中指定上下文,只需要一次网络请求,就能获得资源和子资源的数据。
GraphQL会把schema定义和相关的注释生成可视化的文档,从而使得代码的变更,直接就反映到最新的文档上,避免RESTful中手工维护可能会造成代码、文档不一致的问题。
RESTful方案本身没有对参数的类型做规定,往往都需要自行实现参数的校验机制,以确保安全。
但GraphQL提供了强类型的schema机制,从而天然确保了参数类型的合法性。
GraphQL适用场景
从Facebook最初开发GraphQL的目的,和笔者实际使用的情况而言,GraphQL还是存在一些缺点的,完全替代RESTful作为一种新的接口规范还有些为时过早。
GraphQL作为RESTful的一种辅助工具,尤其是针对前端App在复杂页面,本来要调用有上下文关系的多次RESTful请求时,采用GraphQL,只需要一次请求,就可以拿回所需的全部数据(有点JSON直出的意思),还是可以起到非常好的效果,大大提升App的性能。