如何在 LeanCloud 中使用 GraphQL?

做者:王子亭 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 主頁上看到,這個項目自己也是開源的。

相關文章
相關標籤/搜索