での DynamoDB バッチオペレーションの使用 AWS AppSync - AWS AppSync

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

での DynamoDB バッチオペレーションの使用 AWS AppSync

AWS AppSync は、1 つのリージョン内の 1 つ以上のテーブルで Amazon DynamoDB バッチオペレーションの使用をサポートします。サポートされている処理は、BatchGetItemBatchPutItem、および BatchDeleteItem です。でこれらの機能を使用すると AWS AppSync、次のようなタスクを実行できます。

  • 単一クエリでキーのリストを渡し、テーブルからの結果を返す

  • 単一クエリで 1 つ以上のテーブルからレコードを読み取る

  • 1 つ以上のテーブルに一連のレコードを書き込む

  • 関連のある複数のテーブルのレコードを状況に応じて書き込む、または削除する

のバッチオペレーション AWS AppSync には、非バッチオペレーションと 2 つの重要な違いがあります。

  • データソースのロールには、リゾルバーがアクセスするすべてのテーブルについてアクセス許可が必要です。

  • リゾルバーのテーブル仕様はリクエストオブジェクトに含まれます。

1 つのテーブルのバッチ処理

警告

BatchPutItem および BatchDeleteItem は、競合の検出と解決とともに使用する場合はサポートされていません。これらの設定は、起こり得るエラーを防ぐために無効にする必要があります。

開始するには、新しい GraphQL を作成しましょうAPI。 AWS AppSync コンソールで、Create APIGraphQL APIs、および Design from scratch を選択します。に名前を付けAPIBatchTutorial API次へ を選択しGraphQL リソースの指定ステップで、後で GraphQL リソースの作成 を選択し、次へ をクリックします。詳細を確認し、 を作成しますAPI。スキーマページに移動し、次のスキーマを貼り付けます。クエリでは、 のリストが渡されますIDs。

type Post { id: ID! title: String } input PostInput { id: ID! title: String } type Query { batchGet(ids: [ID]): [Post] } type Mutation { batchAdd(posts: [PostInput]): [Post] batchDelete(ids: [ID]): [Post] }

スキーマを保存した後、ページ上部の [リソースを作成] を選択します。[既存のタイプを使用] を選択し、Post タイプを選択します。Posts テーブルに名前を付けます。プライマリキーid に設定されていることを確認し、「GraphQL を自動生成」を選択解除し (独自のコードを指定します)、「作成」を選択します。はじめに、 AWS AppSync で新しい DynamoDB テーブルを作成し、そのテーブルに適切なロールで接続されたデータソースを作成します。ただし、ロールに追加する必要のあるアクセス許可がまだいくつかあります。[データソース] ページに移動し、新しいデータソースを選択します。[既存のロールを選択] で、テーブルのロールが自動的に作成されたことがわかります。ロールを書き留めて ( のような外観)、IAMコンソール (appsync-ds-ddb-aaabbbcccddd-Posts) に移動しますhttps://console.aws.amazon.com/iam/。IAM コンソールで、ロール を選択し、テーブルからロールを選択します。自身のロールの [アクセス許可ポリシー] で、ポリシーの横にある [+] をクリックします (ロール名と似た名前になっているはずです)。ポリシーが表示されたら、折りたたみ可能なウィンドウの上部にある [編集] を選択します。ポリシーにバッチ許可、具体的にはdynamodb:BatchGetItemdynamodb:BatchWriteItem を追加する必要があります。次のように表示されます。

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "dynamodb:DeleteItem", "dynamodb:GetItem", "dynamodb:PutItem", "dynamodb:Query", "dynamodb:Scan", "dynamodb:UpdateItem", "dynamodb:BatchWriteItem", "dynamodb:BatchGetItem" ], "Resource": [ "arn:aws:dynamodb:…", "arn:aws:dynamodb:…" ] } ] }

[次へ] を選択し、[変更を保存] を選択します。これで、ポリシーでバッチ処理が許可されるはずです。

AWS AppSync コンソールに戻り、スキーマページに移動し、Mutation.batchAddフィールドの横にあるアタッチを選択します。Posts テーブルをデータソースとして使用してリゾルバーを作成します。コードエディターで、ハンドラーを以下のスニペットに置き換えます。これは自動的に GraphQL の input PostInput 型に各項目を渡し、マップを作成します。このマップは BatchPutItem オペレーションに必要になります。

