翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。
GraphQL タイプ
GraphQL は、さまざまなタイプをサポートします。前のセクションで見たように、タイプはデータの形状や動作を定義します。これらは GraphQL スキーマの基本的な構成要素です。
タイプは入力と出力に分類できます。入力は特殊なオブジェクトタイプ (Query、Mutation など) の引数として渡すことができるタイプですが、出力タイプはデータの保存と返しにのみ使用されます。タイプとその分類のリストは以下のとおりです。
                
                
                
                
                
                
            - 
                  オブジェクト: オブジェクトにはエンティティを説明するフィールドが含まれます。例えば、book、authorName、publishingYearなどの特性を記述するフィールドを持つオブジェクトのようなものが考えられます。これらは厳密には出力タイプです。
 
- 
                  スカラー: これらは int や string などのプリミティブ型です。通常はフィールドに割り当てられます。authorNameフィールドを例にとると、「John Smith」のような名前を格納するStringスカラーを割り当てることができます。スカラーは入力タイプでも出力タイプでもかまいません。
 
- 
                  入力: 入力では、フィールドグループを引数として渡すことができます。オブジェクトとよく似た構造ですが、特別なオブジェクトに引数として渡すことができます。入力を使うと、スカラー、列挙型、その他の入力をスコープ内で定義できます。入力は入力タイプにしかなりません。 
- 
                  特殊オブジェクト: 特殊オブジェクトは状態を変更する操作を実行し、サービスの面倒な作業の大部分を行います。特殊なオブジェクトタイプには、クエリ、ミューテーション、サブスクリプションの 3 種類があります。通常、クエリはデータを取得し、ミューテーションはデータを操作し、サブスクリプションはクライアントとサーバー間の双方向接続を開いて維持し、常時通信を行います。特殊オブジェクトは、その機能上、入力でも出力でもありません。 
- 
                  列挙型: 列挙型はあらかじめ定義された有効な値のリストです。列挙型を呼び出す場合、その値はそのスコープで定義されている値のみになります。例えば、交通信号のリストを表すという trafficLightsがある場合、それにはredLightやgreenLightなどの値が含まれることがありますが、purpleLightにはなり得ません。実際の信号機には信号の数が限られているため、列挙型を使用して信号を定義し、trafficLight参照時にそれらだけが有効な値になるように強制できます。列挙型は入力型でも出力型でもかまいません。
 
