AWS AppSync リゾルバマッピングテンプレートの変更ログ - AWS AppSync

AWS AppSync リゾルバマッピングテンプレートの変更ログ

注記

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

リゾルバーと関数のマッピングテンプレートはバージョニングされています。2018-05-29 などのマッピングテンプレートバージョンは、以下を決定します。

  • リクエストテンプレートによって提供されるデータソースリクエスト設定の想定される形式

  • リクエストマッピングテンプレートとレスポンスマッピングテンプレートの実行動作

バージョンは YYYY-MM-DD 形式を使用して表され、より後の日付はより新しいバージョンに対応します。このページには、AWS AppSync で現在サポートされているマッピングテンプレートのバージョン間の違いが一覧表示されます。

バージョンごとのデータソースオペレーションの可用性一覧

オペレーション/サポートされているバージョン 2017-02-28 2018-05-29

AWS Lambda 呼び出し

あり

可能

AWS Lambda BatchInvoke

あり

可能

none データソース

あり

可能

Amazon OpenSearch GET

あり

可能

Amazon OpenSearch POST

あり

可能

Amazon OpenSearch PUT

あり

可能

Amazon OpenSearch DELE

あり

可能

Amazon OpenSearch GET

あり

可能

DynamoDB GetItem

あり

可能

DynamoDB Scan

あり

可能

DynamoDB Query

あり

可能

DynamoDB DeleteItem

あり

可能

DynamoDB PutItem

あり

可能

DynamoDB BatchGetItem

不可

可能

DynamoDB BatchPutItem

不可

可能

DynamoDB BatchDeleteItem

不可

可能

HTTP

不可

可能

Amazon RDS

不可

可能

注意: 関数で現在サポートされているのは 2018-05-29 バージョンのみです。

ユニットリゾルバーのマッピングテンプレートのバージョンの変更

ユニットリゾルバーの場合、バージョンはリクエストマッピングテンプレートの本文の一部として指定されています。バージョンを更新するには、version フィールドを新しいバージョンに更新するだけです。

たとえば、AWS Lambda テンプレートのバージョンを更新するには、以下のようにします。

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

以下のように version フィールドを 2017-02-28 から 2018-05-29 に更新する必要があります。