import { util } from "@aws-appsync/utils"; export function request(ctx) { return { operation: "BatchPutItem", tables: { Posts: ctx.args.posts.map((post) => util.dynamodb.toMapValues(post)), }, }; } export function response(ctx) { if (ctx.error) { util.error(ctx.error.message, ctx.error.type); } return ctx.result.data.Posts; }

AWS AppSync コンソールのクエリページに移動し、次のbatchAddミューテーションを実行します。

mutation add { batchAdd(posts:[{ id: 1 title: "Running in the Park"},{ id: 2 title: "Playing fetch" }]){ id title } }

結果が画面に表示されるはずです。これは、DynamoDB コンソールを確認して、Posts テーブルに書き込まれた値をスキャンすることで検証できます。

次に、Posts テーブルをデータソースとして使用する Query.batchGet フィールドに対してリゾルバーをアタッチするプロセスを繰り返します。ハンドラーを以下のコードに置き換えます。これは自動的に GraphQL の ids:[] 型に各項目を渡し、マップを作成します。このマップは BatchGetItem の処理に必要になります。

import { util } from "@aws-appsync/utils"; export function request(ctx) { return { operation: "BatchGetItem", tables: { Posts: { keys: ctx.args.ids.map((id) => util.dynamodb.toMapValues({ id })), consistentRead: true, }, }, }; } export function response(ctx) { if (ctx.error) { util.error(ctx.error.message, ctx.error.type); } return ctx.result.data.Posts; }

次に、 AWS AppSync コンソールのクエリページに戻り、次のbatchGetクエリを実行します。

query get { batchGet(ids:[1,2,3]){ id title } }

これは、以前に追加した 2 つの id 値の結果を返します。値が nullid に対して 3 値が返っていることに注意してください。これは、その値に対応するレコードが Posts テーブルにまだないためです。また、 はクエリに渡されたキーと同じ順序で結果 AWS AppSync を返します。これはユーザーに代わって AWS AppSync 実行される追加機能です。したがって、batchGet(ids:[1,3,2]) に変更すると、順番が代わります。どの idnull 値が返されたのかもこれで分かります。

最後に、Posts テーブルをデータソースとして使用して、Mutation.batchDelete フィールドにもう 1 つリゾルバーをアタッチします。ハンドラーを以下のコードに置き換えます。これは自動的に GraphQL の ids:[] 型に各項目を渡し、マップを作成します。このマップは BatchGetItem の処理に必要になります。

import { util } from "@aws-appsync/utils"; export function request(ctx) { return { operation: "BatchDeleteItem", tables: { Posts: ctx.args.ids.map((id) => util.dynamodb.toMapValues({ id })), }, }; } export function response(ctx) { if (ctx.error) { util.error(ctx.error.message, ctx.error.type); } return ctx.result.data.Posts; }

次に、 AWS AppSync コンソールのクエリページに戻り、次のbatchDeleteミューテーションを実行します。

mutation delete { batchDelete(ids:[1,2]){ id } }

id12 のレコードが削除されます。以前に使用した batchGet() クエリを再実行すると、これらは null を返します。

複数テーブルのバッチ処理

警告

BatchPutItem および BatchDeleteItem は、競合の検出と解決とともに使用する場合はサポートされていません。これらの設定は、起こり得るエラーを防ぐために無効にする必要があります。

AWS AppSync では、テーブル間でバッチオペレーションを実行することもできます。より複雑なアプリケーションを作成しましょう。Pet Health アプリを作成するとします。これは、センサーによりペットの場所と体温を報告します。センサーは電池により動作し、数分ごとにネットワークへの接続を試みます。センサーが接続を確立すると、センサーは測定値を に送信します AWS AppSync API。その後、データの分析がトリガーされ、ペットの飼い主にダッシュボードが表示されます。センサーとバックエンドのデータストア間のやり取りの作成について考えてみましょう。

AWS AppSync コンソールで、Create APIGraphQL APIs、および Design from scratch を選択します。に名前を付けAPIMultiBatchTutorial API次へ を選択し、GraphQL リソースの指定ステップで、後で GraphQL リソースの作成 を選択し、次へ をクリックします。詳細を確認し、 を作成しますAPI。「スキーマ」ページに移動し、次のスキーマを貼り付けて保存します。

