AWS AppSync Lambda のリゾルバーマッピングテンプレートリファレンス - AWS AppSync

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

AWS AppSync Lambda のリゾルバーマッピングテンプレートリファレンス

注記

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

AWS AppSync 関数とリゾルバーを使用して、 アカウントにある Lambda 関数を呼び出すことができます。リクエストペイロードと Lambda 関数からのレスポンスは、クライアントに返す前に形成できます。マッピングテンプレートを使用して、呼び出すオペレーションの性質 AWS AppSync に関するヒントを提供することもできます。このセクションでは、サポートされる Lambda 操作用の異なるマッピングテンプレートについて説明します。

リクエストマッピングテンプレート

Lambda リクエストマッピングテンプレートは、Lambda 関数に関連するフィールドを処理します。

{ "version": string, "operation": Invoke|BatchInvoke, "payload": any type, "invocationType": RequestResponse|Event }

これは、解決された Lambda リクエストマッピングテンプレートのJSONスキーマ表現です。

{ "definitions": {}, "$schema": "https://json-schema.org/draft-06/schema#", "$id": "https://aws.amazon.com/appsync/request-mapping-template.json", "type": "object", "properties": { "version": { "$id": "/properties/version", "type": "string", "enum": [ "2018-05-29" ], "title": "The Mapping template version.", "default": "2018-05-29" }, "operation": { "$id": "/properties/operation", "type": "string", "enum": [ "Invoke", "BatchInvoke" ], "title": "The Mapping template operation.", "description": "What operation to execute.", "default": "Invoke" }, "payload": {}, "invocationType": { "$id": "/properties/invocationType", "type": "string", "enum": [ "RequestResponse", "Event" ], "title": "The Mapping template invocation type.", "description": "What invocation type to execute.", "default": "RequestResponse" } }, "required": [ "version", "operation" ], "additionalProperties": false }

以下は、ペイロードデータが GraphQL スキーマのgetPostフィールドであり、コンテキストからの引数を含む invokeオペレーションを使用する例です。

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

マッピングドキュメント全体が Lambda 関数への入力として渡されるため、前の例は次のようになります。

{ "version": "2018-05-29", "operation": "Invoke", "payload": { "field": "getPost", "arguments": { "id": "postId1" } } }

Version

すべてのリクエストマッピングテンプレートに共通して、 はテンプレートが使用するバージョンversionを定義します。version は必須で、静的な値です。

"version": "2018-05-29"

操作

Lambda データソースを使用すると、 operationフィールドで Invokeと の 2 つのオペレーションを定義できますBatchInvoke。このInvokeオペレーションでは、 がすべての GraphQL フィールドリゾルバーに対して Lambda 関数を呼び出すことを AWS AppSync に知らせます。 は、現在の GraphQL フィールドのバッチリクエスト AWS AppSync をBatchInvoke指示します。operation フィールドは必須です。

の場合Invoke、解決されたリクエストマッピングテンプレートは Lambda 関数の入力ペイロードと一致します。上記の例を変更してみましょう。

{ "version": "2018-05-29", "operation": "Invoke", "payload": { "arguments": $util.toJson($context.arguments) } }

これは解決され、Lambda 関数に渡されます。この関数は次のようになります。

{ "version": "2018-05-29", "operation": "Invoke", "payload": { "arguments": { "id": "postId1" } } }

の場合BatchInvoke、マッピングテンプレートはバッチ内のすべてのフィールドリゾルバーに適用されます。簡潔にするために、解決されたマッピングテンプレートのすべてのpayload値を、マッピングテンプレートに一致する単一のオブジェクトの下のリストに AWS AppSync マージします。次のサンプルテンプレートは、マージを示します。

{ "version": "2018-05-29", "operation": "BatchInvoke", "payload": $util.toJson($context) }

このテンプレートは、次のマッピングドキュメントに解決されます。

