做者:王子亭 LeanCloud 工程师git
GraphQL 是 FaceBook 开源的一套数据查询语言,也是 Relay 钦定的组件,能够在客户端以一种很是灵活的语法来获取数据,但目前支持 GraphQL 的服务还比较少,最近 GitHub 也宣布了其开放 API 支持了 GraphQL。
由于 GraphQL 的支持须要服务器端的更改,所以我选择了在 LeanCloud 的数据服务的基础上用 Node.js 编写一个中间层,运行在云引擎上,将 GraphQL 的查询翻译成对 LeanCloud SDK 的调用,为客户端提供 GraphQL 支持。github
我也参考了其余语言和框架的 GraphQL 支持,它们都须要开发者进行不少的开发或配置工做。这是由于不管在 MySQL 仍是 MongoDB 中都并无记录数据之间的关联关系(Id 和 ObjectId 都不会记录指向的表或集合,MySQL 的外键却是会记录,但惋惜用户很少);并且即便你定义了数据之间的关联,你仍是须要去定义权限 —— 哪些用户能够访问哪些数据。api
而 LeanCloud 的 Relation 和 Pointer 都记录了所指向的 Class,同时 LeanCloud 自己也有一套基于 sessionToken 和 ACL 的权限控制机制,所以咱们彻底能够作到从 LeanCloud 的数据服务获取数据之间的管理,而后遵循现有的 ACL 来自动实现对 GraphQL 的支持。服务器
leancloud/leancloud-graphql 就是这样的一个项目,你只需将它部署到云引擎上,不须要改动一行代码,即可以用 GraphQL 查询你在 LeanCloud 上的全部数据。session
相较于 RESTful 和 SQL,GraphQL 为数据定义了严格的类型,你能够使用这样一个灵活的语言将数据经过关系组合起来,所见即所得地获得你想要的数据。得益于 GraphQL 的类型系统,你还能够在调试工具(graphql.leanapp.cn)中获得精确的错误提示和补全建议。app
例如这里咱们查询 Todo 这个 Class 中按优先级排序的前两条数据,获取 title、priority,并将 owner 这个 Pointer 展开:框架
query { Todo(ascending: priority, limit: 2) { title, priority, owner { username } } }
结果:工具
{ Todo: [{ title: "紧急 Bug 修复", priority: 0, owner: { username: "someone" } }, { title: "打电话给 Peter", priority: 5, owner: { username: "someone" } }] }
目前 leancloud-graphql 已经实现了 LeanCloud 中大部分的查询参数和查询条件,你能够任意地组合这些条件。例如咱们能够查询优先级大于 5 且存在 content 属性的数据:翻译
query { Todo(exists: {content: true}, greaterThan: {priority: 5}) { title, content, priority } }
GraphQL 最大的亮点仍是对关系查询的支持,不管是 Relation 仍是 Pointer 你均可以任意地展开,而没必要受到 LeanCloud RESTful API 只能展开一层的限制。例如咱们查询全部的 TodoFolder 中的 Todo(Relation)并展开 owner(Pointer):指针
query { TodoFolder { name, containedTodos { title, owner { username, email } } } }
结果(省略了一部分):
{ TodoFolder: [{ name: "工做", containedTodos: [{ title: "紧急 Bug 修复", owner: { username: "someone", email: "test@example.com" } }, // ... ] }, // ... ] }
你也能够在关系查询上附加查询参数或条件。例如咱们查询全部 TodoFolder 中优先级最高的一个 Todo:
query { TodoFolder { name, containedTodos(limit: 1, ascending: priority) { title, priority } } }
结果:
{ TodoFolder: [{ name: "工做", containedTodos: [ {title: "紧急 Bug 修复", priority: 0} ] }, name: "购物清单", containedTodos: [ {title: "买酸奶", priority: 10} ] }, { name: "someone", containedTodos: [ {title: "紧急 Bug 修复", priority: 0} ] }] }
在实现一对多关系时,咱们常常会在「多」上面保存一个到「一」的指针,例如一个 Todo 会有一个叫 owner 的 Pointer 指向用户表。在这时,leancloud-graphql 会自动在用户表上添加一个叫 ownerOfTodo 的属性用来表示这个反向关系,你能够像展开一个 Relation 同样展开这个反向关系,例如咱们查询每一个用户的 Todo 并展开 title:
query { _User { username, ownerOfTodo { title } } }
结果:
{ _User: [{ username: "someone", ownerOfTodo: [ {title: "紧急 Bug 修复"}, {title: "打电话给 Peter"}, {title: "还信用卡帐单"}, {title: "买酸奶"} ] }] }
对 leancloud/leancloud-graphql 的简单介绍就到这里,更多使用方法和功能介绍能够在项目的 GitHub 主页上看到,这个项目自己也是开源的。