

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# GraphQL タイプのリファレンス
<a name="type-reference"></a>

GraphQL のスカラー型は、GraphQL スキーマのプリミティブリーフ値を表します。これらは、単一の値を解決する最も基本的なデータ型です。オブジェクトタイプとは異なり、スカラー型にサブフィールドを含めることはできません。GraphQL にはデフォルトのスカラー型のセットが付属しています。
+ **Int**: 符号付き 32 ビット整数 
+ **Float**: 符号付き倍精度浮動小数点値 
+ **String**: UTF-8 文字シーケンス 
+ **Boolean**: true または false の値
+ **ID**: オブジェクトの再取得やキャッシュのキーとしてよく使用される一意の識別子

これらのスカラー型は、スキーマ内のより複雑なタイプの構成要素として機能します。これらは、シンプルで単一の値を含むフィールドを定義するために使用されます。これらの組み込みスカラーに加えて、AWS AppSync はさまざまなユースケース用の追加のスカラーを提供します。

GraphQL の Interface と Union は、柔軟で拡張可能なスキーマ設計を可能にする抽象型です。これらは、関連するタイプをグループ化し、多相型クエリを有効にするメカニズムを提供します。GraphQL の Interface は、Interface を実装するためにタイプに含める必要があるフィールドのセットを定義する抽象型です。これは、実装タイプが持つ必要があるフィールドの共通セットを指定することで、オブジェクトの契約として機能します。Interface は、いくつかのフィールドを保証しながら、複数の異なる型を持つオブジェクトまたはフィールドを返す場合に便利です。対照的に、GraphQL の Union は、いくつかのオブジェクトタイプのいずれかになる可能性のあるタイプを表しますが、それらのタイプ間で一般的なフィールドは定義しません。Union は、複数のタイプのフィールドを返す必要がある場合に役立ちます。これらのタイプは、必ずしも共通のフィールドを共有しているわけではありません。Interface と Union の両方は、フィールドが異なるタイプのデータを返す可能性があるシナリオで特に有用であり、クライアントは返されたタイプに基づいて特定のフィールドをクエリできます。

このセクションは、スキーマタイプのリファレンスとして使用されます。

