AWS AppSync のリゾルバーマッピングテンプレートの概要 - AWS AppSync GraphQL

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

AWS AppSync のリゾルバーマッピングテンプレートの概要

注記

現在、主に APPSYNC_JSランタイムとそのドキュメントをサポートしています。こちらにある APPSYNC_JS ランタイムとそのガイドの使用をご検討ください。

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

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

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

  • ユニットリゾルバー

  • パイプラインリゾルバー

ユニットリゾルバー

ユニットリゾルバーは、リクエストおよびレスポンステンプレートのみを含む自己完結型エンティティです。1 つのデータソースから項目を一覧表示するなどのシンプルな 1 つのオペレーションに、この種類のリゾルバーを使用します。

  • リクエストテンプレート: GraphQL オペレーションが解析された後に受信リクエストを受け取り、選択されたデータソースオペレーション用のリクエスト設定に変換します。

  • レスポンステンプレート: データソースからのレスポンスを解釈し、GraphQL フィールド出力タイプの形式にマッピングします。

パイプラインリゾルバー

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

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

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

単一のデータソースと通信するユニットリゾルバーの図と、複数のデータソースと通信するパイプラインのリゾルバーの図。

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

パイプラインリゾルバーの仕組み

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

Before マッピングテンプレート

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

関数のリスト

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

After マッピングテンプレート

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

実行フロー

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

GraphQL request flow diagram showing template processing and data source interactions.
  1. パイプラインリゾルバーの Before マッピングテンプレート

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

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

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

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

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

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

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

注記

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

便利な Apache Velocity Template Language (VTL) ユーティリティ

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

$ctx.stash

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

$ctx.prev.result

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

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

#return(data: Object)

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

#return

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

$util.error

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

$util.appendError

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

サンプルテンプレート

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)

ユニットリゾルバーとパイプラインリゾルバーの両方のさらに多くの例については、リゾルバーのチュートリアルを参照してください。

評価されたマッピングテンプレートの逆シリアル化ルール

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

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

JSON オブジェクトでは、重複キーは使用できません。

評価されたマッピングテンプレート文字列が 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 オブジェクトでは末尾に文字は使用できません。

評価されたマッピングテンプレート文字列が 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 に評価されるようにしてください。