

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

# AWS AppSync リゾルバーマッピングテンプレートコンテキストリファレンス
<a name="resolver-context-reference"></a>

**注記**  
現在、主に APPSYNC\$1JS ランタイムとそのドキュメントをサポートしています。[こちら](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html) で APPSYNC\$1JS ランタイムとそのガイドの使用をご検討ください。

AWS AppSync は、リゾルバーマッピングテンプレートを操作するための変数と関数のセットを定義します。これにより、GraphQL を使用してデータの論理的オペレーションが容易になります。このドキュメントでは、それらの関数について説明し、テンプレートの使用例を示します。

## `$context` へのアクセス
<a name="accessing-the-context"></a>

`$context` 変数は、リゾルバー呼び出しのすべてのコンテキスト情報が保持されるマップです。この変数の構造は次のとおりです。

```
{
   "arguments" : { ... },
   "source" : { ... },
   "result" : { ... },
   "identity" : { ... },
   "request" : { ... },
   "info": { ... }
}
```

**注記**  
キーによってディクショナリ/マップエントリ (`context` 内のエントリなど) にアクセスし、値を取得しようとしている場合は、Velocity Template Language (VTL) によって表記 `<dictionary-element>.<key-name>` を直接使用できます。ただし、キー名に特殊文字 (アンダースコア "\$1" など) が使われている場合など、一部のケースでは機能しない場合があります。常に `<dictionary-element>.get("<key-name>")` 表記を使用することをお勧めします。

`$context` マップの各フィールドは次のように定義されます。

### `$context` フィールド
<a name="accessing-the-context-list"></a>

** `arguments` **  
このフィールドのすべての GraphQL 引数を含むマップ。