type Mutation { # Register a batch of readings recordReadings(tempReadings: [TemperatureReadingInput], locReadings: [LocationReadingInput]): RecordResult # Delete a batch of readings deleteReadings(tempReadings: [TemperatureReadingInput], locReadings: [LocationReadingInput]): RecordResult } type Query { # Retrieve all possible readings recorded by a sensor at a specific time getReadings(sensorId: ID!, timestamp: String!): [SensorReading] } type RecordResult { temperatureReadings: [TemperatureReading] locationReadings: [LocationReading] } interface SensorReading { sensorId: ID! timestamp: String! } # Sensor reading representing the sensor temperature (in Fahrenheit) type TemperatureReading implements SensorReading { sensorId: ID! timestamp: String! value: Float } # Sensor reading representing the sensor location (lat,long) type LocationReading implements SensorReading { sensorId: ID! timestamp: String! lat: Float long: Float } input TemperatureReadingInput { sensorId: ID! timestamp: String value: Float } input LocationReadingInput { sensorId: ID! timestamp: String lat: Float long: Float }

次の 2 つの DynamoDB テーブルを作成する必要があります。

  • locationReadings はセンサー位置の読み取り値を格納します。

  • temperatureReadings はセンサーの温度測定値を保存します。

両方のテーブルで同じプライマリキー構造体を共有します。sensorId (String) はパーティションキーで、timestamp (String) がソートキーです。

ページの上部で、[リソースの作成] を選択します。[既存のタイプを使用] を選択し、locationReadings タイプを選択します。locationReadings テーブルに名前を付けてください。プライマリキーsensorId に、ソートキーが timestamp に設定されていることを確認します。[GraphQL を自動的に生成する] (独自のコードを指定します) を選択解除し、[作成] を選択します。temperatureReadings をタイプとテーブル名として使用し,temperatureReadings に対してこのプロセスを繰り返して、ます。上記と同じキーを使用してください。

新しいテーブルには、自動的に生成されたロールが含まれます。これらのロールには、まだ追加する必要のあるアクセス許可がいくつかあります。データソースページに移動し、locationReadings を選択します。[既存のロールを選択] に、そのロールが表示されます。ロールを書き留めて ( のような外観)、IAMコンソール (appsync-ds-ddb-aaabbbcccddd-locationReadings) に移動しますhttps://console.aws.amazon.com/iam/。IAM コンソールで、ロール を選択し、テーブルからロールを選択します。自身のロールの [アクセス許可ポリシー] で、ポリシーの横にある [+] をクリックします (ロール名と似た名前になっているはずです)。ポリシーが表示されたら、折りたたみ可能なウィンドウの上部にある [編集] を選択します。このポリシーにアクセス許可を追加する必要があります。次のように表示されます。

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "dynamodb:DeleteItem", "dynamodb:GetItem", "dynamodb:PutItem", "dynamodb:Query", "dynamodb:Scan", "dynamodb:UpdateItem", "dynamodb:BatchGetItem", "dynamodb:BatchWriteItem" ], "Resource": [ "arn:aws:dynamodb:region:account:table/locationReadings", "arn:aws:dynamodb:region:account:table/locationReadings/*", "arn:aws:dynamodb:region:account:table/temperatureReadings", "arn:aws:dynamodb:region:account:table/temperatureReadings/*" ] } ] }

[次へ] を選択し、[変更を保存] を選択します。上記と同じポリシースニペットを使用して、temperatureReadings データソースに対してこのプロセスを繰り返します。

BatchPutItem - センサーの読み取り値の記録

センサーは、インターネットに接続後、読み取り値を送信できる必要があります。GraphQL フィールドMutation.recordReadingsはAPI、これを行うために使用されるフィールドです。このフィールドにリゾルバーを追加する必要があります。

AWS AppSync コンソールのスキーマページで、 Mutation.recordReadings フィールドの横にあるアタッチを選択します。次の画面で、locationReadings テーブルをデータソースとして使用してリゾルバーを作成します。

リゾルバーを作成したら、エディタでハンドラーを次のコードに置き換えます。このBatchPutItem操作により、複数のテーブルを指定できます。

import { util } from '@aws-appsync/utils' export function request(ctx) { const { locReadings, tempReadings } = ctx.args const locationReadings = locReadings.map((loc) => util.dynamodb.toMapValues(loc)) const temperatureReadings = tempReadings.map((tmp) => util.dynamodb.toMapValues(tmp)) return { operation: 'BatchPutItem', tables: { locationReadings, temperatureReadings, }, } } export function response(ctx) { if (ctx.error) { util.appendError(ctx.error.message, ctx.error.type) } return ctx.result.data }

バッチ処理では、呼び出しからエラーと結果の両方が返る可能性があります。その場合は、任意に追加のエラー処理を実行できます。