- 
                  ユニオン/インターフェース: ユニオンを使うと、クライアントからリクエストされたデータに応じて 1 つ以上のものをリクエストで返すことができます。例えば、titleフィールドのあるBook型とnameフィールドのあるAuthor型がある場合、両方の型を結合することができます。クライアントが「ジュリアス・シーザー」というフレーズをデータベースから検索したい場合、ユニオンはジュリアス・シーザー (ウィリアム・シェイクスピアの戯曲) をBooktitleから、ジュリアス・シーザー(『コメンタリー・デ・ベロ・ガリコ』の作者) をAuthornameから返すことができます。ユニオンは出力タイプとしてのみ使用できます。
 インターフェースは、オブジェクトが実装しなければならないフィールドのセットです。これは、Java などのプログラミング言語のインターフェースに少し似ていますが、インターフェースで定義されたフィールドを実装する必要があります。例えば、Booktitleフィールドを含むというインターフェースを作成するとします。後で、Bookを実装したものNovelという型を作成したとします。Novelにはtitleフィールドを含める必要があります。ただし、Novelには、pageCountまたはISBNのような、インターフェイスにない他のフィールドも含めることができます。インターフェースは出力タイプにしかなれません。
 
 以下のセクションでは、各タイプが GraphQL でどのように機能するかを説明します。
               オブジェクト
               GraphQL オブジェクトは、プロダクションコードでよく使われるタイプです。GraphQL では、オブジェクトは異なるフィールドの集まりであり (他の言語の変数と同様)、各フィールドは値を保持できる型 (通常はスカラーまたは別のオブジェクト) によって定義されます。オブジェクトは、サービス実装から取得/操作できるデータの単位です。
               オブジェクトタイプは Type キーワードを使用して宣言されます。スキーマの例を少し変更してみましょう。
               type Person {
  id: ID!
  name: String
  age: Int
  occupation: Occupation
}
type Occupation {
  title: String
}
               ここでのオブジェクトタイプは Person と Occupation です。各オブジェクトには独自のフィールドと独自のタイプがあります。GraphQL の特徴の 1 つは、フィールドを他のタイプに設定できることです。Person の occupation フィールドには Occupation オブジェクトタイプが含まれていることがわかります。GraphQL はデータを記述するだけで、サービスの実装は記述していないため、この関連付けを行うことができます。
             
               スカラー
               スカラーは基本的に、値を保持するプリミティブ型です。には AWS AppSync、デフォルトの GraphQL スカラーとスカラーという 2 AWS AppSync 種類のスカラーがあります。スカラーは通常、オブジェクトタイプ内のフィールド値を格納するために使用されます。GraphQL のデフォルトタイプには Int、Float、String、Boolean、ID が含まれます。前の例をもう一度使ってみましょう。
               type Person { 
  id: ID!
  name: String
  age: Int
  occupation: Occupation
}
type Occupation {
  title: String
}
               name および title フィールドを除くと、どちらも String スカラーになります。Name は "John Smith" のような文字列値を返すことができ、タイトルは "firefighter" のようなものを返すことができます。一部の GraphQL 実装では、Scalar キーワードを使用してタイプの動作を実装するカスタムスカラーもサポートしています。ただし、 AWS AppSync は現時点ではカスタムスカラーをサポートしていません。スカラーのリストについては、「AWS AppSyncのスカラータイプ」を参照してください。
             
               
               入力型と出力型の概念により、引数を渡すときには一定の制限があります。一般的に渡す必要がある型、特にオブジェクトには制限があります。入力タイプを使用すると、このルールを回避できます。入力は、スカラー、列挙型、その他の入力タイプを含むタイプです。
               入力は input キーワードを使用して定義されます。
               type Person { 
  id: ID!
  name: String
  age: Int
  occupation: Occupation
}
type Occupation {
  title: String
}
input personInput { 
  id: ID!
  name: String
  age: Int
  occupation: occupationInput
}
input occupationInput {
  title: String
}
               ご覧のとおり、元の型を模倣した入力を別々に設定できます。これらの入力は、次のようなフィールド操作でよく使用されます。
               type Person { 
  id: ID!
  name: String
  age: Int
  occupation: Occupation
}
type Occupation {
  title: String
}
input occupationInput {
  title: String
}
type Mutation {
  addPerson(id: ID!, name: String, age: Int, occupation: occupationInput): Person
}
               まだ Occupation の代わりに occupationInput を渡して Person を作成することに注意してください。
               これは入力の 1 つのシナリオに過ぎません。必ずしもオブジェクトを 1:1 でコピーする必要はありませんし、プロダクションコードでは、このような方法を使用することはほとんどありません。引数として入力する必要があるものだけを定義して、GraphQL スキーマを活用するとよいでしょう。
               また、同じ入力を複数の操作で使用することもできますが、これはお勧めしません。スキーマの要件が変更された場合に備えて、各操作には入力の固有のコピーが含まれているのが理想的です。
             
               特殊なオブジェクト
               GraphQL は、スキーマがデータを取得/操作する方法に関するビジネスロジックの一部を定義する特別なオブジェクト用にいくつかのキーワードを予約しています。スキーマには、これらのキーワードがそれぞれ 1 つしか存在できません。これらは、クライアントが GraphQL サービスに対して実行するすべての要求されたデータのエントリポイントとして機能します。
               特別なオブジェクトも type キーワードを使って定義されます。通常のオブジェクトタイプとは使い方が異なりますが、実装は非常に似ています。
               
                  - Queries
