目次
设置 GraphQL 服务器
使用 GraphQL 进行临时查询
GraphQL 突变
高级主题
订阅
验证
架构自省
结论

GraphQL を理解する: GraphQL の概要

Aug 28, 2023 pm 10:05 PM

###############概要###

GraphQL は、アドホック クエリと操作のためのエキサイティングな新しい API です。非常に柔軟性があり、多くの利点があります。これは、グラフやツリー形式で整理されたデータを公開するのに特に適しています。 Facebook は GraphQL を 2012 年に開発し、2015 年にオープンソース化しました。 理解 GraphQL:GraphQL 简介

これは急速に成長し、最も注目されているテクノロジーの 1 つになりました。多くの革新的な企業が本番環境で GraphQL を採用し、使用しています。このチュートリアルでは次のことを学びます:

GraphQLの原理

RESTとの比較

アーキテクチャを設計する方法
  • GraphQLサーバーのセットアップ方法
  • クエリの実装方法と変更方法
  • その他の高度なテーマ
  • GraphQL のハイライトは何ですか?
  • GraphQL が最大限に発揮されるのは、データが階層またはグラフに編成されており、フロントエンドがその階層またはグラフのさまざまなサブセットにアクセスしたい場合です。 NBA を公開するアプリケーションを考えてみましょう。チーム、選手、コーチ、チャンピオンシップ、そしてそれぞれに関する大量の情報があります。以下にいくつかのサンプルクエリを示します:
現在ゴールデンステート ウォリアーズの名簿に載っている選手の名前は何ですか?

ワシントン・ウィザーズのスターティングプレイヤーの名前、身長、年齢は何ですか?

現役で最も多くのチャンピオンシップを獲得したコーチは誰ですか?
  • コーチは何年にどのチームで優勝しましたか?
  • 最も多くの MVP 賞を受賞した選手は誰ですか?
  • このような質問は何百件もできるでしょう。これらすべてのクエリをフロントエンドに公開し、ユーザーや製品マネージャーが新しいエキサイティングなクエリ コンテンツを思いついたときに、新しいクエリ タイプで API を簡単に拡張できる API を設計する必要があることを想像してみてください。
  • これは些細な問題ではありません。 GraphQL はまさにこの問題を解決するために設計されており、すぐにわかるように、単一の API エンドポイントで膨大な機能を提供します。
  • GraphQL と REST

GraphQL の詳細に入る前に、現在最も人気のあるタイプの Web API である REST と比較してみましょう。

REST はリソース指向モデルに従います。リソースが選手、コーチ、チームである場合、次のようなエンドポイントがある可能性があります:

###/プレーヤー###

/プレイヤー/

###/コーチ###

/コーチ/

    ###/チーム### ###/チーム/######
  • 通常、ID のないエンドポイントは ID のリストのみを返しますが、ID を持つエンドポイントはリソースに関する完全な情報を返します。もちろん、他の方法で API を設計することもできます (たとえば、/players エンドポイントは各プレーヤーの名前または各プレーヤーに関するすべての情報を返すこともできます)。
  • 動的環境では、このアプローチの問題は、アンダーフェッチ (例: ID のみを取得し、さらに情報が必要な場合) またはオーバーフェッチ (例: 名前のみが必要な場合) のいずれかになることです。
  • これらは難しい質問です。十分な ID が取得できない場合、100 個の ID を取得した場合、各プレーヤーの情報を取得するために 100 回の個別の API 呼び出しを行う必要があります。オーバーフェッチすると、必要のない大量のデータの準備と送信に多くのバックエンド時間とネットワーク帯域幅が浪費されます。
  • REST を介してこの問題を解決するには、複数の方法があります。多くのカスタム エンドポイントを設計して、それぞれが必要なデータを正確に返すことができます。このソリューションはスケーラブルではありません。 API の一貫性を保つのは困難です。それを進化させるのは難しいです。文書化して使用するのは難しいです。これらのカスタム エンドポイント間に多くの重複がある場合、それを維持するのは困難です。
  • 次の追加のエンドポイントを検討してください:
  • ###/プレーヤの名前###
  • /players/names_and_championships
  • /チーム/スタート

別のアプローチは、少数の共通エンドポイントを保持し、多数のクエリ パラメーターを提供することです。このソリューションは複数のエンドポイントの問題を回避しますが、REST モデルの原則に違反するため、一貫して開発および保守することが困難です。

GraphQL はこのアプローチを限界まで行っていると言えるでしょう。明示的に定義されたリソースは考慮されず、ドメイン全体のサブグラフが考慮されます。

GraphQL型システム

GraphQL は、型とプロパティで構成される型システムを使用してドメインをモデル化します。すべてのプロパティにはタイプがあります。プロパティの型は、ID、String、Boolean など、GraphQL によって提供される基本型の 1 つであることも、ユーザー定義の型であることもできます。グラフのノードはユーザー定義タイプであり、エッジはユーザー定義タイプの属性です。

例えば、「プレイヤー」タイプに「チーム」タイプの「チーム」属性がある場合、各プレイヤーノードからチームノードへのエッジがあることを意味します。すべての型は、GraphQL ドメイン オブジェクト モデルを記述するスキーマで定義されます。
  • これは、NBA ドメインの非常に簡素化されたアーキテクチャです。プレーヤーには名前、最も関係のあるチーム (はい、プレーヤーがあるチームから別のチームに移ることがあるのは知っています)、およびプレーヤーが獲得したチャンピオンシップの数があります。
  • チームには名前、名簿、およびチームが獲得したチャンピオンシップの数があります。
  • リーリー
  • 事前定義されたエントリ ポイントもあります。それらはクエリ、変更、サブスクライブです。フロントエンドはエントリ ポイントを通じてバックエンドと通信し、必要に応じてカスタマイズできます。
