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-29 と 2017-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.result
が null
ではないと想定される場合は、そのシナリオを処理する必要があります。
2017-02-28
特性
-
データソースの呼び出し結果が
null
の場合、レスポンスマッピングテンプレートは実行されません。 -
データソースの呼び出しでエラーが発生した場合、レスポンスマッピングテンプレートは実行され、評価結果は GraphQL レスポンスの
errors.data
ブロック内に挿入されます。