기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.
에서 DynamoDB 배치 작업 사용 AWS AppSync
참고
이제 APPSYNC_JS 런타임과 해당 설명서를 주로 지원합니다. 여기에서 APPSYNC_JS 런타임 및 해당 가이드를 사용하는 것이 좋습니다.
AWS AppSync 는 단일 리전의 하나 이상의 테이블에서 Amazon DynamoDB 배치 작업 사용을 지원합니다. 지원되는 작업은 BatchGetItem
, BatchPutItem
및 BatchDeleteItem
입니다. 에서 이러한 기능을 사용하면 다음과 같은 작업을 수행할 AWS AppSync수 있습니다.
-
단일 쿼리에서 키 목록을 전달하고 테이블의 결과 반환
-
단일 쿼리의 하나 이상의 테이블에서 레코드 읽기
-
하나 이상의 테이블에 대량으로 레코드 쓰기
-
관계가 있을 수 있는 여러 테이블에서 조건부로 레코드 쓰기 또는 삭제
에서 DynamoDB로 배치 작업을 사용하는 AWS AppSync 것은 백엔드 작업 및 테이블 구조에 대한 약간의 추가 생각과 지식이 필요한 고급 기법입니다. 또한 의 배치 작업은 배치가 없는 작업과 두 가지 주요 차이점 AWS AppSync 이 있습니다.
-
데이터 원본 역할에 해석기가 액세스할 모든 테이블에 대한 권한이 있어야 합니다.
-
해석기에 대한 테이블 사양이 매핑 템플릿의 일부입니다.
권한
다른 해석기와 마찬가지로 에서 데이터 소스를 생성하고 역할을 생성 AWS AppSync 하거나 기존 소스를 사용해야 합니다. 배치 작업에는 DynamoDB 테이블에 대한 여러 권한이 필요하기 때문에 읽기 또는 쓰기 작업에 대해 구성된 역할 권한을 부여해야 합니다.
{ "Version": "2012-10-17", "Statement": [ { "Action": [ "dynamodb:BatchGetItem", "dynamodb:BatchWriteItem" ], "Effect": "Allow", "Resource": [ "arn:aws:dynamodb:region:account:table/TABLENAME", "arn:aws:dynamodb:region:account:table/TABLENAME/*" ] } ] }
참고 : 역할은 의 데이터 소스와 연결 AWS AppSync되며 필드의 해석기는 데이터 소스에 대해 호출됩니다. DynamoDB에 대해 가져오도록 구성된 데이터 소스에는 구성을 간단하기 유지하기 위해 지정된 테이블이 하나뿐입니다. 따라서 단일 해석기에서 여러 테이블에 대해 배치 작업을 수행하는 경우(고급 작업임) 데이터 원본 액세스에 대한 역할을 해석기가 상호 작용하는 모든 테이블에 부여해야 합니다. 이는 위의 IAM 정책의 리소스 필드에서 수행됩니다. 배치 호출을 수행하려는 테이블의 구성은 해석기 템플릿에서 수행되는데, 이 내용은 아래에서 설명합니다.
데이터 원본
간단하게 설명하기 위해 이 자습서에서 사용되는 모든 해석기에 대해 동일한 데이터 원본을 사용합니다. 데이터 소스 탭에서 새 DynamoDB 데이터 소스를 생성하고 이름을 지정합니다BatchTutorial. 테이블 이름은 배치 작업을 위한 요청 매핑 템플릿의 일부로 지정되므로 어떤 것이든 지정할 수 있습니다. 테이블의 이름을 empty
라고 지정하겠습니다.
이 자습서의 경우 다음 인라인 정책이 적용된 역할이 모두 작동합니다.
{ "Version": "2012-10-17", "Statement": [ { "Action": [ "dynamodb:BatchGetItem", "dynamodb:BatchWriteItem" ], "Effect": "Allow", "Resource": [ "arn:aws:dynamodb:region:account:table/Posts", "arn:aws:dynamodb:region:account:table/Posts/*", "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/*" ] } ] }
단일 테이블 배치
주의
BatchPutItem
충돌 감지 및 해결과 함께 사용할 때는 및 BatchDeleteItem
가 지원되지 않습니다. 오류가 발생하지 않도록 이러한 설정을 비활성화해야 합니다.
이 예에서는 배치 작업을 통해 항목을 추가 및 제거하려는 Posts라는 단일 테이블이 있다고 가정합니다. 다음 스키마를 사용합니다. 쿼리의 경우 의 목록에 전달됩니다. 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] } schema { query: Query mutation: Mutation }
다음 요청 매핑 템플릿을 사용하여 batchAdd()
필드에 해석기를 첨부합니다. 이렇게 하면 GraphQL input PostInput
형식의 각 항목을 자동으로 받아 BatchPutItem
작업에 필요한 맵을 빌드합니다.
#set($postsdata = []) #foreach($item in ${ctx.args.posts}) $util.qr($postsdata.add($util.dynamodb.toMapValues($item))) #end { "version" : "2018-05-29", "operation" : "BatchPutItem", "tables" : { "Posts": $utils.toJson($postsdata) } }
이 경우 응답 매핑 템플릿은 간단한 패스스루인데, 테이블 이름이 다음과 같이 컨텍스트 객체에 ..data.Posts
로 추가됩니다.
$util.toJson($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 테이블에 기록되었는지 독립적으로 확인할 수 있습니다.
다음으로, 다음 요청 매핑 템플릿을 사용하여 batchGet()
필드에 해석기를 첨부합니다. 이렇게 하면 GraphQL ids:[]
형식의 각 항목을 자동으로 받아 BatchGetItem
작업에 필요한 맵을 빌드합니다.
#set($ids = []) #foreach($id in ${ctx.args.ids}) #set($map = {}) $util.qr($map.put("id", $util.dynamodb.toString($id))) $util.qr($ids.add($map)) #end { "version" : "2018-05-29", "operation" : "BatchGetItem", "tables" : { "Posts": { "keys": $util.toJson($ids), "consistentRead": true, "projection" : { "expression" : "#id, title", "expressionNames" : { "#id" : "id"} } } } }
이 경우 응답 매핑 템플릿은 다시 간단한 패스스루인데, 테이블 이름이 다시 컨텍스트 객체에 ..data.Posts
로 추가됩니다.
$util.toJson($ctx.result.data.Posts)
이제 콘솔의 AWS AppSync 쿼리 페이지로 돌아가서 다음 batchGet 쿼리 를 실행합니다.
query get { batchGet(ids:[1,2,3]){ id title } }
앞서 추가한 두 id
값에 대한 결과를 반환해야 합니다. null
값은 값이 id
인 3
에 대해 반환되었습니다. 이는 Posts 테이블에 해당 값을 가진 레코드가 아직 없기 때문입니다. 또한 는 AWS AppSync 쿼리에 전달된 키와 동일한 순서로 결과를 반환하며, 이는 사용자를 대신하여 AWS AppSync 수행하는 추가 기능입니다. batchGet(ids:[1,3,2)
로 전환하면 순서가 바뀝니다. 또한 어떤 id
가 null
값을 반환하는지 알게 됩니다.
마지막으로, 다음 요청 매핑 템플릿을 사용하여 batchDelete()
필드에 해석기를 첨부합니다. 이렇게 하면 GraphQL ids:[]
형식의 각 항목을 자동으로 받아 BatchGetItem
작업에 필요한 맵을 빌드합니다.
#set($ids = []) #foreach($id in ${ctx.args.ids}) #set($map = {}) $util.qr($map.put("id", $util.dynamodb.toString($id))) $util.qr($ids.add($map)) #end { "version" : "2018-05-29", "operation" : "BatchDeleteItem", "tables" : { "Posts": $util.toJson($ids) } }
이 경우 응답 매핑 템플릿은 다시 간단한 패스스루인데, 테이블 이름이 다시 컨텍스트 객체에 ..data.Posts
로 추가됩니다.
$util.toJson($ctx.result.data.Posts)
이제 콘솔의 AWS AppSync 쿼리 페이지로 돌아가서 다음 batchDelete 변형을 실행합니다.
mutation delete { batchDelete(ids:[1,2]){ id } }
이제 id
1
및 2
인 레코드가 삭제되어야 합니다. 앞에서 batchGet()
쿼리를 다시 실행하면 null
을 반환해야 합니다.
다중 테이블 배치
주의
BatchPutItem
충돌 감지 및 해결과 함께 사용할 때는 및 BatchDeleteItem
가 지원되지 않습니다. 오류가 발생하지 않도록 이러한 설정을 비활성화해야 합니다.
AWS AppSync 를 사용하면 테이블 간에 배치 작업을 수행할 수도 있습니다. 더 복잡한 애플리케이션을 빌드해 보겠습니다. 센서가 애완동물의 위치와 신체 온도를 보고하는 애완동물 건강 앱을 빌드한다고 가정해 보겠습니다. 센서는 배터리로 구동되며 몇 분마다 네트워크에 연결을 시도합니다. 센서가 연결을 설정하면 판독값을 로 전송합니다 AWS AppSync API. 그런 다음 트리거가 데이터를 분석해 애완동물 주인에게 대시보드가 제공됩니다. 센서와 백엔드 데이터 스토어 간의 상호 작용에 대해 중점적으로 설명해 보겠습니다.
먼저 두 개의 DynamoDB 테이블을 생성해 보겠습니다. locationReadings는 센서 위치 판독값을 저장하고 센서 온도 판독값을 temperatureReadings 저장합니다. 두 테이블은 동일한 기본 키 구조를 공유하는데, sensorId
(String)
는 파티션 키이고, timestamp (String)
는 정렬 키입니다.
다음 GraphQL 스키마를 사용해 보겠습니다.
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 }
BatchPutItem - 기록 센서 판독값
센서는 인터넷에 연결되면 판독값을 전송할 수 있어야 합니다. GraphQL 필드는 이를 위해 사용할 API Mutation.recordReadings
입니다. 를 API 실현하기 위해 해석기를 연결해 보겠습니다.
Mutation.recordReadings
필드 옆의 첨부를 선택합니다. 다음 화면에서 자습서 시작 부분에서 생성한 것과 같은 BatchTutorial
데이터 원본을 선택합니다.
다음 요청 매핑 템플릿을 추가해 보겠습니다.
요청 매핑 템플릿
## Convert tempReadings arguments to DynamoDB objects #set($tempReadings = []) #foreach($reading in ${ctx.args.tempReadings}) $util.qr($tempReadings.add($util.dynamodb.toMapValues($reading))) #end ## Convert locReadings arguments to DynamoDB objects #set($locReadings = []) #foreach($reading in ${ctx.args.locReadings}) $util.qr($locReadings.add($util.dynamodb.toMapValues($reading))) #end { "version" : "2018-05-29", "operation" : "BatchPutItem", "tables" : { "locationReadings": $utils.toJson($locReadings), "temperatureReadings": $utils.toJson($tempReadings) } }
보시다시피 BatchPutItem
작업을 통해 여러 테이블을 지정할 수 있습니다.
다음 응답 매핑 템플릿을 사용해 보겠습니다.
응답 매핑 템플릿
## If there was an error with the invocation ## there might have been partial results #if($ctx.error) ## Append a GraphQL error for that field in the GraphQL response $utils.appendError($ctx.error.message, $ctx.error.message) #end ## Also returns data for the field in the GraphQL response $utils.toJson($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 } } }
하나의 변형으로 센서 판독값 10개를 전송했고, 판독값은 테이블 2개로 분할되어 있었습니다. DynamoDB 콘솔을 사용하여 locationReadings 및 temperatureReadings 테이블 모두에 데이터가 표시되는지 확인합니다.
BatchDeleteItem - 센서 판독값 삭제
마찬가지로 센서 판독값의 배치를 삭제해야 합니다. 이를 위해 Mutation.deleteReadings
GraphQL 필드를 사용해 보겠습니다. Mutation.recordReadings
필드 옆의 첨부를 선택합니다. 다음 화면에서 자습서 시작 부분에서 생성한 것과 같은 BatchTutorial
데이터 원본을 선택합니다.
다음 요청 매핑 템플릿을 사용해 보겠습니다.
요청 매핑 템플릿
## Convert tempReadings arguments to DynamoDB primary keys #set($tempReadings = []) #foreach($reading in ${ctx.args.tempReadings}) #set($pkey = {}) $util.qr($pkey.put("sensorId", $reading.sensorId)) $util.qr($pkey.put("timestamp", $reading.timestamp)) $util.qr($tempReadings.add($util.dynamodb.toMapValues($pkey))) #end ## Convert locReadings arguments to DynamoDB primary keys #set($locReadings = []) #foreach($reading in ${ctx.args.locReadings}) #set($pkey = {}) $util.qr($pkey.put("sensorId", $reading.sensorId)) $util.qr($pkey.put("timestamp", $reading.timestamp)) $util.qr($locReadings.add($util.dynamodb.toMapValues($pkey))) #end { "version" : "2018-05-29", "operation" : "BatchDeleteItem", "tables" : { "locationReadings": $utils.toJson($locReadings), "temperatureReadings": $utils.toJson($tempReadings) } }
이 응답 매핑 템플릿은 Mutation.recordReadings
에 사용한 것과 동일합니다.
응답 매핑 템플릿
## If there was an error with the invocation ## there might have been partial results #if($ctx.error) ## Append a GraphQL error for that field in the GraphQL response $utils.appendError($ctx.error.message, $ctx.error.message) #end ## Also return data for the field in the GraphQL response $utils.toJson($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 } } }
DynamoDB 콘솔을 통해 이 두 판독값이 locationReadings 및 temperatureReadings 테이블에서 삭제되었는지 확인합니다.
BatchGetItem - 판독값 검색
애완동물 건강 앱의 또 다른 일반 작업은 특정 시점에 센서의 판독값을 검색하는 것입니다. 스키마의 Query.getReadings
GraphQL 필드에 해석기를 연결해 보겠습니다. 연결을 선택하고 다음 화면에서 자습서 시작 부분에서 생성한 것과 같은 BatchTutorial
데이터 원본을 선택합니다.
다음 요청 매핑 템플릿을 추가해 보겠습니다.
요청 매핑 템플릿
## Build a single DynamoDB primary key, ## as both locationReadings and tempReadings tables ## share the same primary key structure #set($pkey = {}) $util.qr($pkey.put("sensorId", $ctx.args.sensorId)) $util.qr($pkey.put("timestamp", $ctx.args.timestamp)) { "version" : "2018-05-29", "operation" : "BatchGetItem", "tables" : { "locationReadings": { "keys": [$util.dynamodb.toMapValuesJson($pkey)], "consistentRead": true }, "temperatureReadings": { "keys": [$util.dynamodb.toMapValuesJson($pkey)], "consistentRead": true } } }
이제 BatchGetItem 작업을 사용 중입니다.
SensorReading
목록을 반환하도록 선택했으므로 응답 매핑 템플릿이 약간 다릅니다. 호출 결과를 원하는 모양으로 매핑해 보겠습니다.
응답 매핑 템플릿
## Merge locationReadings and temperatureReadings ## into a single list ## __typename needed as schema uses an interface #set($sensorReadings = []) #foreach($locReading in $ctx.result.data.locationReadings) $util.qr($locReading.put("__typename", "LocationReading")) $util.qr($sensorReadings.add($locReading)) #end #foreach($tempReading in $ctx.result.data.temperatureReadings) $util.qr($tempReading.put("__typename", "TemperatureReading")) $util.qr($sensorReadings.add($tempReading)) #end $util.toJson($sensorReadings)
해석기를 저장하고 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데이터 소스 작업은 때때로 부분 결과를 반환할 수 있습니다. 일부 결과는 작업의 출력이 일부 데이터와 오류로 구성된 경우를 나타내는 데 사용되는 용어입니다. 오류 처리는 기본적으로 애플리케이션별로 다르기 때문에 AWS AppSync 는 응답 매핑 템플릿에서 오류를 처리할 수 있는 기회를 제공합니다. 해석기 호출 오류(있는 경우)는 컨텍스트에서 $ctx.error
로 확인할 수 있습니다. 호출 오류에는 항상 $ctx.error.message
및 $ctx.error.type
속성으로 액세스할 수 있는 메시지와 유형이 포함되어 있습니다. 응답 매핑 템플릿 호출 중 다음과 같은 3가지 방법으로 일부 결과를 처리할 수 있습니다.
-
데이터를 반환하여 호출 오류를 가립니다.
-
응답 매핑 템플릿 평가를 중단해 오류를 나타냅니다(
$util.error(...)
사용). 이 경우에는 데이터가 반환되지 않습니다. -
오류를 추가하고(
$util.appendError(...)
사용) 데이터도 반환합니다.
DynamoDB 배치 작업을 사용해 위의 3가지 방법을 각각 시연해 보겠습니다!
DynamoDB 배치 작업
DynamoDB 배치 작업을 사용하면 배치를 부분적으로 완료할 수 있습니다. 즉, 요청된 항목 또는 키 중 일부가 처리되지 않은 상태로 남아 있을 수 있습니다. AWS AppSync 가 배치를 완료할 수 없는 경우 처리되지 않은 항목과 호출 오류가 컨텍스트에 설정됩니다.
이 자습서 이전 단원에서 사용한 Query.getReadings
작업의 BatchGetItem
필드 구성을 사용하여 오류 처리를 구현하겠습니다. 이때, Query.getReadings
필드를 실행하는 동안 temperatureReadings
DynamoDB 테이블에 프로비저닝된 처리량이 부족하다고 가정해 보겠습니다. DynamoDBProvisionedThroughputExceededException는 배치의 나머지 요소를 처리하기 AWS AppSync 위해 를 에 의해 두 번째 시도에서 제기했습니다.
다음은 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": [] }
컨텍스트에 대해서 알아야 할 몇 가지가 있습니다.
-
호출 오류가 에
$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
입니다.
이 오류를 세 가지 다른 방법으로 처리해 보겠습니다.
1. 호출 오류 가리기
호출 오류를 처리하지 않고 데이터를 반환하면 오류를 효과적으로 가려 주어진 GraphQL 필드에 대한 결과가 항상 성공입니다.
여기서 작성한 응답 매핑 템플릿은 알기 쉽고 결과 데이터에만 중점을 두고 있습니다.
응답 매핑 템플릿:
$util.toJson($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(...)
유틸리티 메서드가 정확하게 이러한 동작을 수행합니다.
응답 매핑 템플릿:
## there was an error let's mark the entire field ## as failed and do not return any data back in the response #if ($ctx.error) $util.error($ctx.error.message, $ctx.error.type, null, $ctx.result.data.unprocessedKeys) #end $util.toJson($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 응답 오류 블록에 오류가 추가됩니다.
3. 오류를 추가하고 데이터 및 오류를 둘 다 반환
특정한 경우 사용자 경험을 개선하기 위해 애플리케이션에서는 일부 결과를 반환하고 클라이언트에게 처리되지 않은 항목이 있음을 알릴 수 있습니다. 그러면 클라이언트는 재시도를 수행하거나 오류를 최종 사용자에게 다시 번역할지 결정할 수 있습니다. $util.appendError(...)
는 애플리케이션 디자이너가 템플릿 평가를 방해하지 않고 컨텍스트에 오류를 추가하도록 하여 이러한 동작을 가능하게 하는 유틸리티 메서드입니다. 템플릿을 평가한 후 AWS AppSync 는 컨텍스트 오류를 GraphQL 응답의 오류 블록에 추가하여 처리합니다.
응답 매핑 템플릿:
#if ($ctx.error) ## pass the unprocessed keys back to the caller via the `errorInfo` field $util.appendError($ctx.error.message, $ctx.error.type, null, $ctx.result.data.unprocessedKeys) #end $util.toJson($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. (...)" } ] }