###############概要###
GraphQL は、アドホック クエリと操作のためのエキサイティングな新しい API です。非常に柔軟性があり、多くの利点があります。これは、グラフやツリー形式で整理されたデータを公開するのに特に適しています。 Facebook は GraphQL を 2012 年に開発し、2015 年にオープンソース化しました。
これは急速に成長し、最も注目されているテクノロジーの 1 つになりました。多くの革新的な企業が本番環境で GraphQL を採用し、使用しています。このチュートリアルでは次のことを学びます:
RESTとの比較
アーキテクチャを設計する方法
現役で最も多くのチャンピオンシップを獲得したコーチは誰ですか?
GraphQL の詳細に入る前に、現在最も人気のあるタイプの Web API である REST と比較してみましょう。
REST はリソース指向モデルに従います。リソースが選手、コーチ、チームである場合、次のようなエンドポイントがある可能性があります:
###/コーチ###
/コーチ/
別のアプローチは、少数の共通エンドポイントを保持し、多数のクエリ パラメーターを提供することです。このソリューションは複数のエンドポイントの問題を回避しますが、REST モデルの原則に違反するため、一貫して開発および保守することが困難です。
GraphQL はこのアプローチを限界まで行っていると言えるでしょう。明示的に定義されたリソースは考慮されず、ドメイン全体のサブグラフが考慮されます。
GraphQL型システム
GraphQL は、型とプロパティで構成される型システムを使用してドメインをモデル化します。すべてのプロパティにはタイプがあります。プロパティの型は、ID、String、Boolean など、GraphQL によって提供される基本型の 1 つであることも、ユーザー定義の型であることもできます。グラフのノードはユーザー定義タイプであり、エッジはユーザー定義タイプの属性です。
例えば、「プレイヤー」タイプに「チーム」タイプの「チーム」属性がある場合、各プレイヤーノードからチームノードへのエッジがあることを意味します。すべての型は、GraphQL ドメイン オブジェクト モデルを記述するスキーマで定義されます。
type Query { allPlayers: [Player!]! }
感叹号表示该值不能为空。对于 allPlayers
查询,它可以返回空列表,但不能返回 null。另外,这意味着列表中不能有空玩家(因为它包含 Player!)。
这是一个基于 Node-Express 的成熟 GraphQL 服务器。它有一个内存中的硬编码数据存储。通常,数据将位于数据库中或从其他服务获取。数据定义如下(如果您最喜欢的球队或球员未能入选,请提前致歉):
let data = { "allPlayers": { "1": { "id": "1", "name": "Stephen Curry", "championshipCount": 2, "teamId": "3" }, "2": { "id": "2", "name": "Michael Jordan", "championshipCount": 6, "teamId": "1" }, "3": { "id": "3", "name": "Scottie Pippen", "championshipCount": 6, "teamId": "1" }, "4": { "id": "4", "name": "Magic Johnson", "championshipCount": 5, "teamId": "2" }, "5": { "id": "5", "name": "Kobe Bryant", "championshipCount": 5, "teamId": "2" }, "6": { "id": "6", "name": "Kevin Durant", "championshipCount": 1, "teamId": "3" } }, "allTeams": { "1": { "id": "1", "name": "Chicago Bulls", "championshipCount": 6, "players": [] }, "2": { "id": "2", "name": "Los Angeles Lakers", "championshipCount": 16, "players": [] }, "3": { "id": "3", "name": "Golden State Warriors", "championshipCount": 5, "players": [] } } }
我使用的库是:
const express = require('express'); const graphqlHTTP = require('express-graphql'); const app = express(); const { buildSchema } = require('graphql'); const _ = require('lodash/core');
这是构建架构的代码。请注意,我向 allPlayers
根查询添加了几个变量。
schema = buildSchema(` type Player { id: ID name: String! championshipCount: Int! team: Team! } type Team { id: ID name: String! championshipCount: Int! players: [Player!]! } type Query { allPlayers(offset: Int = 0, limit: Int = -1): [Player!]! }`
关键部分来了:连接查询并实际提供数据。 rootValue
对象可能包含多个根。
这里,只有 allPlayers
。它从参数中提取偏移量和限制,对所有玩家数据进行切片,然后根据团队 ID 设置每个玩家的团队。这使得每个玩家都是一个嵌套对象。
rootValue = { allPlayers: (args) => { offset = args['offset'] limit = args['limit'] r = _.values(data["allPlayers"]).slice(offset) if (limit > -1) { r = r.slice(0, Math.min(limit, r.length)) } _.forEach(r, (x) => { data.allPlayers[x.id].team = data.allTeams[x.teamId] }) return r }, }
最后,这是 graphql
端点,传递架构和根值对象:
app.use('/graphql', graphqlHTTP({ schema: schema, rootValue: rootValue, graphiql: true })); app.listen(3000); module.exports = app;
将 graphiql
设置为 true
使我们能够使用出色的浏览器内 GraphQL IDE 来测试服务器。我强烈推荐它来尝试不同的查询。
万事俱备。让我们导航到 http://localhost:3000/graphql 并享受一些乐趣。
我们可以从简单的开始,只包含玩家姓名列表:
query justNames { allPlayers { name } } Output: { "data": { "allPlayers": [ { "name": "Stephen Curry" }, { "name": "Michael Jordan" }, { "name": "Scottie Pippen" }, { "name": "Magic Johnson" }, { "name": "Kobe Bryant" }, { "name": "Kevin Durant" } ] } }
好吧。我们这里有一些超级巨星。毫无疑问。让我们尝试一些更奇特的东西:从偏移量 4 开始,有 2 名玩家。对于每个球员,返回他们的名字和他们赢得的冠军数量以及他们的球队名称和球队赢得的冠军数量。
query twoPlayers { allPlayers(offset: 4, limit: 2) { name championshipCount team { name championshipCount } } } Output: { "data": { "allPlayers": [ { "name": "Kobe Bryant", "championshipCount": 5, "team": { "name": "Los Angeles Lakers", "championshipCount": 16 } }, { "name": "Kevin Durant", "championshipCount": 1, "team": { "name": "Golden State Warriors", "championshipCount": 5 } } ] } }
所以科比·布莱恩特随湖人队赢得了 5 个总冠军,湖人队总共获得了 16 个总冠军。凯文·杜兰特在勇士队只赢得了一次总冠军,而勇士队总共赢得了五次总冠军。
魔术师约翰逊无疑是场上的魔术师。但如果没有他的朋友卡里姆·阿卜杜勒·贾巴尔,他不可能做到这一点。让我们将 Kareem 添加到我们的数据库中。我们可以定义 GraphQL 突变来执行从图表中添加、更新和删除数据等操作。
首先,让我们向架构添加突变类型。它看起来有点像函数签名:
type Mutation { createPlayer(name: String, championshipCount: Int, teamId: String): Player }
然后,我们需要实现它并将其添加到根值中。该实现只是获取查询提供的参数并将一个新对象添加到 data['allPlayers']
。它还确保正确设置团队。最后,它返回新的玩家。
createPlayer: (args) => { id = (_.values(data['allPlayers']).length + 1).toString() args['id'] = id args['team'] = data['allTeams'][args['teamId']] data['allPlayers'][id] = args return data['allPlayers'][id] },
要实际添加 Kareem,我们可以调用突变并查询返回的玩家:
mutation addKareem { createPlayer(name: "Kareem Abdul-Jabbar", championshipCount: 6, teamId: "2") { name championshipCount team { name } } } Output: { "data": { "createPlayer": { "name": "Kareem Abdul-Jabbar", "championshipCount": 6, "team": { "name": "Los Angeles Lakers" } } } }
这是一个关于突变的黑暗小秘密......它们实际上与查询完全相同。您可以在查询中修改数据,并且可能只从突变中返回数据。 GraphQL 不会查看您的代码。查询和突变都可以接受参数并返回数据。它更像是语法糖,可以使您的架构更具人类可读性。
订阅是 GraphQL 的另一个杀手级功能。通过订阅,客户端可以订阅每当服务器状态发生变化时就会触发的事件。订阅是后来引入的,不同的框架以不同的方式实现。
GraphQL 将验证针对架构的每个查询或突变。当输入数据具有复杂形状时,这是一个巨大的胜利。您不必编写烦人且脆弱的验证代码。 GraphQL 将为您处理好它。
您可以检查和查询当前架构本身。这为您提供了动态发现架构的元能力。下面是一个返回所有类型名称及其描述的查询:
query q { __schema { types { name description } }
GraphQL 是一项令人兴奋的新 API 技术,与 REST API 相比,它具有许多优势。它背后有一个充满活力的社区,更不用说Facebook了。我预测它将很快成为前端的主要内容。试一试。你会喜欢的。
以上がGraphQL を理解する: GraphQL の概要の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。