{ "version": "2018-05-29", ## Note the version "operation": "Invoke", "payload": { "field": "getPost", "arguments": $utils.toJson($context.arguments) } }

関数のバージョンの変更

関数の場合、バージョンは function オブジェクトの functionVersion フィールドとして指定されています。バージョンを更新するには、functionVersion を更新するだけです。注意: 現在、関数では 2018-05-29 のみがサポートされています。

以下に示しているのは、既存の関数バージョンを更新する CLI コマンドの例です。

aws appsync update-function \ --api-id REPLACE_WITH_API_ID \ --function-id REPLACE_WITH_FUNCTION_ID \ --data-source-name "PostTable" \ --function-version "2018-05-29" \ --request-mapping-template "{...}" \ --response-mapping-template "\$util.toJson(\$ctx.result)"

注意: 関数のリクエストマッピングテンプレートから version フィールドを省略することをお勧めします。それにより、このフィールドが優先されなくなります。関数のリクエストマッピングテンプレート内でバージョンを指定した場合、version の値は functionVersion フィールドの値によって書き換えられます。

2018-05-29

動作の変更

  • データソースの呼び出しの結果が null の場合は、レスポンスマッピングテンプレートが実行されます。

  • データソースの呼び出しでエラーが発生した場合、エラーを処理するのはお客様です。レスポンスマッピングテンプレートの評価結果は常に GraphQL レスポンスの data ブロック内に挿入されます。

理由

  • null の呼び出し結果には意味があり、アプリケーションのユースケースによっては、null の結果を独自の方法で処理することが必要になる場合があります。たとえば、アプリケーションで承認チェックを実行するために、Amazon DynamoDB テーブルにレコードが存在するかどうかを確認するとします。この場合、null の呼び出し結果は、ユーザーが承認されていない可能性があることを意味します。レスポンスマッピングテンプレートを実行することで、承認エラーを発生させることが可能になりました。この動作により、API 設計者はより強力な制御機能を得られます。

以下のレスポンスマッピングテンプレートがあるとします。

$util.toJson($ctx.result)

以前、2017-02-28 では、$ctx.result から null が返された場合、レスポンスマッピングテンプレートは実行されませんでした。2018-05-29 では、このシナリオを処理できるようになりました。たとえば、以下のように承認エラーを発生させることが可能です。

# throw an unauthorized error if the result is null #if ( $util.isNull($ctx.result) ) $util.unauthorized() #end $util.toJson($ctx.result)

注意: データソースから返されるエラーの中には、致命的でないものがあり、予期できないものもあります。そのため、レスポンスマッピングテンプレートには、呼び出しエラーを処理して、無視するか、再発生させるか、別のエラーをスローするかを判断する柔軟性が必要になります。

以下のレスポンスマッピングテンプレートがあるとします。

$util.toJson($ctx.result)

以前、2017-02-28 では、呼び出しエラーが発生した場合にレスポンスマッピングテンプレートが評価され、結果は GraphQL レスポンスの errors ブロックに自動的に挿入されていました。2018-05-29 では、エラーをどう処理するか、再発生させるか、別のエラーを発生させるか、またはデータを返すときにエラーを付加するかを選択できるようになりました。

呼び出しエラーを再発生させる

以下のレスポンステンプレートでは、データソースから返されたものと同じエラーを発生させます。

#if ( $ctx.error ) $util.error($ctx.error.message, $ctx.error.type) #end $util.toJson($ctx.result)

呼び出しエラー ($ctx.error など) の場合、レスポンスは以下のようになります。

{ "data": { "getPost": null }, "errors": [ { "path": [ "getPost" ], "errorType": "DynamoDB:ConditionalCheckFailedException", "message": "Conditional check failed exception...", "locations": [ { "line": 5, "column": 5 } ] } ] }

別のエラーを発生させる

以下のレスポンステンプレートでは、データソースから返されたエラーを処理した後で、カスタムエラーを発生させます。

#if ( $ctx.error ) #if ( $ctx.error.type.equals("ConditionalCheckFailedException") ) ## we choose here to change the type and message of the error for ConditionalCheckFailedExceptions $util.error("Error while updating the post, try again. Error: $ctx.error.message", "UpdateError") #else $util.error($ctx.error.message, $ctx.error.type) #end #end $util.toJson($ctx.result)

呼び出しエラー ($ctx.error など) の場合、レスポンスは以下のようになります。

{ "data": { "getPost": null }, "errors": [ { "path": [ "getPost" ], "errorType": "UpdateError", "message": "Error while updating the post, try again. Error: Conditional check failed exception...", "locations": [ { "line": 5, "column": 5 } ] } ] }

データを返すときにエラーを付加する

以下のレスポンステンプレートでは、レスポンス内でデータを返すときに、データソースから返されたものと同じエラーを追加します。これは、部分レスポンスとも呼ばれます。

#if ( $ctx.error ) $util.appendError($ctx.error.message, $ctx.error.type) #set($defaultPost = {id: "1", title: 'default post'}) $util.toJson($defaultPost) #else $util.toJson($ctx.result) #end

呼び出しエラー ($ctx.error など) の場合、レスポンスは以下のようになります。

{ "data": { "getPost": { "id": "1", "title: "A post" } }, "errors": [ { "path": [ "getPost" ], "errorType": "ConditionalCheckFailedException", "message": "Conditional check failed exception...", "locations": [ { "line": 5, "column": 5 } ] } ] }

2017-02-28 から 2018-05-29 への移行

2017-02-28 から 2018-05-29 への移行は簡単です。リゾルバーのリクエストマッピングテンプレートの version フィールドまたは関数の version オブジェクトを変更します。ただし、2018-05-292017-02-28 では実行動作が異なるため、変更点についてこちらで概要を説明しています。

2017-02-28 から 2018-05-29 への同じ実行動作の保持

場合によっては、同じ実行動作を保持できる場合もあります。tたとえば2018-05-29バージョン管理されたテンプレートを実行しながら2017-02-28を実行することが可能です。

例: DynamoDB PutItem

以下の 2017-02-28 DynamoDB PutItem リクエストテンプレートがあるとします。

{ "version" : "2017-02-28", "operation" : "PutItem", "key": { "foo" : ... typed value, "bar" : ... typed value }, "attributeValues" : { "baz" : ... typed value }, "condition" : { ... } }

また、以下のレスポンステンプレートがあるとします。

$util.toJson($ctx.result)

2018-05-29 に移行すると、これらのテンプレートは以下のように変更されます。

{ "version" : "2018-05-29", ## Note the new 2018-05-29 version "operation" : "PutItem", "key": { "foo" : ... typed value, "bar" : ... typed value }, "attributeValues" : { "baz" : ... typed value }, "condition" : { ... } }

また、レスポンステンプレートは以下のように変更されます。

## If there is a datasource invocation error, we choose to raise the same error ## the field data will be set to null. #if($ctx.error) $util.error($ctx.error.message, $ctx.error.type, $ctx.result) #end ## If the data source invocation is null, we return null. #if($util.isNull($ctx.result)) #return #end $util.toJson($ctx.result)

エラーを処理するのはお客様であるため、DynamoDB から返された $util.error() を使用して同じエラーが発生するようにしました。マッピングテンプレートを 2018-05-29 に変換するようにこのスニペットを調整できます。レスポンステンプレートが異なる場合は、実行動作が変わることを考慮する必要があります。

例: DynamoDB GetItem

以下の 2017-02-28 DynamoDB GetItem リクエストテンプレートがあるとします。

{ "version" : "2017-02-28", "operation" : "GetItem", "key" : { "foo" : ... typed value, "bar" : ... typed value }, "consistentRead" : true }

また、以下のレスポンステンプレートがあるとします。

## map table attribute postId to field Post.id $util.qr($ctx.result.put("id", $ctx.result.get("postId"))) $util.toJson($ctx.result)

2018-05-29 に移行すると、これらのテンプレートは以下のように変更されます。

{ "version" : "2018-05-29", ## Note the new 2018-05-29 version "operation" : "GetItem", "key" : { "foo" : ... typed value, "bar" : ... typed value }, "consistentRead" : true }

また、レスポンステンプレートは以下のように変更されます。

## If there is a datasource invocation error, we choose to raise the same error #if($ctx.error) $util.error($ctx.error.message, $ctx.error.type) #end ## If the data source invocation is null, we return null. #if($util.isNull($ctx.result)) #return #end ## map table attribute postId to field Post.id $util.qr($ctx.result.put("id", $ctx.result.get("postId"))) $util.toJson($ctx.result)

2017-02-28 バージョンでは、データソースの呼び出しが null の場合は、DynamoDB テーブルにキーと一致する項目がないことを意味します。そのため、レスポンスマッピングテンプレートは実行されません。ほとんどの場合は問題ありませんが、$ctx.resultnull ではないと想定される場合は、そのシナリオを処理する必要があります。

2017-02-28

特性

  • データソースの呼び出し結果が null の場合、レスポンスマッピングテンプレートは実行されません

  • データソースの呼び出しでエラーが発生した場合、レスポンスマッピングテンプレートは実行され、評価結果は GraphQL レスポンスの errors.data ブロック内に挿入されます。