注記

utils.appendError() の使用法は util.error() と同様ですが、リクエストまたはレスポンスハンドラーの評価を中断しないという大きな違いがあります。代わりに、エラーが発生したことをフィールドで通知します。ただし、テンプレートを評価して、データを引き続き呼び出し元に返すことも可能です。アプリケーションで部分的な結果を返す必要がある場合は、utils.appendError() を使用することを推奨します。

リゾルバーを保存し、 AWS AppSync コンソールのクエリページに移動します。これで、センサーの読み取り値をいくつか送信できます。

次のミューテーションを実行します。

mutation sendReadings { recordReadings( tempReadings: [ {sensorId: 1, value: 85.5, timestamp: "2018-02-01T17:21:05.000+08:00"}, {sensorId: 1, value: 85.7, timestamp: "2018-02-01T17:21:06.000+08:00"}, {sensorId: 1, value: 85.8, timestamp: "2018-02-01T17:21:07.000+08:00"}, {sensorId: 1, value: 84.2, timestamp: "2018-02-01T17:21:08.000+08:00"}, {sensorId: 1, value: 81.5, timestamp: "2018-02-01T17:21:09.000+08:00"} ] locReadings: [ {sensorId: 1, lat: 47.615063, long: -122.333551, timestamp: "2018-02-01T17:21:05.000+08:00"}, {sensorId: 1, lat: 47.615163, long: -122.333552, timestamp: "2018-02-01T17:21:06.000+08:00"}, {sensorId: 1, lat: 47.615263, long: -122.333553, timestamp: "2018-02-01T17:21:07.000+08:00"}, {sensorId: 1, lat: 47.615363, long: -122.333554, timestamp: "2018-02-01T17:21:08.000+08:00"}, {sensorId: 1, lat: 47.615463, long: -122.333555, timestamp: "2018-02-01T17:21:09.000+08:00"} ]) { locationReadings { sensorId timestamp lat long } temperatureReadings { sensorId timestamp value } } }

1 つのミューテーションで 10 個のセンサー読み取り値を送信しました。これらは 2 つのテーブルに分けられています。DynamoDB コンソールを使用して、locationReadings テーブルと temperatureReadings テーブルの両方にデータが表示されることを確認します。

BatchDeleteItem - センサー読み取り値の削除

同様に、センサーの読み取り値を一括して削除する必要もあります。これを行うために、Mutation.deleteReadings GraphQL フィールドを使用してみましょう。 AWS AppSync コンソールのスキーマページで、 Mutation.deleteReadings フィールドの横にあるアタッチを選択します。次の画面で、locationReadings テーブルをデータソースとして使用してリゾルバーを作成します。

リゾルバーを作成したら、コードエディターのハンドラーを以下のスニペットに置き換えます。このリゾルバーでは、提供された入力から sensorIdtimestamp を抽出する補助関数マッパーを使用します。

import { util } from '@aws-appsync/utils' export function request(ctx) { const { locReadings, tempReadings } = ctx.args const mapper = ({ sensorId, timestamp }) => util.dynamodb.toMapValues({ sensorId, timestamp }) return { operation: 'BatchDeleteItem', tables: { locationReadings: locReadings.map(mapper), temperatureReadings: tempReadings.map(mapper), }, } } export function response(ctx) { if (ctx.error) { util.appendError(ctx.error.message, ctx.error.type) } return ctx.result.data }

リゾルバーを保存し、 AWS AppSync コンソールのクエリページに移動します。では、いくつかのセンサーの読み取り値を削除しましょう!

次のミューテーションを実行します。