- 
                        クエリは、読み取り専用のフェッチを実行してソースからデータを取得するという点で GETオペレーションとよく似ています。GraphQL では、Queryがサーバーに対してリクエストを行うクライアントのすべてのエントリポイントを定義します。GraphQL の実装にはQueryが必ずあります。
 前のスキーマの例で使用した Queryと変更されたオブジェクトタイプは次のとおりです。
 type Person { 
  id: ID!
  name: String
  age: Int
  occupation: Occupation
}
type Occupation {
  title: String
}
type Query {                                   
  people: [Person]
}
 Queryには、データソースかPersonインスタンスのリストを返すpeopleというフィールドがあります。アプリケーションの動作を変更する必要があり、今度は別の目的でOccupationインスタンスのみのリストを返す必要があるとしましょう。これをクエリに追加するだけで済みます。
 type Query {                                   
  people: [Person]
  occupations: [Occupation]
}
 GraphQL では、クエリをリクエストの単一ソースとして扱うことができます。お分かりのように、これは、異なるエンドポイントを使用して同じこと (.../api/1/peopleと.../api/1/occupations) を実現する RESTful な実装よりもずっと簡単になる可能性があります。
 このクエリ用のリゾルバー実装があると仮定すると、実際のクエリを実行できるようになります。Queryタイプは存在しますが、アプリケーションのコードで実行するには明示的に呼び出す必要があります。これはqueryキーワードを使用して行うことができます。
 query getItems {
   people {
      name
   }
   occupations {
      title
   }
}
 ご覧のとおり、このクエリは getItemsと呼ばれ、people(Personオブジェクトのリスト) とoccupations(Occupationオブジェクトのリスト) を返します。peopleでは、それぞれのPersonのnameフィールドのみを返し、それぞれのOccupationのtitleフィールドを返しています。また、レスポンスは次のようになります。
 {
  "data": {
    "people": [
      {
        "name": "John Smith"
      },
      {
        "name": "Andrew Miller"
      },
      .
      .
      .
    ],
    "occupations": [
      {
        "title": "Firefighter"
      },
      {
        "title": "Bookkeeper"
      },
      .
      .
      .
    ]
  }
}
 レスポンス例は、データがクエリの形状に従っていることを示している。取得された各エントリは、フィールドの範囲内で一覧表示されます。peopleとoccupationsをそれぞれを個別のリストとして返しています。便利ですが、ユーザーの名前と職業のリストを返すようにクエリを変更したほうが便利かもしれません。
 query getItems {
   people {
      name   
      occupation {
        title
      }
}
 PersonタイプにはOccupationタイプのoccupationフィールドが含まれているので、これは合法的な変更です。peopleの範囲内にリストされている場合は、titleによって関連するOccupationとともにそれぞれのPersonのnameを返すことになります。また、レスポンスは次のようになります。
 }
  "data": {
    "people": [
      {
        "name": "John Smith",
        "occupation": {
          "title": "Firefighter"
        }
      },
      {
        "name": "Andrew Miller",
        "occupation": {
          "title": "Bookkeeper"
        }
      },
      .
      .
      .
    ]
  }
}
 
