{"id":19614749,"url":"https://github.com/leancloud/leancloud-graphql","last_synced_at":"2025-04-28T01:32:15.768Z","repository":{"id":57289925,"uuid":"76430627","full_name":"leancloud/leancloud-graphql","owner":"leancloud","description":"Third party GraphQL support for LeanCloud, running on LeanEngine","archived":false,"fork":false,"pushed_at":"2018-01-16T03:25:45.000Z","size":32,"stargazers_count":105,"open_issues_count":5,"forks_count":12,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-04-24T02:40:24.442Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://graphql.leanapp.cn","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/leancloud.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-12-14T06:14:53.000Z","updated_at":"2024-11-18T23:45:09.000Z","dependencies_parsed_at":"2022-08-25T07:40:51.936Z","dependency_job_id":null,"html_url":"https://github.com/leancloud/leancloud-graphql","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leancloud%2Fleancloud-graphql","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leancloud%2Fleancloud-graphql/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leancloud%2Fleancloud-graphql/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leancloud%2Fleancloud-graphql/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/leancloud","download_url":"https://codeload.github.com/leancloud/leancloud-graphql/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251234122,"owners_count":21556787,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-11T10:53:33.466Z","updated_at":"2025-04-28T01:32:15.464Z","avatar_url":"https://github.com/leancloud.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# LeanCloud GraphQL\n运行在云引擎上的第三方 GraphQL 支持，允许你用 GraphQL 查询 LeanCloud 云存储中的所有数据。\n\n\u003c!-- toc --\u003e\n\n- [部署到云引擎](#%E9%83%A8%E7%BD%B2%E5%88%B0%E4%BA%91%E5%BC%95%E6%93%8E)\n- [GraphQL](#graphql)\n- [获取数据](#%E8%8E%B7%E5%8F%96%E6%95%B0%E6%8D%AE)\n- [查询条件](#%E6%9F%A5%E8%AF%A2%E6%9D%A1%E4%BB%B6)\n  * [equalTo](#equalto)\n  * [exists](#exists)\n  * [范围查询](#%E8%8C%83%E5%9B%B4%E6%9F%A5%E8%AF%A2)\n  * [数组查询](#%E6%95%B0%E7%BB%84%E6%9F%A5%E8%AF%A2)\n  * [组合查询](#%E7%BB%84%E5%90%88%E6%9F%A5%E8%AF%A2)\n- [关系查询](#%E5%85%B3%E7%B3%BB%E6%9F%A5%E8%AF%A2)\n  * [Relation](#relation)\n  * [Pointer](#pointer)\n  * [查询条件](#%E6%9F%A5%E8%AF%A2%E6%9D%A1%E4%BB%B6-1)\n  * [反向关系](#%E5%8F%8D%E5%90%91%E5%85%B3%E7%B3%BB)\n  * [多级关系](#%E5%A4%9A%E7%BA%A7%E5%85%B3%E7%B3%BB)\n- [修改对象](#%E4%BF%AE%E6%94%B9%E5%AF%B9%E8%B1%A1)\n  * [创建对象](#%E5%88%9B%E5%BB%BA%E5%AF%B9%E8%B1%A1)\n  * [更新对象](#%E6%9B%B4%E6%96%B0%E5%AF%B9%E8%B1%A1)\n- [添加到现有项目](#%E6%B7%BB%E5%8A%A0%E5%88%B0%E7%8E%B0%E6%9C%89%E9%A1%B9%E7%9B%AE)\n  * [作为中间件添加](#%E4%BD%9C%E4%B8%BA%E4%B8%AD%E9%97%B4%E4%BB%B6%E6%B7%BB%E5%8A%A0)\n  * [获取 GraphQLSchema](#%E8%8E%B7%E5%8F%96-graphqlschema)\n\n\u003c!-- tocstop --\u003e\n\n## 部署到云引擎\n\n见 [LeanCloud 命令行工具](https://leancloud.cn/docs/leanengine_cli.html)。\n\n## GraphQL\n\n[GraphQL](http://graphql.org/) 是 FaceBook 开源的一套查询语言，你可以用它定义数据的格式和获取方法（这就是 leancloud-graphql 做的工作，它会自动将你在 LeanCloud 的数据结构转换为 GraphQL 的 Schema），然后便可以在客户端以一种非常灵活的语法来获取数据，甚至也可以用它来创建和更新数据。\n\n在使用 leancloud-graphql 之前，你可能需要先了解一下 [GraphQL 的语法](http://graphql.org/learn/queries/) ，下面我们不会过多地介绍 GraphQL 本身。这篇文章将使用 JavaScript SDK 文档中的 [示例数据结构](https://leancloud.cn/docs/leanstorage_guide-js.html#示例数据结构) 进行讲解。\n\nGraphQL 在客户端几乎不需要什么 SDK，你可以花几行代码封装一个工具函数：\n\n```javascript\nfunction requestGraphQL(query) {\n  return fetch('/', {\n    method: 'POST',\n    body: query\n  }).then( res =\u003e {\n    return res.json();\n  }).then( result =\u003e {\n    return result.data;\n  });\n}\n```\n\n我们也用 GraphiQL 提供了一个支持自动补全等功能的 GraphQL 控制台（本地调试时为 \u003chttp://127.0.0.1:3000/\u003e），你可以在这里测试你的查询。\n\n我们会应用客户端发来的 sessionToken，确保在用户的权限范围内进行查询。你可以从我们的 JavaScript SDK 上获取 sessionToken 并随着请求发送，修改 requestGraphQL：\n\n```diff\n  headers: {\n    'Content-Type': 'application/graphql',\n+   'X-LC-Session': AV.User.current() \u0026\u0026 AV.User.current().getSessionToken()\n  },\n```\n\n## 获取数据\n\n最简单的一个查询：\n\n```graphql\nrequestGraphQL(`\n  query {\n    Todo {\n      title, priority\n    }\n  }\n`)\n```\n\n默认会返回最多 100 条数据：\n\n```javascript\n{\n  Todo: [\n    {title: \"紧急 Bug 修复\", priority: 0},\n    {title: \"打电话给 Peter\",priority: 5},\n    {title: \"还信用卡账单\", priority: 10},\n    {title: \"买酸奶\", priority: 10},\n    {title: \"团队会议\", priority: 5}\n  ]\n}\n```\n\n你可以在此基础上添加排序、条数限制等选项：\n\n- `ascending` 按照指定字段升序。\n- `descending` 按照指定字段降序。\n- `limit` 条数限制。\n\n例如我们按照优先级升序排序，取最重要的两个任务：\n\n```graphql\nquery {\n  Todo(ascending: priority, limit: 2) {\n    title, priority\n  }\n}\n```\n\n结果：\n\n```javascript\n{\n  Todo: [\n    {title: \"紧急 Bug 修复\", priority: 0},\n    {title: \"打电话给 Peter\",priority: 5}\n  ]\n}\n```\n\n## 查询条件\n\n首先你可以按照 objectId 进行简单的查询：\n\n```graphql\nquery {\n  Todo(objectId: \"5853a0e5128fe1006b5ce449\") {\n    title, priority\n  }\n}\n```\n\n结果：\n\n```javascript\n{\n  Todo: [\n    {title: \"还信用卡账单\", priority: 10}\n  ]\n}\n```\n\n### equalTo\n\n你也可以像 LeanCloud 的 SDK 一样使用多种查询条件：\n\n```graphql\nquery {\n  Todo(equalTo: {title: \"团队会议\"}) {\n    title\n  }\n}\n```\n\n### exists\n\nexists 可以用来查询存在或不存在某一字段的对象，例如我们查询存在 title 但不存在 content 的 Todo：\n\n```graphql\nquery {\n  Todo(exists: {title: true, content: false}) {\n    title, content\n  }\n}\n```\n\n### 范围查询\n\n```graphql\nquery {\n  Todo(greaterThanOrEqualTo: {priority: 10}) {\n    title, priority\n  }\n}\n```\n\n目前支持的查询包括：\n\n- `greaterThan` 约束指定列大于特定值。\n- `greaterThanOrEqualTo` 约束指定列大于等于特定值。\n- `lessThan` 约束指定列小于特定值。\n- `lessThanOrEqualTo` 约束指定列小于等于特定值。\n\n### 数组查询\n\n```graphql\nquery {\n  Todo(containedIn: {tags: [\"Online\"]}) {\n    title, tags\n  }\n}\n```\n\n目前支持的数组查询包括：\n\n- `containedIn` 约束指定列中包含特定元素。\n- `containsAll` 约束指定列中包含所有元素。\n\n### 组合查询\n\n你可以将我们前面提到的所有查询条件组合在一起：\n\n```graphql\nquery {\n  Todo(exists: {content: true}, ascending: priority, greaterThan: {priority: 5}) {\n    title, content, priority\n  }\n}\n```\n\n## 关系查询\n\n### Relation\n\n如果对象的一个字段是 Relation，那么你就可以在 GraphQL 中将它展开，例如我们可以查询每个 TodoFolder 中包含的 Todo：\n\n```graphql\nquery {\n  TodoFolder {\n    name, containedTodos {\n      title, priority\n    }\n  }\n}\n```\n\n结果：\n\n```javascript\n{\n  TodoFolder: [{\n    name: \"工作\",\n    containedTodos: [\n      {title: \"紧急 Bug 修复\", priority: 0},\n      {title: \"打电话给 Peter\", priority: 5},\n      {title: \"团队会议\", priority: 5}\n    ]\n  }, {\n    name: \"购物清单\",\n    containedTodos: [\n      {title: \"买酸奶\", priority: 10}\n    ]\n  }]\n}\n```\n\n### Pointer\n\n如果一个字段是 Pointer 你也可以将它展开，例如我们可以查询 Todo 的创建者（到用户表的指针）：\n\n```graphql\nquery {\n  Todo(limit: 1) {\n    title, owner {\n      username, email\n    }\n  }\n}\n```\n\n结果：\n\n```javascript\n{\n  Todo: [\n    {\n      title: \"紧急 Bug 修复\",\n      owner: {\n        username: \"someone\",\n        email: \"test@example.com\"\n      }\n    }\n  ]\n}\n```\n\n### 查询条件\n\n你也可以在关系查询上附加查询参数或查询条件：\n\n```graphql\nquery {\n  TodoFolder {\n    name, containedTodos(limit: 1, exists: {content: true}) {\n      title, content\n    }\n  }\n}\n```\n\n结果：\n\n```javascript\n{\n  TodoFolder: [{\n    name: \"工作\",\n    containedTodos: [\n      {title: \"团队会议\", content: \"BearyChat\"}\n    ]\n  }, {\n    name: \"购物清单\",\n    containedTodos: []\n  }, {\n    name: \"someone\",\n    containedTodos: [\n      {title: \"还信用卡账单\", content: \"2016 年 12 月\"}\n    ]\n  }]\n}\n```\n\n支持的参数和条件包括：`ascending`、`descending`、`limit`、`objectId`、`equalTo`、`exists`、`greaterThan`、`greaterThanOrEqualTo`、`lessThan`、`lessThanOrEqualTo`、`containedIn`、`containsAll`。\n\n### 反向关系\n\n在实现一对多关系时，我们经常会在「多」上面保存一个到「一」的指针，leancloud-graphql 会自动在「多」上面创建一个属性，用来表示反向关系。例如因为 Todo 的 owner 是一个指向 \\_User 的 Pointer，所以 \\_User 上会自动出现一个 `ownerOfTodo`：\n\n```graphql\nquery {\n  _User {\n    username, ownerOfTodo {\n      title\n    }\n  }\n}\n```\n\n这样我们便可以查到每个用户的 Todo：\n\n```javascript\n{\n  _User: [{\n    username: \"someone\",\n    ownerOfTodo: [\n      {title: \"紧急 Bug 修复\"},\n      {title: \"打电话给 Peter\"},\n      {title: \"还信用卡账单\"},\n      {title: \"买酸奶\"}\n    ]\n  }]\n}\n```\n\n你也可以在 Relation 上进行反向查询，例如查询每个 Todo 所属的 TodoFolder：\n\n```graphql\nquery {\n  Todo {\n    title, containedTodosOfTodoFolder {\n      name\n    }\n  }\n}\n```\n\n结果（省略了一部分）：\n\n```javascript\n{\n  Todo: [{\n    title: \"紧急 Bug 修复\",\n    containedTodosOfTodoFolder: [\n      {name: \"工作\"},\n      {name: \"someone\"}\n    ]\n  }, {\n    title: \"买酸奶\",\n    containedTodosOfTodoFolder: [\n      {name: \"购物清单\"},\n      {name: \"someone\"}\n    ]\n  }, {\n    title: \"团队会议\",\n    containedTodosOfTodoFolder: [\n      {name: \"工作\"}\n    ]\n  }]\n}\n```\n\n### 多级关系\n\n在 GraphQL 中你甚至可以进行多层级的关系查询：\n\n```graphql\nquery {\n  TodoFolder {\n    name,\n    containedTodos {\n      title, owner {\n        username, email\n      }\n    }\n  }\n}\n```\n\n结果（省略了一部分）：\n\n```javascript\n{\n  TodoFolder: [{\n    name: \"工作\",\n    containedTodos: [{\n      title: \"紧急 Bug 修复\",\n      owner: {\n        username: \"someone\",\n        email: \"test@example.com\"\n      }\n    }, // ...\n    ]\n  }, // ...\n  ]\n}\n```\n\n## 修改对象\n\nGraphQL 毕竟是一个数据查询语言，因此我们仅提供了非常有限的创建和更新对象的功能。\n\n### 创建对象\n\n你可以这样创建一个对象，并要求服务器返回 objectId、标题和优先级：\n\n```graphql\nmutation {\n  Todo(title: \"思考巨石阵是如何修建的\") {\n    objectId, title, priority\n  }\n}\n```\n\n结果：\n\n```javascript\n{\n  Todo: {\n    objectId: \"5853adb7b123db006562f83b\",\n    title: \"思考巨石阵是如何修建的\",\n    priority: 10\n  }\n}\n```\n\n### 更新对象\n\n然后你可以用非常相似的语法来更新这个对象（当你提供了 objectId 便是更新对象）：\n\n```graphql\nmutation {\n  Todo(objectId: \"5853adb7b123db006562f83b\", priority: 5) {\n    title, priority\n  }\n}\n```\n\n结果：\n\n```javascript\n{\n  Todo: {\n    title: \"思考巨石阵是如何修建的\",\n    priority: 5\n  }\n}\n```\n\n## 添加到现有项目\n\n如果要添加到现有项目，需要先将 leancloud-graphql 添加为依赖：\n\n    npm install --save leancloud-graphql\n\n请确保 Node.js 版本在 4.0 以上。\n\n### 作为中间件添加\n\nleancloud-graphql 导出了一个 express 中间件，可以直接添加到现有的 express 项目上：\n\n```javascript\nvar leancloudGraphQL = require('leancloud-graphql').express;\nvar app = express();\napp.use('/graphql', leancloudGraphQL());\n```\n\nleancloudGraphQL 有一些选项：\n\n- `graphiql` 开启调试控制台，默认 true.\n- `cors` 提供跨域支持，默认 true.\n- `pretty` 格式化返回的 JSON。\n\n使用该中间件时请确保环境变量中有 `LEANCLOUD_` 系列的环境变量，即需要运行在云引擎上或用 `lean up` 启动。\n\n### 获取 GraphQLSchema\n\nleancloud-graphql 默认导出了一个构建 GraphQLSchema 的函数：\n\n```javascript\nvar buildSchema = require('leancloud-graphql');\nvar {printSchema} = require('graphql');\n\nbuildSchema({\n  appId: process.env.LEANCLOUD_APP_ID,\n  appKey: process.env.LEANCLOUD_APP_KEY,\n  masterKey: process.env.LEANCLOUD_APP_MASTER_KEY\n}).then( schema =\u003e {\n  console.log(printSchema(schema));\n});\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleancloud%2Fleancloud-graphql","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fleancloud%2Fleancloud-graphql","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleancloud%2Fleancloud-graphql/lists"}