{ "version": "2018-05-29", "operation": "BatchInvoke", "payload": [ {...}, // context for batch item 1 {...}, // context for batch item 2 {...} // context for batch item 3 ] }

payload リストの各要素は、単一のバッチ項目に対応します。Lambda 関数は、リクエストで送信された項目の順序に一致するリスト形式のレスポンスも返す予定です。

[ { "data": {...}, "errorMessage": null, "errorType": null }, // result for batch item 1 { "data": {...}, "errorMessage": null, "errorType": null }, // result for batch item 2 { "data": {...}, "errorMessage": null, "errorType": null } // result for batch item 3 ]

ペイロード

payload フィールドは、任意のウェルフォームを Lambda 関数JSONに渡すために使用されるコンテナです。operation フィールドが に設定されている場合BatchInvoke、 は既存のpayload値をリストに AWS AppSync ラップします。payload フィールドはオプションです。

呼び出しタイプ

Lambda データソースでは、 RequestResponseと の 2 つの呼び出しタイプを定義できますEvent。呼び出しタイプは、Lambda APIで定義されている呼び出しタイプと同義です。RequestResponse 呼び出しタイプを使用すると、Lambda 関数を同期的に AWS AppSync 呼び出してレスポンスを待つことができます。Event 呼び出しでは、Lambda 関数を非同期的に呼び出すことができます。Lambda がEvent呼び出しタイプのリクエストを処理する方法の詳細については、「非同期呼び出し」を参照してください。invocationType フィールドはオプションです。このフィールドがリクエストに含まれていない場合、 AWS AppSync はデフォルトでRequestResponse呼び出しタイプになります。

どのinvocationTypeフィールドでも、解決されたリクエストは Lambda 関数の入力ペイロードと一致します。上記の例を変更してみましょう。

{ "version": "2018-05-29", "operation": "Invoke", "invocationType": "Event" "payload": { "arguments": $util.toJson($context.arguments) } }

これは解決され、Lambda 関数に渡されます。この関数は次のようになります。

{ "version": "2018-05-29", "operation": "Invoke", "invocationType": "Event", "payload": { "arguments": { "id": "postId1" } } }

BatchInvoke オペレーションをEvent呼び出しタイプフィールドと組み合わせて使用する場合、 は上記の方法と同じ方法でフィールドリゾルバーを AWS AppSync マージし、リクエストは を値payloadのリストとする非同期イベントとして Lambda 関数に渡されます。Event 呼び出しタイプのリゾルバーのリゾルバーキャッシュは、キャッシュヒットがあった場合に Lambda に送信されないため、無効にすることをお勧めします。

レスポンスマッピングテンプレート

他のデータソースと同様に、Lambda 関数は、GraphQL タイプに変換 AWS AppSync する必要があるレスポンスを に送信します。

Lambda 関数の結果は、Velocity Template Language (VTL) $context.resultプロパティを介して利用可能なcontextオブジェクトで設定されます。

Lambda 関数のレスポンスの形状と GraphQL タイプの形状が正確に一致する場合は、以下のレスポンスマッピングテンプレートを使用して、レスポンスを転送できます。

$util.toJson($context.result)

レスポンスマッピングテンプレートに適用される形状の制限や必須フィールドはありません。ただし、GraphQL が厳密に型指定されているので、解決されたマッピングテンプレートは予想される GraphQL タイプに一致する必要があります。

Lambda 関数のバッチ処理されたレスポンス

operation フィールドが に設定されている場合BatchInvoke、 AWS AppSync は Lambda 関数から返される項目のリストを期待します。 AWS AppSync が各結果を元のリクエスト項目にマッピングするには、レスポンスリストのサイズと順序が一致している必要があります。応答リストにnull項目を含めることは有効です。それに応じて null$ctx.result設定されます。

ダイレクトLambda リゾルバー

マッピングテンプレートの使用を完全に回避する場合は、Lambda 関数にデフォルトのペイロードを提供し、GraphQL タイプにデフォルトの Lambda 関数レスポンスを提供 AWS AppSync できます。リクエストテンプレート、レスポンステンプレート、またはどちらも指定せず、それに応じて AWS AppSync 処理することもできます。

ダイレクト Lambda リクエストマッピングテンプレート

リクエストマッピングテンプレートが指定されていない場合、 AWS AppSync は Invokeオペレーションとして Lambda 関数に直接Contextオブジェクトを送信します。Context オブジェクトの構造の詳細については、「AWS AppSync リゾルバーマッピングテンプレートコンテキストリファレンス」を参照してください。

ダイレクト Lambda レスポンスマッピングテンプレート

レスポンスマッピングテンプレートが指定されていない場合、Lambda 関数のレスポンスを受信すると、 は 2 つのことのいずれか AWS AppSync を行います。リクエストマッピングテンプレートを指定しなかった場合、または バージョン でリクエストマッピングテンプレートを指定した場合2018-05-29、レスポンスは次のレスポンスマッピングテンプレートと同等になります。

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

バージョン でテンプレートを指定した場合2017-02-28、レスポンスロジックは次のレスポンスマッピングテンプレートと同等に機能します。

$util.toJson($ctx.result)

表面的には、マッピングテンプレートバイパスは、前の例に示すように、特定のマッピングテンプレートを使用するのと同様に動作します。ただし、裏では、マッピングテンプレートの評価は完全に回避されます。テンプレート評価ステップはバイパスされるため、アプリケーションは、評価する必要があるレスポンスマッピングテンプレートを持つ Lambda 関数と比較して、一部のシナリオでレスポンス中にオーバーヘッドとレイテンシーを経験するかもしれません。

ダイレクト Lambda リゾルバーレスポンスのカスタムエラー処理

カスタム例外を発生させることにより、ダイレクト Lambda リゾルバーによって呼び出される Lambda 関数からのエラーレスポンスをカスタマイズできます。次の例は、 を使用してカスタム例外を作成する方法を示しています JavaScript。

class CustomException extends Error { constructor(message) { super(message); this.name = "CustomException"; } } throw new CustomException("Custom message");

例外が発生すると、errorTypeerrorMessage が、それぞれ個別に、スローされるカスタムエラーの namemessage になります。

errorType が の場合UnauthorizedException、 AWS AppSync はカスタムメッセージの代わりにデフォルトのメッセージ ("You are not authorized to make this call.") を返します。

次のスニペットは、カスタム を示す GraphQL レスポンスの例ですerrorType

{ "data": { "query": null }, "errors": [ { "path": [ "query" ], "data": null, "errorType": "CustomException", "errorInfo": null, "locations": [ { "line": 5, "column": 10, "sourceName": null } ], "message": "Custom Message" } ] }

ダイレクト Lambda リゾルバー: バッチ処理が有効

Direct Lambda リゾルバーのバッチ処理を有効にするには、リゾルバーで maxBatchSize を設定します。maxBatchSize が Direct Lambda リゾルバー0の より大きい値に設定されている場合、 は最大 のサイズで Lambda 関数にリクエストをバッチで AWS AppSync 送信しますmaxBatchSize

Direct Lambda リゾルバー0maxBatchSize を に設定すると、バッチ処理はオフになります。

Lambda リゾルバーによるバッチ処理の仕組みの詳細については、「高度なユースケース: バッチ処理」を参照してください。

リクエストマッピングテンプレート

バッチ処理が有効で、リクエストマッピングテンプレートが指定されていない場合、 はContextオブジェクトのリストをBatchInvokeオペレーションとして Lambda 関数に直接 AWS AppSync 送信します。

レスポンスマッピングテンプレート

バッチ処理が有効で、レスポンスマッピングテンプレートが提供されていない場合、レスポンスロジックは次のレスポンスマッピングテンプレートと同様に機能します。

#if( $context.result && $context.result.errorMessage ) $utils.error($context.result.errorMessage, $context.result.errorType, $context.result.data) #else $utils.toJson($context.result.data) #end

Lambda 関数は、送信された Context オブジェクトのリストと同じ順序で結果のリストを返す必要があります。特定の結果に対して errorMessageerrorTypeを指定することで、個々のエラーを返すことができます。リストの各結果には、次の形式があります。

{ "data" : { ... }, // your data "errorMessage" : { ... }, // optional, if included an error entry is added to the "errors" object in the AppSync response "errorType" : { ... } // optional, the error type }
注記

結果オブジェクトの他のフィールドは現時点では無視されます。

Lambda からのエラーの処理

Lambda 関数に例外またはエラーを投げると、すべての結果に対してエラーを返すことができます。バッチリクエストのペイロードリクエストまたはレスポンスサイズが大きすぎる場合、Lambda はエラーを返します。その場合は、maxBatchSize を小さくするか、レスポンスペイロードのサイズを小さくすることを検討してください。

個別のエラー処理については、「個々のエラーを返す」を参照してください。

サンプル Lambda 関数

以下のスキーマを使用して、Post.relatedPostsフィールドリゾルバーの Direct Lambda Resolver を作成し、maxBatchSize上記の を設定してバッチ処理を有効にすることができます0

schema { query: Query mutation: Mutation } type Query { getPost(id:ID!): Post allPosts: [Post] } type Mutation { addPost(id: ID!, author: String!, title: String, content: String, url: String): Post! } type Post { id: ID! author: String! title: String content: String url: String ups: Int downs: Int relatedPosts: [Post] }

次のクエリでは、relatedPosts を解決するリクエストのバッチとともに Lambda 関数が呼び出されます。

query getAllPosts { allPosts { id relatedPosts { id } } }

Lambda 関数の簡単な実装を以下に示します。

const posts = { 1: { id: '1', title: 'First book', author: 'Author1', url: 'https://amazon.com/', content: 'SAMPLE TEXT AUTHOR 1 SAMPLE TEXT AUTHOR 1 SAMPLE TEXT AUTHOR 1 SAMPLE TEXT AUTHOR 1 SAMPLE TEXT AUTHOR 1 SAMPLE TEXT AUTHOR 1', ups: '100', downs: '10', }, 2: { id: '2', title: 'Second book', author: 'Author2', url: 'https://amazon.com', content: 'SAMPLE TEXT AUTHOR 2 SAMPLE TEXT AUTHOR 2 SAMPLE TEXT', ups: '100', downs: '10', }, 3: { id: '3', title: 'Third book', author: 'Author3', url: null, content: null, ups: null, downs: null }, 4: { id: '4', title: 'Fourth book', author: 'Author4', url: 'https://www.amazon.com/', content: 'SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4', ups: '1000', downs: '0', }, 5: { id: '5', title: 'Fifth book', author: 'Author5', url: 'https://www.amazon.com/', content: 'SAMPLE TEXT AUTHOR 5 SAMPLE TEXT AUTHOR 5 SAMPLE TEXT AUTHOR 5 SAMPLE TEXT AUTHOR 5 SAMPLE TEXT', ups: '50', downs: '0', }, } const relatedPosts = { 1: [posts['4']], 2: [posts['3'], posts['5']], 3: [posts['2'], posts['1']], 4: [posts['2'], posts['1']], 5: [], } exports.handler = async (event) => { console.log('event ->', event) // retrieve the ID of each post const ids = event.map((context) => context.source.id) // fetch the related posts for each post id const related = ids.map((id) => relatedPosts[id]) // return the related posts; or an error if none were found return related.map((r) => { if (r.length > 0) { return { data: r } } else { return { data: null, errorMessage: 'Not found', errorType: 'ERROR' } } }) }