- Mutations
- 
                        ミューテーションは、PUTやPOSTのような状態を変える操作に似ています。書き込み操作を実行してソース内のデータを変更し、レスポンスを取得します。データ変更リクエストのエントリポイントを定義します。クエリとは異なり、ミューテーションはプロジェクトのニーズに応じてスキーマに含まれる場合と含まれない場合があります。スキーマの例からのミューテーションは次のとおりです。
 type Mutation {
  addPerson(id: ID!, name: String, age: Int): Person
}
 addPersonフィールドは、Personをデータソースに追加する 1 つのエントリポイントを表します。addPersonはフィールド名、id、name、ageはパラメータ、Personは戻り型です。Personタイプを振り返ってみます。
 type Person { 
  id: ID!
  name: String
  age: Int
  occupation: Occupation
}
 occupationフィールドを追加しました。ただし、オブジェクトは引数として渡すことができないため、このフィールドを直接Occupationに設定することはできません。オブジェクトは厳密には出力タイプです。代わりに、同じフィールドを含む入力を引数として渡す必要があります。
 input occupationInput {
  title: String
}
  新しいインスタンスを作るときに、パラメータとして含めるように簡単に addPersonを更新することもできます。
 type Mutation {
  addPerson(id: ID!, name: String, age: Int, occupation: occupationInput): Person
}
 更新されたスキーマは次のとおりです。 type Person { 
  id: ID!
  name: String
  age: Int
  occupation: Occupation
}
type Occupation {
  title: String
}
input occupationInput {
  title: String
}
type Mutation {
  addPerson(id: ID!, name: String, age: Int, occupation: occupationInput): Person
}
 元のオブジェクトの代わりに、occupationがoccupationInputからtitleフィールドに渡すことでPersonの作成が完了することに注意してください。addPersonのリゾルバーの実装があると仮定すると、実際のミューテーションを実行できるようになりました。Mutation型は存在しますが、アプリケーションのコードで実行するには明示的に呼び出す必要があります。これはmutationキーワードを使用して行うことができます。
 mutation createPerson {
  addPerson(id: ID!, name: String, age: Int, occupation: occupationInput) {
    name
    age
    occupation {
      title
    }
  }
}
 このミューテーションは createPersonと呼ばれ、addPersonがオペレーションです。新しいPersonを作成するにはid、name、age、occupationの引数を入力します。addPersonの範囲には、name、ageなどの他のフィールドもあります。これはあなたのレスポンスです。これらはaddPersonオペレーションが完了した後に返されるフィールドです。この例の最後の部分は次のとおりです。
 mutation createPerson {
  addPerson(id: "1", name: "Steve Powers", age: "50", occupation: "Miner") {
    id
    name
    age
    occupation {
      title
    }
  }
}
 このミューテーションを使用すると、結果は以下のようになります。 {
  "data": {
    "addPerson": {
      "id": "1",
      "name": "Steve Powers",
      "age": "50",
      "occupation": {
        "title": "Miner"
      }
    }
  }
}
 ご覧のとおり、レスポンスはリクエストした値を、ミューテーションで定義したのと同じ形式で返しました。混乱を減らし、今後さらにクエリが必要にならないように、変更されたすべての値を返すことをお勧めします。ミューテーションを使うと、複数の操作をその範囲に含めることができます。これらはミューテーションにリストされている順序で順番に実行されます。例えば、データソースに役職を追加する addOccupationという操作をもう 1 つ作成した場合、これをaddPersonの後にミューテーションで呼び出すことができます。addPersonが最初に処理され、その後にaddOccupationが処理されます。
 