mutation deleteReadings { # Let's delete the first two readings we recorded deleteReadings( tempReadings: [{sensorId: 1, timestamp: "2018-02-01T17:21:05.000+08:00"}] locReadings: [{sensorId: 1, timestamp: "2018-02-01T17:21:05.000+08:00"}]) { locationReadings { sensorId timestamp lat long } temperatureReadings { sensorId timestamp value } } }
注記

DeleteItem オペレーションとは対照的に、完全に削除された項目はレスポンスで返されません。渡されたキーのみが返されます。詳細については、BatchDeleteItem DynamoDB の JavaScript リゾルバー関数リファレンスの「」を参照してください。

DynamoDB コンソールを通じて locationReadings および temperatureReadings テーブルから削除されたこれら 2 つの読み取り値を検証します。

BatchGetItem - 読み取り値を取得する

アプリのもう 1 つの一般的な処理として、特定の時刻にセンサーの読み取り値を取得します。スキーマの Query.getReadings GraphQL フィールドにリゾルバーをアタッチしましょう。 AWS AppSync コンソールのスキーマページで、 Query.getReadings フィールドの横にあるアタッチを選択します。次の画面で、locationReadings テーブルをデータソースとして使用してリゾルバーを作成します。

以下のコードを使用します。

import { util } from '@aws-appsync/utils' export function request(ctx) { const keys = [util.dynamodb.toMapValues(ctx.args)] const consistentRead = true return { operation: 'BatchGetItem', tables: { locationReadings: { keys, consistentRead }, temperatureReadings: { keys, consistentRead }, }, } } export function response(ctx) { if (ctx.error) { util.appendError(ctx.error.message, ctx.error.type) } const { locationReadings: locs, temperatureReadings: temps } = ctx.result.data return [ ...locs.map((l) => ({ ...l, __typename: 'LocationReading' })), ...temps.map((t) => ({ ...t, __typename: 'TemperatureReading' })), ] }

リゾルバーを保存し、 AWS AppSync コンソールのクエリページに移動します。では、センサーの読み取り値を取得しましょう!

次のクエリを実行します。

query getReadingsForSensorAndTime { # Let's retrieve the very first two readings getReadings(sensorId: 1, timestamp: "2018-02-01T17:21:06.000+08:00") { sensorId timestamp ...on TemperatureReading { value } ...on LocationReading { lat long } } }

を使用した DynamoDB バッチオペレーションの使用を正常に実証しました AWS AppSync。

エラー処理

では AWS AppSync、データソースオペレーションが部分的な結果を返すことがあります。部分的な結果という用語は、処理の出力がいくつかのデータと 1 つのエラーで構成されていることを表す場合に使用します。エラー処理は本質的にアプリケーション固有のものであるため、 はレスポンスハンドラーのエラーを処理する機会 AWS AppSync を提供します。リゾルバーの呼び出しエラーがある場合、これは context から ctx.error として読み出せます。呼び出しエラーには必ずメッセージと型が含まれています。これらは ctx.error.messagectx.error.type というプロパティとしてアクセスできます。レスポンスハンドラーでは、部分的な結果を次の 3 つの方法で処理できます。

  1. データを返すだけで、呼び出しエラーは通知しない

  2. ハンドラーの評価を停止することでエラーを発生させる (util.error(...) を使用)。データは返さない。

  3. エラーを付加し (util.appendError(...) を使用)、データも返す

DynamoDB のバッチ処理を使用して、上記の 3 つの方法をそれぞれ試してみましょう!

DynamoDB のバッチ処理

DynamoDB のバッチ処理を使用すると、バッチを部分的に完了させることができます。つまり、リクエストされた項目またはキーの一部を未処理のままにすることができます。 AWS AppSync がバッチを完了できない場合、未処理の項目と呼び出しエラーがコンテキストに設定されます。

このチュートリアルの以前のセクションの Query.getReadings 処理で使用した BatchGetItem フィールドの設定を使用してエラー処理を実装します。ここでは、Query.getReadings フィールドの実行中に、temperatureReadings DynamoDB テーブルがプロビジョニングされたスループットを使い果たしたとします。DynamoDB は、バッチ内の残りの要素を処理する AWS AppSync ために によって 2 回目の試行ProvisionedThroughputExceededException中に を生成しました。

以下は、DynamoDB バッチ呼び出し後、レスポンスハンドラーが呼び出される前のシリアル化されたコンテキストJSONを表します。

{ "arguments": { "sensorId": "1", "timestamp": "2018-02-01T17:21:05.000+08:00" }, "source": null, "result": { "data": { "temperatureReadings": [ null ], "locationReadings": [ { "lat": 47.615063, "long": -122.333551, "sensorId": "1", "timestamp": "2018-02-01T17:21:05.000+08:00" } ] }, "unprocessedKeys": { "temperatureReadings": [ { "sensorId": "1", "timestamp": "2018-02-01T17:21:05.000+08:00" } ], "locationReadings": [] } }, "error": { "type": "DynamoDB:ProvisionedThroughputExceededException", "message": "You exceeded your maximum allowed provisioned throughput for a table or for one or more global secondary indexes. (...)" }, "outErrors": [] }

context に関する注意事項がいくつかあります。

  • 呼び出しエラーは、 ctx.errorによって のコンテキストに設定され AWS AppSync、エラータイプは に設定されていますDynamoDB:ProvisionedThroughputExceededException

  • エラーが存在していても、結果はテーブルごとに ctx.result.data にマッピングされます。

  • 未処理のキーは ctx.result.data.unprocessedKeys でアクセス可能です。ここでは、テーブルスループットが不十分なため、キー (sensorId:1、タイムスタンプ:2018-02-01T17:21:05.000+08:00) を持つ項目を取得 AWS AppSync できませんでした。

注記

BatchPutItem の場合、これは ctx.result.data.unprocessedItems です。BatchDeleteItem の場合、これは ctx.result.data.unprocessedKeys です。

3 つの異なる方法でこのエラーを処理しましょう。

1. 呼び出しエラーを通知しない

呼び出しエラーを処理せずにデータを返して、エラーを実質的に通知しません。指定した GraphQL フィールドの結果は常に成功とします。

記述するコードは通常どおりであり、結果のデータのみにフォーカスします。

レスポンスハンドラー

export function response(ctx) { return ctx.result.data }

GraphQL レスポンス

{ "data": { "getReadings": [ { "sensorId": "1", "timestamp": "2018-02-01T17:21:05.000+08:00", "lat": 47.615063, "long": -122.333551 }, { "sensorId": "1", "timestamp": "2018-02-01T17:21:05.000+08:00", "value": 85.5 } ] } }

データのみが有効なため、エラーレスポンスにエラーは追加されません。

2. エラーを発生させて、レスポンスハンドラーの実行を中止する

クライアントから見て、部分的な障害を完全な障害として扱う必要がある場合、レスポンスハンドラーの実行を中断することでデータの返送を抑制することができます。この動作には、util.error(...) ユーティリティメソッドを使用するのが最適です。

レスポンスハンドラーコード

export function response(ctx) { if (ctx.error) { util.error(ctx.error.message, ctx.error.type, null, ctx.result.data.unprocessedKeys); } return ctx.result.data; }

GraphQL レスポンス

{ "data": { "getReadings": null }, "errors": [ { "path": [ "getReadings" ], "data": null, "errorType": "DynamoDB:ProvisionedThroughputExceededException", "errorInfo": { "temperatureReadings": [ { "sensorId": "1", "timestamp": "2018-02-01T17:21:05.000+08:00" } ], "locationReadings": [] }, "locations": [ { "line": 58, "column": 3 } ], "message": "You exceeded your maximum allowed provisioned throughput for a table or for one or more global secondary indexes. (...)" } ] }

一部の結果が DynamoDB のバッチ処理から返されてもエラーが発生するように選択して、getReadings GraphQL フィールドが null になり、かつ GraphQL レスポンスの errors ブロックにエラーが追加されるようにします。

3. エラーを付加してデータとエラーの両方を返す

場合によっては、より優れたユーザーエクスペリエンスを提供するために、アプリケーションから部分的な結果を返すとともに、クライアントに未処理の項目を通知することができます。クライアントでは、再試行を実装することも、エラーを変換してエンドユーザーに通知することもできます。util.appendError(...) はこの動作を可能とするユーティリティメソッドであり、アプリケーションの設計者は、レスポンスハンドラーの評価を妨げることなく、context にエラーを付加できます。レスポンスハンドラーを評価した後、 AWS AppSync は GraphQL レスポンスのエラーブロックに追加することで、コンテキストエラーを処理します。

レスポンスハンドラーコード

export function response(ctx) { if (ctx.error) { util.appendError(ctx.error.message, ctx.error.type, null, ctx.result.data.unprocessedKeys); } return ctx.result.data; }

ここでは、GraphQL レスポンスのエラーブロック内の呼び出しエラーと unprocessedKeys 要素の両方が転送されています。以下のレスポンスで分かるとおり、getReadings フィールドもまた locationReadings テーブルから部分的なデータを返します。

GraphQL レスポンス

{ "data": { "getReadings": [ null, { "sensorId": "1", "timestamp": "2018-02-01T17:21:05.000+08:00", "value": 85.5 } ] }, "errors": [ { "path": [ "getReadings" ], "data": null, "errorType": "DynamoDB:ProvisionedThroughputExceededException", "errorInfo": { "temperatureReadings": [ { "sensorId": "1", "timestamp": "2018-02-01T17:21:05.000+08:00" } ], "locationReadings": [] }, "locations": [ { "line": 58, "column": 3 } ], "message": "You exceeded your maximum allowed provisioned throughput for a table or for one or more global secondary indexes. (...)" } ] }