これは、すべてのプレーヤーを返す単純なクエリです:

type Query {
    allPlayers: [Player!]!
}
ログイン後にコピー

感叹号表示该值不能为空。对于 allPlayers 查询,它可以返回空列表,但不能返回 null。另外,这意味着列表中不能有空玩家(因为它包含 Player!)。

设置 GraphQL 服务器

这是一个基于 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 来测试服务器。我强烈推荐它来尝试不同的查询。

使用 GraphQL 进行临时查询

万事俱备。让我们导航到 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 个总冠军。凯文·杜兰特在勇士队只赢得了一次总冠军,而勇士队总共赢得了五次总冠军。

GraphQL 突变

魔术师约翰逊无疑是场上的魔术师。但如果没有他的朋友卡里姆·阿卜杜勒·贾巴尔,他不可能做到这一点。让我们将 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 サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

フロントエンドのサーマルペーパーレシートのために文字化けしたコード印刷に遭遇した場合はどうすればよいですか? フロントエンドのサーマルペーパーレシートのために文字化けしたコード印刷に遭遇した場合はどうすればよいですか? Apr 04, 2025 pm 02:42 PM

フロントエンドのサーマルペーパーチケット印刷のためのよくある質問とソリューションフロントエンド開発におけるチケット印刷は、一般的な要件です。しかし、多くの開発者が実装しています...

誰がより多くのPythonまたはJavaScriptを支払われますか? 誰がより多くのPythonまたはJavaScriptを支払われますか? Apr 04, 2025 am 12:09 AM

スキルや業界のニーズに応じて、PythonおよびJavaScript開発者には絶対的な給与はありません。 1. Pythonは、データサイエンスと機械学習でさらに支払われる場合があります。 2。JavaScriptは、フロントエンドとフルスタックの開発に大きな需要があり、その給与もかなりです。 3。影響要因には、経験、地理的位置、会社の規模、特定のスキルが含まれます。

javascriptの分解:それが何をするのか、なぜそれが重要なのか javascriptの分解:それが何をするのか、なぜそれが重要なのか Apr 09, 2025 am 12:07 AM

JavaScriptは現代のWeb開発の基礎であり、その主な機能には、イベント駆動型のプログラミング、動的コンテンツ生成、非同期プログラミングが含まれます。 1)イベント駆動型プログラミングにより、Webページはユーザー操作に応じて動的に変更できます。 2)動的コンテンツ生成により、条件に応じてページコンテンツを調整できます。 3)非同期プログラミングにより、ユーザーインターフェイスがブロックされないようにします。 JavaScriptは、Webインタラクション、シングルページアプリケーション、サーバー側の開発で広く使用されており、ユーザーエクスペリエンスとクロスプラットフォーム開発の柔軟性を大幅に改善しています。

JavaScriptを使用して、同じIDを持つArray要素を1つのオブジェクトにマージする方法は? JavaScriptを使用して、同じIDを持つArray要素を1つのオブジェクトにマージする方法は? Apr 04, 2025 pm 05:09 PM

同じIDを持つ配列要素をJavaScriptの1つのオブジェクトにマージする方法は?データを処理するとき、私たちはしばしば同じIDを持つ必要性に遭遇します...

Shiseidoの公式Webサイトのように、視差スクロールと要素のアニメーション効果を実現する方法は?
または:
Shiseidoの公式Webサイトのようにスクロールするページを伴うアニメーション効果をどのように実現できますか? Shiseidoの公式Webサイトのように、視差スクロールと要素のアニメーション効果を実現する方法は? または: Shiseidoの公式Webサイトのようにスクロールするページを伴うアニメーション効果をどのように実現できますか? Apr 04, 2025 pm 05:36 PM

この記事の視差スクロールと要素のアニメーション効果の実現に関する議論では、Shiseidoの公式ウェブサイト(https://www.shisido.co.co.jp/sb/wonderland/)と同様の達成方法について説明します。

Console.log出力の違い結果:なぜ2つの呼び出しが異なるのですか? Console.log出力の違い結果:なぜ2つの呼び出しが異なるのですか? Apr 04, 2025 pm 05:12 PM

Console.log出力の違いの根本原因に関する詳細な議論。この記事では、Console.log関数の出力結果の違いをコードの一部で分析し、その背後にある理由を説明します。 �...

JavaScriptは学ぶのが難しいですか? JavaScriptは学ぶのが難しいですか? Apr 03, 2025 am 12:20 AM

JavaScriptを学ぶことは難しくありませんが、挑戦的です。 1)変数、データ型、関数などの基本概念を理解します。2)非同期プログラミングをマスターし、イベントループを通じて実装します。 3)DOM操作を使用し、非同期リクエストを処理することを約束します。 4)一般的な間違いを避け、デバッグテクニックを使用します。 5)パフォーマンスを最適化し、ベストプラクティスに従ってください。

PowerPointはJavaScriptを実行できますか? PowerPointはJavaScriptを実行できますか? Apr 01, 2025 pm 05:17 PM

JavaScriptはPowerPointで実行でき、外部JavaScriptファイルを呼び出したり、VBAを介してHTMLファイルを埋め込んだりすることで実装できます。 1. VBAを使用してJavaScriptファイルを呼び出すには、マクロを有効にし、VBAプログラミングの知識を持つ必要があります。 2。JavaScriptを含むHTMLファイルを埋め込みます。これは、シンプルで使いやすいが、セキュリティ制限の対象となります。利点には、拡張機能と柔軟性が含まれますが、欠点にはセキュリティ、互換性、複雑さが含まれます。実際には、セキュリティ、互換性、パフォーマンス、ユーザーエクスペリエンスに注意を払う必要があります。

See all articles