- Subscriptions
- 
                        サブスクリプションは WebSockets を使用して、サーバーとクライアント間の永続的な双方向接続を開きます。通常、クライアントはサーバーをサブスクライブまたはリッスンします。サーバーがサーバー側で変更を加えたり、イベントを実行したりするたびに、サブスクライブしているクライアントは更新を受け取ります。このタイプのプロトコルは、複数のクライアントがサブスクライブしていて、サーバーや他のクライアントで発生した変更について通知を受ける必要がある場合に役立ちます。例えば、サブスクリプションを使用してソーシャルメディアフィードを更新できます。ユーザー A とユーザー B の 2 人のユーザーが、どちらもダイレクトメッセージを受信するたびに自動通知更新をサブスクライブしている場合があります。クライアント A のユーザー A は、クライアント B のユーザー B にダイレクトメッセージを送信できます。ユーザー A のクライアントはダイレクトメッセージを送信し、サーバーによって処理されます。その後、サーバーはユーザー B のアカウントにダイレクトメッセージを送信し、クライアント B には自動通知を送信します。 スキーマの例に追加できる Subscriptionの例を以下に示します。
 type Subscription {                                   
  personAdded: Person
}
 personAddedフィールドは、データソースに新しいPersonが追加されるたびに、サブスクライブしているクライアントにメッセージを送信します。personAddedのリゾルバーの実装があると仮定すると、サブスクリプションを使用できるようになりました。Subscription型は存在しますが、アプリケーションのコード内で実行するには明示的に呼び出す必要があります。これはsubscriptionキーワードを使用して行うことができます。
 subscription personAddedOperation {
  personAdded {
    id
    name
  }
}
 サブスクリプションは personAddedOperationと呼ばれ、オペレーションはpersonAddedです。personAddedは新しいPersonインスタンスのidおよびnameフィールドを返します。ミューテーションの例を見てみると、以下の操作を使用してPersonを追加しました。
 addPerson(id: "1", name: "Steve Powers", age: "50", occupation: "Miner")
 クライアントが新しく追加された Personへのアップデートを購読していた場合、addPerson実行後に以下のように表示されるかもしれません。
 {
  "data": {
    "personAdded": {
      "id": "1",
      "name": "Steve Powers"
    }
  }
}
 以下は、サブスクリプションが提供するものの概要です。 サブスクリプションは、クライアントとサーバーが迅速で安定したアップデートを受信できるようにする双方向のチャネルです。通常、標準化された安全な接続を実現する WebSocket プロトコルを使用します。 サブスクリプションは、接続設定のオーバーヘッドを減らすという点で機敏です。一度サブスクライブすると、クライアントはそのサブスクリプションで長期間稼働し続けることができます。通常、開発者がサブスクリプションの有効期間を調整したり、要求される情報を設定したりできるようにすることで、コンピューティングリソースを効率的に使用します。 一般に、サブスクリプションを使用すると、クライアントは一度に複数のサブスクリプションを作成できます。サブスクリプションは AWS AppSync、 AWS AppSync サービスからリアルタイムの更新を受け取るためにのみ使用されます。クエリやミューテーションの実行には使用できません。 サブスクリプションに代わる主な方法はポーリングです。ポーリングでは、設定した間隔でクエリを送信してデータを要求します。このプロセスは通常、サブスクリプションほど効率的ではなく、クライアントとバックエンドの両方に大きな負担をかけます。 
スキーマの例では言及されていなかったことの 1 つは、特殊なオブジェクト型も schema ルートで定義しなければならないという事実です。したがって、スキーマを にエクスポートすると AWS AppSync、次のようになります。
               
                  - schema.graphql
- 
                        schema {
  query: Query
  mutation: Mutation
  subscription: Subscription
}
.
.
.
type Query {                                   
  # code goes here
}
type Mutation {                                   
  # code goes here
}
type Subscription {                                   
  # code goes here
}
 
列挙型
               列挙型は、タイプやフィールドが持つ可能性のある有効な引数を制限する特殊なスカラーです。つまり、スキーマで列挙型が定義されると、それに関連するタイプまたはフィールドは列挙型内の値に限定されます。列挙型は文字列スカラーとしてシリアル化されます。プログラミング言語が異なれば、GraphQL 列挙型の処理も異なる場合があることに注意してください。例えば、JavaScript はネイティブの列挙型をサポートしていないため、代わりに列挙値を int 値にマップできます。
               列挙型は enum キーワードを使用して定義されます。例を示します。
               enum trafficSignals {
  solidRed
  solidYellow
  solidGreen
  greenArrowLeft
  ...
}
               trafficLights 列挙型を呼び出すとき、引数に指定できるのは solidRed、solidYellow、solidGreen などのみです。列挙型を使うのは、はっきりしているが選択肢の数が限られているものを表すのに使うのが一般的です。
             
               ユニオン/インターフェース
               GraphQL の「Interface と Union」を参照してください。