**トピック**
+ [GraphQL のスカラー型](https://docs.aws.amazon.com/appsync/latest/devguide/scalars.html)
+ [GraphQL の Interface と Union](https://docs.aws.amazon.com/appsync/latest/devguide/interfaces-and-unions.html)

# GraphQL のスカラー型
<a name="scalars"></a>

 GraphQL オブジェクトタイプには名前とフィールドがあり、これらのフィールドにはサブフィールドを使用できます。最終的には、オブジェクトタイプのフィールドを、クエリの各要素を表す*スカラー*型に解決する必要があります。オブジェクトタイプとスカラーの詳細については、GraphQL ウェブサイトの「[スキーマとタイプ](https://graphql.org/learn/schema/)」を参照してください。

GraphQL スカラーのデフォルトセットに加えて、AWS AppSync では *AWS* プレフィックスで始まる**サービス定義**のスカラーも使用できます。AWS AppSync では**ユーザー定義** (カスタム) スカラーの作成はサポートしていません デフォルトまたは *AWS* スカラーのいずれかを使用する必要があります。

カスタムオブジェクトタイプのプレフィックスとして *AWS* を使用することはできません。

次のセクションはスキーマタイピングのリファレンスです。

## デフォルトスカラー
<a name="graph-ql-base-scalars"></a>

 GraphQL は、次のデフォルトスカラー を定義します。

### デフォルトのスカラーのリスト
<a name="graph-ql-base-scalars-list"></a>

`ID`  
オブジェクトの一意な識別子。このスカラーは、`String` のようにシリアル化されますが、人間が読めることは意図していません。

`String`  
UTF-8 文字シーケンス。

`Int`  
-(231) と 231-1の間の整数値。

`Float`  
IEEE 754 浮動小数点値

`Boolean`  
ブール値 (`true` または `false`)。

## AWS AppSync スカラー
<a name="graph-ql-aws-appsync-scalars"></a>

AWS AppSync は次のスカラーを定義します。

### AWS AppSync スカラーリスト
<a name="graph-ql-aws-appsync-scalars-list"></a>

`AWSDate`  
拡張機能[ISO 8601 の日付](https://en.wikipedia.org/wiki/ISO_8601#Calendar_dates)形式の文字列`YYYY-MM-DD`。

`AWSTime`  
拡張機能[ISO 8601](https://en.wikipedia.org/wiki/ISO_8601#Times)形式の文字列`hh:mm:ss.sss`。

`AWSDateTime`  
拡張機能[ISO 8601 の日時番号](https://en.wikipedia.org/wiki/ISO_8601#Combined_date_and_time_representations)形式の文字列`YYYY-MM-DDThh:mm:ss.sssZ`。

**注記**  
`AWSDate`、`AWSTime`、および `AWSDateTime` スカラーは、必要に応じて[タイムゾーンオフセット](https://en.wikipedia.org/wiki/ISO_8601#Time_zone_designators)に含むことができます。例えば、値 `1970-01-01Z`、`1970-01-01-07:00`、 および `1970-01-01+05:30` はすべて `AWSDate` に有効です。タイムゾーンのオフセットは、`Z`(UTC)、または時間と分 (およびオプションで秒) のオフセットのいずれかである必要があります。例えば、`±hh:mm:ss`。ISO 8601 標準には含まれていませんが、タイムゾーンオフセットの第 2 フィールドは有効と見なされます。

`AWSTimestamp`  
`1970-01-01-T00:00Z` 前後の秒数を表す整数値。

`AWSEmail`  
[RFC 822](https://tools.ietf.org/html/rfc822)で定義される `local-part@domain-part` 形式のメールアドレス。

`AWSJSON`  
JSON 文字列。すべての有効な JSON コンストラクトは、リテラルな入力文字列としてではなく、マップ、リスト、スカラー値として自動的に解析され、リゾルバーマッピングテンプレートにロードされます。引用符で囲まれていない文字列、または無効な JSON は GraphQL 検証エラーになります。

`AWSPhone`  
電話番号 この値は文字列として保存されます。電話番号には、スペースまたはハイフンのいずれかを指定して、数字グループを区切ることができます。国番号のない電話番号は、[北米番号計画 (NANP)](https://en.wikipedia.org/wiki/North_American_Numbering_Plan)に紐づいている米国/北米の電話番号とみなされます。

`AWSURL`  
[RFC 1738](https://tools.ietf.org/html/rfc1738)によって定義される URL。例えば、`https://www.amazon.com/dp/B000NZW3KC/`、`mailto:example@example.com` です。URL にはスキーマ (`http`,`mailto`) および 2 つのフォワードスラッシュ (`//`) をパス部分に入れる必要があります。

`AWSIPAddress`  
有効な IPv4 または IPv6 アドレス。IPv4 アドレスはクアッドドット表記で想定されます (`123.12.34.56`)。IPv6 アドレスは、角カッコで囲まれていないコロン区切りの形式で想定されます (`1a2b:3c4b::1234:4567`)。オプションの CIDR サフィックス (`123.45.67.89/16`) を含めることで、サブネットマスクを示すことができます。

## スキーマの使用例
<a name="example-schema-usage"></a>

以下に示す GraphQL スキーマの例は、すべてのカスタムのスカラーを「オブジェクト」として使用するとともに、基本的なput、get、および list 操作にリゾルバーリクエストとレスポンステンプレートを使用しています。最後に、 クエリとミューテーションを実行するときに、この をどのように 使用できるかの例を示します。

```
type Mutation {
    putObject(
        email: AWSEmail,
        json: AWSJSON,
        date: AWSDate,
        time: AWSTime,
        datetime: AWSDateTime,
        timestamp: AWSTimestamp,
        url: AWSURL,
        phoneno: AWSPhone,
        ip: AWSIPAddress
    ): Object
}

type Object {
    id: ID!
    email: AWSEmail
    json: AWSJSON
    date: AWSDate
    time: AWSTime
    datetime: AWSDateTime
    timestamp: AWSTimestamp
    url: AWSURL
    phoneno: AWSPhone
    ip: AWSIPAddress
}

type Query {
    getObject(id: ID!): Object
    listObjects: [Object]
}

schema {
    query: Query
    mutation: Mutation
}
```

`putObject` のリクエストテンプレートは次のようになります。`putObject` は `PutItem` オペレーションを使用して Amazon DynamoDB テーブル内の項目を作成または更新します。このコードスニペットには、データソースとして Amazon DynamoDB テーブルが設定されていないことに注意してください。これは例としてのみ使用されています。

```
{
    "version" : "2017-02-28",
    "operation" : "PutItem",
    "key" : {
        "id": $util.dynamodb.toDynamoDBJson($util.autoId()),
    },
    "attributeValues" : $util.dynamodb.toMapValuesJson($ctx.args)
}
```

`putObject` のレスポンステンプレートは結果を返します。

```
$util.toJson($ctx.result)
```

`getObject` のリクエストテンプレートは次のようになります。`getObject` は `GetItem` オペレーションを開始し、指定されたプライマリキーを持つ項目の属性のセットを取得します。このコードスニペットには、データソースとして Amazon DynamoDB テーブルが設定されていないことに注意してください。これは例としてのみ使用されています。

```
{
    "version": "2017-02-28",
    "operation": "GetItem",
    "key": {
        "id": $util.dynamodb.toDynamoDBJson($ctx.args.id),
    }
}
```

`getObject` のレスポンステンプレートは結果を返します。

```
$util.toJson($ctx.result)
```

`listObjects` のリクエストテンプレートは次のようになります。`listObjects` は `Scan` オペレーションを使用して 1 つ以上の項目と属性を返します。このコードスニペットには、データソースとして Amazon DynamoDB テーブルが設定されていないことに注意してください。これは例としてのみ使用されています。

```
{
    "version" : "2017-02-28",
    "operation" : "Scan",
}
```

`listObjects` のレスポンステンプレートは結果を返します。

```
$util.toJson($ctx.result.items)
```

このスキーマを GraphQL クエリと共に使用する例をいくつか次に示します。

```
mutation CreateObject {
    putObject(email: "example@example.com"
        json: "{\"a\":1, \"b\":3, \"string\": 234}"
        date: "1970-01-01Z"
        time: "12:00:34."
        datetime: "1930-01-01T16:00:00-07:00"
        timestamp: -123123
        url:"https://amazon.com"
        phoneno: "+1 555 764 4377"
        ip: "127.0.0.1/8"
    ) {
        id
        email
        json
        date
        time
        datetime
        url
        timestamp
        phoneno
        ip
    }
}

query getObject {
    getObject(id:"0d97daf0-48e6-4ffc-8d48-0537e8a843d2"){
        email
        url
        timestamp
        phoneno
        ip
    }
}

query listObjects {
    listObjects {
        json
        date
        time
        datetime
    }
}
```

# GraphQL の Interface と Union
<a name="interfaces-and-unions"></a>

GraphQL 型システムは [Interface](https://graphql.org/learn/schema/#interfaces) をサポートしています。インターフェイスを実装するためにタイプに含める必要がある、フィールドの特定セットをインターフェイスで公開します。

GraphQL 型システムは[Union](https://graphql.org/learn/schema/#union-types)もサポートしています。Union はインターフェイスと同じです。異なるのはフィールドの共通セットを定義しない点です。Union は、可能なタイプが論理階層を共有しないとき、一般的にインターフェイスより優先されます。

次のセクションは、スキーマの型付けに関するリファレンスです。

## インターフェースの例
<a name="interfaces"></a>

たとえば、何らかのアクティビティまたは人の集まりを `Event` インターフェイスで表すことができます。考えられるイベントタイプには`Concert`、`Conference`、`Festival` などがあります。このようなタイプにはすべて、共通の特性 (名前、イベントの開催場所、開始日および終了日など) があります。これらのタイプに差分もあります。`Conference` には、講演者やワークショップのリストがあり、`Concert` には演奏するバンドが記載されています。

スキーマ定義言語 (SDL) では、`Event` インターフェイスは次のように定義されます。

```
interface Event {
        id: ID!
        name : String!
        startsAt: String
        endsAt: String
        venue: Venue
        minAgeRestriction: Int
}
```

また、`Event` インターフェイスを実装する各タイプは次のようになります。

```
type Concert implements Event {
    id: ID!
    name: String!
    startsAt: String
    endsAt: String
    venue: Venue
    minAgeRestriction: Int
    performingBand: String
}

type Festival implements Event {
    id: ID!
    name: String!
    startsAt: String
    endsAt: String
    venue: Venue
    minAgeRestriction: Int
    performers: [String]
}

type Conference implements Event {
    id: ID!
    name: String!
    startsAt: String
    endsAt: String
    venue: Venue
    minAgeRestriction: Int
    speakers: [String]
    workshops: [String]
}
```

インターフェイスは数種類の要素がある場合を表すのに便利です。たとえば、特定の会場で開催されているすべてのイベントを検索できます。次のように `findEventsByVenue` フィールドをスキーマに追加します。

```
schema {
    query: Query
}

type Query {
    # Retrieve Events at a specific Venue
    findEventsAtVenue(venueId: ID!): [Event]
}

type Venue {
    id: ID!
    name: String
    address: String
    maxOccupancy: Int
}

type Concert implements Event {
    id: ID!
    name: String!
    startsAt: String
    endsAt: String
    venue: Venue
    minAgeRestriction: Int
    performingBand: String
}

interface Event {
    id: ID!
    name: String!
    startsAt: String
    endsAt: String
    venue: Venue
    minAgeRestriction: Int
}

type Festival implements Event {
    id: ID!
    name: String!
    startsAt: String
    endsAt: String
    venue: Venue
    minAgeRestriction: Int
    performers: [String]
}

type Conference implements Event {
    id: ID!
    name: String!
    startsAt: String
    endsAt: String
    venue: Venue
    minAgeRestriction: Int
    speakers: [String]
    workshops: [String]
}
```

`findEventsByVenue` は `Event` のリストを返します。GraphQL インターフェイスフィールドはすべての実装タイプに共通しているため、`Event` インターフェイス (`id`、`name`、`startsAt`、`endsAt`、`venue`、および `minAgeRestriction`) の任意のフィールドを選択できます。さらに、GraphQL の [フラグメント](https://graphql.org/learn/queries/#fragments)を使用して、タイプを指定している限り、任意の実装タイプのフィールドにアクセスできます。

インターフェイスを使用する GraphQL クエリの例を詳しく見てみましょう。

```
query {
  findEventsAtVenue(venueId: "Madison Square Garden") {
    id
    name
    minAgeRestriction
    startsAt

    ... on Festival {
      performers
    }

    ... on Concert {
      performingBand
    }

    ... on Conference {
      speakers
      workshops
    }
  }
}
```

上記のクエリは、結果の単一のリストを生み出し、サーバーで、デフォルトでは、開始日によりイベントをソートできます。

```
{
  "data": {
    "findEventsAtVenue": [
      {
        "id": "Festival-2",
        "name": "Festival 2",
        "minAgeRestriction": 21,
        "startsAt": "2018-10-05T14:48:00.000Z",
        "performers": [
          "The Singers",
          "The Screamers"
        ]
      },
      {
        "id": "Concert-3",
        "name": "Concert 3",
        "minAgeRestriction": 18,
        "startsAt": "2018-10-07T14:48:00.000Z",
        "performingBand": "The Jumpers"
      },
      {
        "id": "Conference-4",
        "name": "Conference 4",
        "minAgeRestriction": null,
        "startsAt": "2018-10-09T14:48:00.000Z",
        "speakers": [
          "The Storytellers"
        ],
        "workshops": [
          "Writing",
          "Reading"
        ]
      }
    ]
  }
}
```

結果はイベントの 1 つのコレクションとして返されるため、共通特性を表すためにインターフェイスを使用すると、結果のソートに大変役立ちます。

## ユニオンの例
<a name="unions"></a>

先に述べたように、ユニオンは共通のフィールドセットを定義しません。検索結果で多様なタイプを表すことがあります。`Event` スキーマを使用して、次のように `SearchResult` ユニオンを定義できます。

```
type Query {
    # Retrieve Events at a specific Venue
    findEventsAtVenue(venueId: ID!): [Event]
    # Search across all content
    search(query: String!): [SearchResult]
}

union SearchResult = Conference | Festival | Concert | Venue
```

この場合、`SearchResult` ユニオンで任意のフィールドをクエリするには、フラグメントを使用する必要があります。

```
query {
  search(query: "Madison") {
    ... on Venue {
      id
      name
      address
    }

    ... on Festival {
      id
      name
      performers
    }

    ... on Concert {
      id
      name
      performingBand
    }

    ... on Conference {
      speakers
      workshops
    }
  }
}
```

## AWS AppSync でのタイプ解決
<a name="type-resolution-in-appsynclong"></a>

タイプ解決は、GraphQL エンジンが特定のオブジェクトタイプとして解決された値を識別するメカニズムです。

ユニオン検索例に戻り、クエリで結果を出した場合、結果リストの各項目は、定義された `SearchResult` ユニオンの可能なタイプの 1 つ (つまり、`Conference`、`Festival`、`Concert`、または `Venue`) として、それ自体を示す必要があります。

`Festival` を `Venue` や `Conference` から識別するロジックは、アプリケーションの要件に依存するため、GraphQL エンジンには、そのままの結果から可能なタイプを識別するヒントを与える必要があります。

 AWS AppSync では、このヒントは という名前のメタフィールドで表されます。このメタフィールドの値は`__typename`、識別されたオブジェクトタイプ名に対応します。 `__typename`は、インターフェイスまたはユニオンである戻り型に必要です。

## タイプ解決の例
<a name="type-resolution-example"></a>

前のスキーマを再利用します。コンソールに移動して、[**スキーマ**] ページで以下を追加することで、手順どおりに進めることができます。

```
schema {
    query: Query
}

type Query {
    # Retrieve Events at a specific Venue
    findEventsAtVenue(venueId: ID!): [Event]
    # Search across all content
    search(query: String!): [SearchResult]
}

union SearchResult = Conference | Festival | Concert | Venue

type Venue {
    id: ID!
    name: String!
    address: String
    maxOccupancy: Int
}

interface Event {
    id: ID!
    name: String!
    startsAt: String
    endsAt: String
    venue: Venue
    minAgeRestriction: Int
}

type Festival implements Event {
    id: ID!
    name: String!
    startsAt: String
    endsAt: String
    venue: Venue
    minAgeRestriction: Int
    performers: [String]
}

type Conference implements Event {
    id: ID!
    name: String!
    startsAt: String
    endsAt: String
    venue: Venue
    minAgeRestriction: Int
    speakers: [String]
    workshops: [String]
}

type Concert implements Event {
    id: ID!
    name: String!
    startsAt: String
    endsAt: String
    venue: Venue
    minAgeRestriction: Int
    performingBand: String
}
```

リゾルバーを `Query.search` フィールドにアタッチしましょう。`Resolvers` セクションで、**[アタッチ]** を選択し、*NONE* タイプの新しい**データソース**を作成してから、*StubDataSource* という名前を付けます。この例では、外部ソースから結果を取得したものとし、リクエストマッピングテンプレートで取得された結果をハードコードします。

リクエストマッピングテンプレートペインで、次のように入力します。

```
{
    "version" : "2018-05-29",
    "payload":
    ## We are effectively mocking our search results for this example
    [
        {
            "id": "Venue-1",
            "name": "Venue 1",
            "address": "2121 7th Ave, Seattle, WA 98121",
            "maxOccupancy": 1000
        },
        {
            "id": "Festival-2",
            "name": "Festival 2",
            "performers": ["The Singers", "The Screamers"]
        },
        {
            "id": "Concert-3",
            "name": "Concert 3",
            "performingBand": "The Jumpers"
        },
        {
            "id": "Conference-4",
            "name": "Conference 4",
            "speakers": ["The Storytellers"],
            "workshops": ["Writing", "Reading"]
        }
    ]
}
```

アプリケーションが、`id` フィールドの一部としてタイプ名を返す場合、タイプ解決ロジックは、`id` フィールドを解析してタイプ名を抽出し、`__typename` フィールドを各結果を追加します。次のようにレスポンスマッピングテンプレートでそのロジックを実行できます。

**注記**  
Lambda データソースを使用している場合は、このタスクを Lambda 関数の一部として実行することもできます。

```
#foreach ($result in $context.result)
    ## Extract type name from the id field.
    #set( $typeName = $result.id.split("-")[0] )
    #set( $ignore = $result.put("__typename", $typeName))
#end
$util.toJson($context.result)
```

次のクエリを実行します。

```
query {
  search(query: "Madison") {
    ... on Venue {
      id
      name
      address
    }

    ... on Festival {
        id
      name
      performers
    }

    ... on Concert {
      id
      name
      performingBand
    }

    ... on Conference {
      speakers
      workshops
    }
  }
}
```

クエリにより、次の結果が返されます。

```
{
  "data": {
    "search": [
      {
        "id": "Venue-1",
        "name": "Venue 1",
        "address": "2121 7th Ave, Seattle, WA 98121"
      },
      {
        "id": "Festival-2",
        "name": "Festival 2",
        "performers": [
          "The Singers",
          "The Screamers"
        ]
      },
      {
        "id": "Concert-3",
        "name": "Concert 3",
        "performingBand": "The Jumpers"
      },
      {
        "speakers": [
          "The Storytellers"
        ],
        "workshops": [
          "Writing",
          "Reading"
        ]
      }
    ]
  }
}
```

タイプ解決ロジックはアプリケーションによって異なります。たとえば、特定のフィールドまたはフィールドの組み合わせの存在をチェックする、異なる識別ロジックがあってもかまいません。つまり、`performers` フィールドの存在を検出して、`Festival` を識別する、または `speakers` と `workshops` フィールドの組み合わせを検出して、`Conference` を識別できます。最終的に、使用するロジックを定義するのはユーザーです。