** `identity` **  
呼び出し元に関する情報を含むオブジェクト。このフィールドの構造の詳細については、「[ID](#aws-appsync-resolver-context-reference-identity)」を参照してください。

** `source` **  
親フィールドの解像度を含むマップ。

** `stash` **  
stash は、リゾルバーと関数の各マッピングテンプレート内で使用可能になるマップです。同じ stash インスタンスは 1 つのリゾルバーの実行を通して存続します。つまり、stash を使用して、リクエストとレスポンスのマッピングテンプレート間、およびパイプラインリゾルバーの関数間で、任意のデータを渡すことができます。stash は [Java Map](https://docs.oracle.com/javase/8/docs/api/java/util/Map.html) データ構造と同じメソッドを継承しています。

** `result` **  
このリゾルバーの結果用のコンテナ。このフィールドはレスポンスマッピングテンプレートでのみ使用できます。  
たとえば、次のクエリの `author` フィールドを解決する場合:  

```
query {
    getPost(id: 1234) {
        postId
        title
        content
        author {
            id
            name
        }
    }
}
```
レスポンスマッピングテンプレートを処理する際に使用可能な完全な `$context` 変数は次のようになります。  

```
{
  "arguments" : {
    id: "1234"
  },
  "source": {},
  "result" : {
      "postId": "1234",
      "title": "Some title",
      "content": "Some content",
      "author": {
        "id": "5678",
        "name": "Author Name"
      }
  },
  "identity" : {
      "sourceIp" : ["x.x.x.x"],
      "userArn" : "arn:aws:iam::123456789012:user/appsync",
      "accountId" : "666666666666",
      "user" : "AIDAAAAAAAAAAAAAAAAAA"
  }
}
```

** `prev.result` **  
パイプラインリゾルバーで実行された前回のオペレーションの結果です。  
前のオペレーションがパイプラインリゾルバーのリクエストマッピングテンプレートであった場合、`$ctx.prev.result` はテンプレートの評価の出力を表し、パイプライン内の最初の関数に使用可能になります。  
前のオペレーションが最初の関数であった場合、`$ctx.prev.result` は最初の関数の出力を表し、パイプライン内の 2 番目の関数に使用可能になります。  
前のオペレーションが最後の関数であった場合、`$ctx.prev.result` は最後の関数の出力を表し、パイプラインリゾルバーのレスポンスマッピングテンプレートに使用可能になります。

** `info` **  
GraphQL リクエストに関する情報を含むオブジェクト。このフィールドの構造については、「[情報](#aws-appsync-resolver-context-reference-info)」を参照してください。

### アイデンティティ
<a name="aws-appsync-resolver-context-reference-identity"></a>

`identity` セクションには、呼び出し元に関する情報が含まれています。このセクションのシェイプは、使用する AWS AppSync API の認可タイプによって異なります。

 AWS AppSync セキュリティオプションの詳細については、[「認可と認証](security-authz.md#aws-appsync-security)」を参照してください。

** `API_KEY` authorization**  
`identity` フィールドは入力されていません。

**`AWS_LAMBDA` authorization**  
`identity`には、リクエストを承認する Lambda 関数によって返されるのと同じ `resolverContext` コンテンツを含む `resolverContext` キーが含まれています。

** `AWS_IAM` authorization**  
`identity` の形式は次のとおりです。  

```
{
    "accountId" : "string",
    "cognitoIdentityPoolId" : "string",
    "cognitoIdentityId" : "string",
    "sourceIp" : ["string"],
    "username" : "string", // IAM user principal
    "userArn" : "string",
    "cognitoIdentityAuthType" : "string", // authenticated/unauthenticated based on the identity type
    "cognitoIdentityAuthProvider" : "string" // the auth provider that was used to obtain the credentials
}
```

** `AMAZON_COGNITO_USER_POOLS` authorization**  
`identity` の形式は次のとおりです。  

```
{
    "sub" : "uuid",
    "issuer" : "string",
    "username" : "string"
    "claims" : { ... },
    "sourceIp" : ["x.x.x.x"],
    "defaultAuthStrategy" : "string"
}
```

各フィールドは次のように定義されています。

** `accountId` **  
発信者の AWS アカウント ID。

** `claims` **  
ユーザーが持っているクレーム。

** `cognitoIdentityAuthType` **  
ID タイプに基づいて認証済みまたは未認証のいずれか。

** `cognitoIdentityAuthProvider` **  
リクエストの署名に使用された認証情報の取得先となる外部 ID プロバイダ情報のカンマ区切りリスト。

** `cognitoIdentityId` **  
リクエストを行う呼び出し元の Amazon Cognito 認証 ID。

** `cognitoIdentityPoolId` **  
呼び出し元に関連付けられている Amazon Cognito ID プール。

** `defaultAuthStrategy` **  
この呼び出し元のデフォルトの認可方法 (`ALLOW`または`DENY`)。

** `issuer` **  
トークン発行者。

** `sourceIp` **  
が AWS AppSync 受信する発信者の送信元 IP アドレス。リクエストに `x-forwarded-for` ヘッダーが含まれていない場合、ソース IP の値には TCP 接続からの 1 つの IP アドレスのみが含まれます。リクエストに `x-forwarded-for` ヘッダーが含まれている場合、ソース IP は、TCP 接続からの IP アドレスと `x-forwarded-for` ヘッダーからの IP アドレスのリストです。

** `sub` **  
認証されたユーザーの UUID。

** `user` **  
IAM ユーザー。

** `userArn` **  
IAM ユーザーの Amazon リソースネーム (ARN)。

** `username` **  
認証されたユーザーのユーザー名です。`AMAZON_COGNITO_USER_POOLS` 認可の場合、*username* の値は *cognito:username* 属性の値です。`AWS_IAM` 認可の場合、*ユーザー名*の値は AWS ユーザープリンシパルの値です。Amazon Cognito アイデンティティプールから発行された認証情報による IAM 認可を使用されている場合は、`cognitoIdentityId`の使用をお勧めします。

### リクエストヘッダーへのアクセス
<a name="aws-appsync-resolver-context-reference-util"></a>

AWS AppSync は、クライアントからのカスタムヘッダーの受け渡しと、 を使用した GraphQL リゾルバーでのカスタムヘッダーへのアクセスをサポートしています`$context.request.headers`。データソースへデータの挿入や認可チェックなどのアクションでそのヘッダーの値を使用できます。次の例のようにコマンドラインから API キーで `$curl` を使用して、1 つまたは複数のリクエストヘッダーを使用できます。

**単一ヘッダーの例** 

次のように、`custom` のヘッダーに `nadia` の値を設定しているとします。

```
curl -XPOST -H "Content-Type:application/graphql" -H "custom:nadia" -H "x-api-key:<API-KEY-VALUE>" -d '{"query":"mutation { createEvent(name: \"demo\", when: \"Next Friday!\", where: \"Here!\") {id name when where description}}"}' https://<ENDPOINT>/graphql
```

この値には `$context.request.headers.custom` を使用してアクセスできます。たとえば、DynamoDB に対する VTL は次のようになります。

```
"custom": $util.dynamodb.toDynamoDBJson($context.request.headers.custom)
```

**複数ヘッダーの例** 

1 つのリクエストで複数のヘッダーを渡して、リゾルバーのマッピングテンプレートでそれらのヘッダーにアクセスすることもできます。例えば、次のように `custom` ヘッダーに 2 つの値が設定されているとします。

```
curl -XPOST -H "Content-Type:application/graphql" -H "custom:bailey" -H "custom:nadia" -H "x-api-key:<API-KEY-VALUE>" -d '{"query":"mutation { createEvent(name: \"demo\", when: \"Next Friday!\", where: \"Here!\") {id name when where description}}"}' https://<ENDPOINT>/graphql
```

それらのヘッダーに配列としてアクセスできます (例: `$context.request.headers.custom[1]`)。

**注記**  
AWS AppSync は の Cookie ヘッダーを公開しません`$context.request.headers`。

### リクエストカスタムドメイン名にアクセスする
<a name="aws-access-requested-custom-domain-names"></a>

AWS AppSync は、APIs の GraphQL およびリアルタイムエンドポイントにアクセスするために使用できるカスタムドメインの設定をサポートしています。カスタムドメイン名を使用してリクエストを行う場合は、`$context.request.domainName` を使用してドメイン名を取得できます。

デフォルトの GraphQL エンドポイントドメイン名を使用する場合、値は `null` です。

### [情報]
<a name="aws-appsync-resolver-context-reference-info"></a>

`info` セクションには、GraphQL リクエストに関する情報が含まれています。このセクションには、次の形式が含まれます。

```
{
    "fieldName": "string",
    "parentTypeName": "string",
    "variables": { ... },
    "selectionSetList": ["string"],
    "selectionSetGraphQL": "string"
}
```

各フィールドは次のように定義されています。

** `fieldName` **  
現在解決中のフィールドの名前。

** `parentTypeName` **  
現在解決中のフィールドの親タイプの名前。

** `variables` **  
GraphQLリクエストに渡されるすべての変数を保持するマップ。

** `selectionSetList` **  
GraphQL 選択セット内のフィールドのリスト表現。エイリアスされたフィールドは、フィールド名ではなく、エイリアス名によってのみ参照されます。次の例で詳細を示します。

** `selectionSetGraphQL` **  
選択セットの文字列表現。GraphQL スキーマ定義言語 (SDL) としてフォーマットされます。フラグメントは選択セットにマージされませんが、次の例に示すように、インラインフラグメントは保持されます。

**注記**  
`context.info` を `$utils.toJson()` で使用する場合，`selectionSetList` および `selectionSetGraphQL` によって返される値はデフォルトでシリアル化されません。

たとえば、次のクエリの `getPost` フィールドを解決する場合:

```
query {
  getPost(id: $postId) {
    postId
    title
    secondTitle: title
    content
    author(id: $authorId) {
      authorId
      name
    }
    secondAuthor(id: "789") {
      authorId
    }
    ... on Post {
      inlineFrag: comments: {
        id
      }
    }
    ... postFrag
  }
}

fragment postFrag on Post {
  postFrag: comments: {
    id
  }
}
```

レスポンスマッピングテンプレートを処理する際に使用可能な完全な `$context.info` 変数は次のようになります。

```
{
  "fieldName": "getPost",
  "parentTypeName": "Query",
  "variables": {
    "postId": "123",
    "authorId": "456"
  },
  "selectionSetList": [
    "postId",
    "title",
    "secondTitle"
    "content",
    "author",
    "author/authorId",
    "author/name",
    "secondAuthor",
    "secondAuthor/authorId",
    "inlineFragComments",
    "inlineFragComments/id",
    "postFragComments",
    "postFragComments/id"
  ],
  "selectionSetGraphQL": "{\n  getPost(id: $postId) {\n    postId\n    title\n    secondTitle: title\n    content\n    author(id: $authorId) {\n      authorId\n      name\n    }\n    secondAuthor(id: \"789\") {\n      authorId\n    }\n    ... on Post {\n      inlineFrag: comments {\n        id\n      }\n    }\n    ... postFrag\n  }\n}"
}
```

`selectionSetList` は現在のタイプに属するフィールドのみを公開します。現在のタイプがインタフェースまたは共用体の場合、そのインタフェースに属する選択されたフィールドのみが公開されます。例として、次のスキーマがあるとします。

```
type Query {
    node(id: ID!): Node
}

interface Node {
    id: ID
}

type Post implements Node {
    id: ID
    title: String
    author: String
}

type Blog implements Node {
    id: ID
    title: String
    category: String
}
```

そして次のクエリがあります。

```
query {
    node(id: "post1") {
        id
        ... on Post {
            title
        }

        ... on Blog {
            title
        }
    }
}
```

`Query.node` フィールド解決で `$ctx.info.selectionSetList` が呼び出されると、`id` のみが公開されます。

```
"selectionSetList": [
    "id"
]
```

## 入力のサニタイズ
<a name="sanitizing-inputs"></a>

アプリケーションは、信頼できない入力をサニタイズして、部外者が意図した用途以外でアプリケーションを使用することを防ぐ必要があります。`$context` には、`$context.arguments`、`$context.identity`、`$context.result`、`$context.info.variables`、`$context.request.headers` などのプロパティにユーザー入力が含まれているため、マッピングテンプレート内の値をサニタイズするように注意する必要があります。

マッピングテンプレートは JSON を表すため、入力のサニタイズは、ユーザー入力を表す文字列から JSON 予約文字をエスケープする形式をとります。JSON 予約文字をマッピングテンプレートに配置するときは、`$util.toJson()` ユーティリティを使用して機密文字列値からエスケープすることをお勧めします。

たとえば、以下の Lambda リクエストマッピングテンプレートでは、安全でないユーザー入力文字列 (`$context.arguments.id`) にアクセスしたため、エスケープされていない JSON 文字が JSON テンプレートを破壊するのを防ぐために、`$util.toJson()` でラップしました。

```
{
    "version": "2017-02-28",
    "operation": "Invoke",
    "payload": {
        "field": "getPost",
        "postId": $util.toJson($context.arguments.id)
    }
}
```

`$context.arguments.id` をサニタイズなしで直接挿入する以下のマッピングテンプレートとは対照的です。これは、エスケープされていない二重引用符やその他の JSON 予約文字を含む文字列では機能せず、テンプレートを開くとエラーになる可能性があります。

```
## DO NOT DO THIS
{
    "version": "2017-02-28",
    "operation": "Invoke",
    "payload": {
        "field": "getPost",
        "postId": "$context.arguments.id" ## Unsafe! Do not insert $context string values without escaping JSON characters.
    }
}
```