

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

# AWS AppSync リゾルバーマッピングテンプレートの概要
<a name="resolver-mapping-template-reference-overview"></a>

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

AWS AppSync では、リソースに対してオペレーションを実行して GraphQL リクエストに応答できます。クエリ や ミューテーション など、実行する GraphQL フィールドごとに、データソースとやり取りするためにリゾルバーをアタッチする必要があります。通常、この通信はパラメータを介して行うか、データソースに固有の処理を使用します。

リゾルバーは GraphQL とデータソースの間のコネクタです。受信した GraphQL リクエストをバックエンドデータソースの手順に変換する方法と、そのデータソースからのレスポンスを GraphQL レスポンスに変換する方法を AWS AppSync に伝えます。これらは [Apache Velocity Template Language (VTL)](https://velocity.apache.org/engine/1.7/user-guide.html) で記述されます。これにより、入力としてリクエストを受け取り、リゾルバーに関する指示を含む JSON ドキュメントを出力します。GraphQL フィールドから引数を渡すなどの簡単な指示や、引数の指定により、項目をビルドしてから DynamoDB への挿入を繰り返すといったより複雑な指示をマッピングテンプレートを使用して行えます。

 AWS AppSync には、マッピングテンプレートをわずかに異なる方法で活用する 2 種類のリゾルバーがあります。
+ ユニットリゾルバー
+ パイプラインリゾルバー

## ユニットリゾルバー
<a name="unit-resolvers"></a>

ユニットリゾルバーは、リクエストおよびレスポンステンプレートのみを含む自己完結型エンティティです。1 つのデータソースから項目を一覧表示するなどのシンプルな 1 つのオペレーションに、この種類のリゾルバーを使用します。
+ リクエストテンプレート: GraphQL オペレーションが解析された後に受信リクエストを受け取り、選択されたデータソースオペレーション用のリクエスト設定に変換します。
+ レスポンステンプレート: データソースからのレスポンスを解釈し、GraphQL フィールド出力タイプの形式にマッピングします。

## パイプラインリゾルバー
<a name="pipeline-resolvers"></a>

パイプラインリゾルバーには、順番に実行される 1 つ以上の*関数*が含まれています。各関数には、リクエストテンプレートとレスポンステンプレートが含まれています。パイプラインのリゾルバーには、一連の関数を囲むテンプレートである *before* テンプレートと*after* テンプレートも含まれています。*After* テンプレートは GraphQL フィールド出力タイプにマッピングします。パイプラインのリゾルバーは、レスポンステンプレートの出力をマッピングする点でユニットリゾルバーとは異なります。パイプラインリゾルバーは、別の関数の入力や、パイプラインリゾルバーの*after*テンプレートを含むどんな出力でもマッピングできます。

 パイプラインリゾルバー*機能*では、スキーマ内の複数のリゾルバーにまたがって再利用できる共通のロジックを作成できます。関数はデータソースに直接アタッチされており、ユニットリゾルバーのものと同じリクエストおよびレスポンスマッピングテンプレート形式を含んでいます。

次の図は、左側がユニットリゾルバー、右側がパイプラインリゾルバーのプロセスフローを示しています。

![\[単一のデータソースと通信するユニットリゾルバーの図と、複数のデータソースと通信するパイプラインのリゾルバーの図。\]](http://docs.aws.amazon.com/ja_jp/appsync/latest/devguide/images/unit-pipeline-resolver.png)


パイプラインリゾルバーには、少々複雑になるものの、ユニットリゾルバーが提供する機能の上位集合が含まれています。

### パイプラインリゾルバーの仕組み
<a name="anatomy-of-a-pipeline-resolver"></a>

パイプラインリゾルバーは、**Before** マッピングテンプレート、**After** マッピングテンプレート、関数のリストで構成されています。各関数には、データソースに対して実行される**リクエスト**および**レスポンス**マッピングテンプレートがあります。パイプラインリゾルバーは実行をリスト内の関数に委任するため、いずれのデータソースにもリンクされていません。ユニットリゾルバーと関数は、データソースに対してオペレーションを実行するプリミティブです。詳細については、「[リゾルバーのマッピングテンプレートの概要](#aws-appsync-resolver-mapping-template-reference-overview)」を参照してください。

#### Before マッピングテンプレート
<a name="before-mapping-template"></a>

パイプラインリゾルバーのリクエストマッピングテンプレート (**Before** ステップとも呼ばれる) では、定義した関数を実行する前に準備ロジックを実行できます。

#### 関数のリスト
<a name="functions-list"></a>

パイプラインリゾルバーが順番に実行する関数のリスト。パイプラインリゾルバーのリクエストマッピングテンプレートの評価結果は、最初の関数で `$ctx.prev.result` として使用可能になります。各関数の出力は、以下の関数で `$ctx.prev.result` として使用可能です。

#### After マッピングテンプレート
<a name="after-mapping-template"></a>

パイプラインリゾルバーのレスポンスマッピングテンプレート (**After** ステップとも呼ばれる) では、最後の関数の出力から、想定される GraphQL フィールドタイプへの、最終的なマッピングロジックを実行できます。関数のリストの最後にある関数の出力は、パイプラインリゾルバーのマッピングテンプレートで `$ctx.prev.result` または `$ctx.result` として使用可能です。

#### 実行フロー
<a name="execution-flow"></a>

2 つの関数で構成されるパイプラインリゾルバーがあるとします。以下のリストでは、リゾルバーが呼び出されたときの実行フローを表しています。

![\[GraphQL request flow diagram showing template processing and data source interactions.\]](http://docs.aws.amazon.com/ja_jp/appsync/latest/devguide/images/PipelineResolver.jpg)


1. パイプラインリゾルバーの Before マッピングテンプレート

1. 関数 1: 関数のリクエストマッピングテンプレート

1. 関数 1: データソースの呼び出し

1. 関数 1: 関数のレスポンスマッピングテンプレート

1. 関数 2: 関数のリクエストマッピングテンプレート

1. 関数 2: データソースの呼び出し

1. 関数 2: 関数のレスポンスマッピングテンプレート

1. パイプラインリゾルバーの After マッピングテンプレート

**注記**  
パイプラインリゾルバーの実行フローは単方向であり、リゾルバーで静的に定義されています。

#### 便利な Apache Velocity Template Language (VTL) ユーティリティ
<a name="useful-apache-velocity-template-language-vtl-utilities"></a>

アプリケーションの複雑さが増すにつれて、開発生産性を促進するのが、VTL ユーティリティとディレクティブの目的です。パイプラインリゾルバーでの作業には、以下のユーティリティが役立ちます。

##### \$1ctx.stash
<a name="ctx-stash"></a>

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

##### \$1ctx.prev.result
<a name="ctx-prev-result"></a>

`$ctx.prev.result` は、パイプラインリゾルバーで実行された前のオペレーションの結果を表します。

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

##### \$1return(data: Object)
<a name="return-data-object"></a>

マッピングテンプレートから途中で戻る必要がある場合は、`#return(data: Object)` ディレクティブが便利です。`#return(data: Object)` は、プログラミング言語の *return* キーワードと似ています。これは、最も近いスコープのロジックブロックから戻るためです。つまり、リゾルバーのマッピングテンプレート内で `#return` を使用すると、リゾルバーから戻ることになります。リゾルバーのマッピングテンプレートで `#return(data: Object)` を使用すると、GraphQL フィールドに `data` が設定されます。さらに、関数のマッピングテンプレートから `#return(data: Object)` を使用すると、実行が関数から戻り、パイプライン内の次の関数に、またはリゾルバーのレスポンスマッピングテンプレートに継続されます。

##### \$1return
<a name="return"></a>

これは `#return(data: Object)` と同じですが、代わりに `null` が返されます。

##### \$1util.error
<a name="util-error"></a>

`$util.error` ユーティリティはフィールドエラーをスローするのに便利です。関数のマッピングテンプレート内で `$util.error` を使用すると、フィールドエラーがすぐにスローされ、それ以降の関数が実行されなくなります。詳細およびその他の `$util.error` 署名については、「[リゾルバーのマッピングテンプレートのユーティリティリファレンス](resolver-util-reference.md#aws-appsync-resolver-mapping-template-util-reference)」を参照してください。

##### \$1util.appendError
<a name="util-appenderror"></a>

注意: `$util.appendError` は `$util.error()` と似ていますが、マッピングテンプレートの評価を中断しないという違いがあります。代わりに、フィールドにエラーがあったことを通知します。ただし、テンプレートを評価し、データを引き続き返すことも可能です。関数内で `$util.appendError` を使用しても、パイプラインの実行フローは中断されません。詳細およびその他の `$util.error` 署名については、「[リゾルバーのマッピングテンプレートのユーティリティリファレンス](resolver-util-reference.md#aws-appsync-resolver-mapping-template-util-reference)」を参照してください。

## サンプルテンプレート
<a name="example-template"></a>

DynamoDB データソースがあり、また次の GraphQL クエリにより `Post` 型を返す `getPost(id:ID!)` というフィールドの **ユニット** リゾルバーがあるとします。

```
getPost(id:1){
    id
    title
    content
}
```

リゾルバーのテンプレートは以下のようになります。

```
{
    "version" : "2018-05-29",
    "operation" : "GetItem",
    "key" : {
        "id" : $util.dynamodb.toDynamoDBJson($ctx.args.id)
    }
}
```

これは、`id` の入力パラメータ値 `1` を `${ctx.args.id}` に置き換え、次の JSON を生成します。

```
{
    "version" : "2018-05-29",
    "operation" : "GetItem",
    "key" : {
        "id" : { "S" : "1" }
    }
}
```

AWS AppSync はこのテンプレートを使用して、DynamoDB と通信してデータを取得する (または必要に応じて他のオペレーションを実行する) 手順を生成します。データが返されたら、 AWS AppSync はオプションのレスポンスマッピングテンプレートを使用してこの指示を実行します。このテンプレートは、データの形式操作またはロジックを実行するために使用できます。たとえば、DynamoDB から次のような結果を取得します。

```
{
        "id" : 1,
        "theTitle" : "AWS AppSync works offline!",
        "theContent-part1" : "It also has realtime functionality",
        "theContent-part2" : "using GraphQL"
}
```

次のようなレスポンスマッピングテンプレートを使用して、2 つのフィールドを 1 つのフィールドに結合することもできます。

```
{
        "id" : $util.toJson($context.data.id),
        "title" : $util.toJson($context.data.theTitle),
        "content" : $util.toJson("${context.data.theContent-part1} ${context.data.theContent-part2}")
}
```

テンプレートがデータに適用されると、データは次のように成形されます。

```
{
        "id" : 1,
        "title" : "AWS AppSync works offline!",
        "content" : "It also has realtime functionality using GraphQL"
}
```

このデータは以下のように、クライアントへのレスポンスとして返されます。

```
{
        "data": {
                "getPost":      {
                        "id" : 1,
                        "title" : "AWS AppSync works offline!",
                        "content" : "It also has realtime functionality using GraphQL"
                }
        }
}
```

ほとんどの場合、レスポンスマッピングテンプレートはデータを単純に転送します。個々の項目や項目のリストを返す場合は、大きく異なります。個々の項目について、パススルーは次のようになります。

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

リストについて、パススルーは通常次のようになります。

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

ユニットリゾルバーとパイプラインリゾルバーの両方のさらに多くの例については、[リゾルバーのチュートリアル](tutorials.md#aws-appsync-tutorials)を参照してください。

## 評価されたマッピングテンプレートの逆シリアル化ルール
<a name="evaluated-mapping-template-deserialization-rules"></a>

マッピングテンプレートは文字列として評価されます。 AWS AppSync では、有効な出力文字列は JSON 構造に従う必要があります。

さらに、以下の逆シリアル化ルールが適用されます。

### JSON オブジェクトでは、重複キーは使用できません。
<a name="duplicate-keys-are-not-allowed-in-json-objects"></a>

評価されたマッピングテンプレート文字列が JSON オブジェクトを表すか、重複するキーのあるオブジェクトを含む場合、マッピングテンプレートから以下のエラーメッセージが返されます。

 `Duplicate field 'aField' detected on Object. Duplicate JSON keys are not allowed.` 

評価されたリクエストマッピングテンプレートの重複キーの例:

```
{
    "version": "2018-05-29",
    "operation": "Invoke",
    "payload": {
        "field": "getPost",
        "postId": "1",
        "field": "getPost" ## key 'field' has been redefined
    }
}
```

このエラーを修正するには、JSON オブジェクトのキーを再定義しないでください。

### JSON オブジェクトでは末尾に文字は使用できません。
<a name="trailing-characters-are-not-allowed-in-json-objects"></a>

評価されたマッピングテンプレート文字列が JSON オブジェクトを表し、末尾に無関係な文字が含まれている場合は、マッピングテンプレートから以下のエラーメッセージが返されます。

 `Trailing characters at the end of the JSON string are not allowed.` 

評価されたリクエストマッピングテンプレートの末尾の文字の例:

```
{
    "version": "2018-05-29",
    "operation": "Invoke",
    "payload": {
        "field": "getPost",
        "postId": "1",
    }
}extraneouschars
```

このエラーを修正するには、評価対象のテンプレートが厳密に JSON に評価されるようにしてください。