

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 在 中使用 AWS Lambda 解析程式 AWS AppSync
<a name="tutorial-lambda-resolvers"></a>

**注意**  
我們現在主要支援 APPSYNC\$1JS 執行期及其文件。請考慮[在此處](https://docs.aws.amazon.com/appsync/latest/devguide/tutorials-js.html)使用 APPSYNC\$1JS 執行期及其指南。

您可以使用 AWS Lambda with AWS AppSync 來解析任何 GraphQL 欄位。例如，GraphQL 查詢可能會將呼叫傳送至 Amazon Relational Database Service (Amazon RDS) 執行個體，而 GraphQL 變動可能會寫入 Amazon Kinesis 串流。在本節中，我們將示範如何撰寫 Lambda 函數，根據 GraphQL 欄位操作的調用執行商業邏輯。

## 建立 Lambda 函式
<a name="create-a-lam-function"></a>

下列範例顯示寫入 的 Lambda 函數`Node.js`，該函數會在部落格文章應用程式中對部落格文章執行不同的操作。

```
exports.handler = (event, context, callback) => {
    console.log("Received event {}", JSON.stringify(event, 3));
    var 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"} };

    var relatedPosts = {
        "1": [posts['4']],
        "2": [posts['3'], posts['5']],
        "3": [posts['2'], posts['1']],
        "4": [posts['2'], posts['1']],
        "5": []
    };

    console.log("Got an Invoke Request.");
    switch(event.field) {
        case "getPost":
            var id = event.arguments.id;
            callback(null, posts[id]);
            break;
        case "allPosts":
            var values = [];
            for(var d in posts){
                values.push(posts[d]);
            }
            callback(null, values);
            break;
        case "addPost":
            // return the arguments back
            callback(null, event.arguments);
            break;
        case "addPostErrorWithData":
            var id = event.arguments.id;
            var result = posts[id];
            // attached additional error information to the post
            result.errorMessage = 'Error with the mutation, data has changed';
            result.errorType = 'MUTATION_ERROR';
            callback(null, result);
            break;
        case "relatedPosts":
            var id = event.source.id;
            callback(null, relatedPosts[id]);
            break;
        default:
            callback("Unknown field, unable to resolve" + event.field, null);
            break;
    }
};
```

此 Lambda 函數會依 ID 擷取文章、新增文章、擷取文章清單，以及擷取特定文章的相關文章。

 **注意：**Lambda 函數使用 上的 `switch`陳述式`event.field`來判斷目前正在解析哪個欄位。

使用 AWS 管理主控台或 AWS CloudFormation 堆疊建立此 Lambda 函數。若要從 CloudFormation 堆疊建立函數，您可以使用下列 AWS Command Line Interface (AWS CLI) 命令：

```
aws cloudformation create-stack --stack-name AppSyncLambdaExample \
--template-url https://s3.us-west-2.amazonaws.com/awsappsync/resources/lambda/LambdaCFTemplate.yaml \
--capabilities CAPABILITY_NAMED_IAM
```

您也可以從這裡在美國西部 （奧勒岡） AWS 區域中啟動 AWS CloudFormation 堆疊：

[https://console.aws.amazon.com/cloudformation/home?region=us-west-2#/stacks/new?templateURL=https://s3.us-west-2.amazonaws.com/awsappsync/resources/lambda/LambdaCFTemplate.yaml](https://console.aws.amazon.com/cloudformation/home?region=us-west-2#/stacks/new?templateURL=https://s3.us-west-2.amazonaws.com/awsappsync/resources/lambda/LambdaCFTemplate.yaml)

## 設定 Lambda 的資料來源
<a name="configure-data-source-for-lamlong"></a>

建立 Lambda 函數後，在 AWS AppSync 主控台中導覽至 GraphQL API，然後選擇**資料來源**索引標籤。

選擇**建立資料來源**，輸入易記**的資料來源名稱** （例如 **Lambda**)，然後針對**資料來源類型**選擇 **AWS Lambda 函數**。針對**區域**，選擇與函數相同的區域。（如果您從提供的 CloudFormation 堆疊建立函數，則函數可能位於 **US-WEST-2**。) 針對**函數 ARN**，選擇 Lambda 函數的 Amazon Resource Name (ARN)。

選擇 Lambda 函數後，您可以建立新的 AWS Identity and Access Management (IAM) 角色 ( AWS AppSync 會為其指派適當的許可），或選擇具有下列內嵌政策的現有角色：

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "lambda:InvokeFunction"
            ],
            "Resource": "arn:aws:lambda:us-east-1:111122223333:function:LAMBDA_FUNCTION"
        }
    ]
}
```

------

您還必須為 IAM 角色設定與 AWS AppSync 的信任關係，如下所示：

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "appsync.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
```

------

## 建立 GraphQL 結構描述
<a name="creating-a-graphql-schema"></a>

現在資料來源已連接至 Lambda 函數，請建立 GraphQL 結構描述。

從 AWS AppSync 主控台的結構描述編輯器，請確定您的結構描述符合下列結構描述：

```
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]
}
```

## 設定解析程式
<a name="configuring-resolvers"></a>

現在您已註冊 Lambda 資料來源和有效的 GraphQL 結構描述，您可以使用解析程式將 GraphQL 欄位連線至 Lambda 資料來源。

若要建立解析程式，您需要映射範本。若要進一步了解映射範本，請參閱 [Resolver Mapping Template Overview](resolver-mapping-template-reference-overview.md#aws-appsync-resolver-mapping-template-reference-overview)。

如需 Lambda 映射範本的詳細資訊，請參閱 [Resolver mapping template reference for Lambda](resolver-mapping-template-reference-lambda.md#aws-appsync-resolver-mapping-template-reference-lambda)。

在此步驟中，您將解析程式連接至下列欄位的 Lambda 函數：`getPost(id:ID!): Post`、`addPost(id: ID!, author: String!, title: String, content: String, url: String): Post!`、 `allPosts: [Post]`和 `Post.relatedPosts: [Post]`。

從 AWS AppSync 主控台的結構描述編輯器的右側，選擇**連接解析程式**`getPost(id:ID!): Post`。

然後，在**動作功能表中**，選擇**更新執行時間**，然後選擇**單位解析程式 （僅限 VTL)**。

之後，選擇您的 Lambda 資料來源。在 **request mapping template (請求映射範本)** 區段中，選擇 **Invoke And Forward Arguments (叫用並轉發引數)**。

修改 `payload` 物件以新增欄位名稱。您的範本看起來應該如下所示：

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

在 **response mapping template (回應映射範本)** 區段中，選擇 **Return Lambda Result (傳回 Lambda 結果)**。

在此案例中，使用原本的基礎範本。它看起來應該如下所示：

```
$utils.toJson($context.result)
```

選擇**儲存**。您已成功連接第一個解析程式。對剩餘欄位重複此操作，如下所示：

`addPost(id: ID!, author: String!, title: String, content: String, url: String): Post!` 請求映射範本：

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

`addPost(id: ID!, author: String!, title: String, content: String, url: String): Post!` 回應映射範本：

```
$utils.toJson($context.result)
```

`allPosts: [Post]` 請求映射範本：

```
{
    "version": "2017-02-28",
    "operation": "Invoke",
    "payload": {
        "field": "allPosts"
    }
}
```

`allPosts: [Post]` 回應映射範本：

```
$utils.toJson($context.result)
```

`Post.relatedPosts: [Post]` 請求映射範本：

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

`Post.relatedPosts: [Post]` 回應映射範本：

```
$utils.toJson($context.result)
```

## 測試 GraphQL API
<a name="testing-your-graphql-api"></a>

現在，您的 Lambda 函式已經連接到 GraphQL 解析程式，您可以使用主控台或用戶端應用程式執行一些變動和查詢。

在 AWS AppSync 主控台的左側，選擇**查詢**，然後貼上下列程式碼：

### addPost Mutation
<a name="addpost-mutation"></a>

```
mutation addPost {
    addPost(
        id: 6
        author: "Author6"
        title: "Sixth book"
        url: "https://www.amazon.com/"
        content: "This is the book is a tutorial for using GraphQL with AWS AppSync."
    ) {
        id
        author
        title
        content
        url
        ups
        downs
    }
}
```

### getPost Query
<a name="getpost-query"></a>

```
query getPost {
    getPost(id: "2") {
        id
        author
        title
        content
        url
        ups
        downs
    }
}
```

### allPosts Query
<a name="allposts-query"></a>

```
query allPosts {
    allPosts {
        id
        author
        title
        content
        url
        ups
        downs
        relatedPosts {
            id
            title
        }
    }
}
```

## 傳回錯誤
<a name="returning-errors"></a>

任何指定的欄位解析度都可能導致錯誤。透過 AWS AppSync，您可以從下列來源引發錯誤：
+ 請求或回應映射範本
+ Lambda 函式

### 從映射範本
<a name="from-the-mapping-template"></a>

若要引發刻意錯誤，您可以使用 Velocity 範本語言 (VTL) 範本中的`$utils.error`協助程式方法。它使用 `errorMessage`、`errorType`，及選用的 `data` 值做為引數。發生錯誤時，`data` 可將額外的資料傳回給用戶端。`data` 物件會新增到 GraphQL 最後回應中的 `errors`。

以下範例說明如何在 `Post.relatedPosts: [Post]` 回應映射範本中使用它：

```
$utils.error("Failed to fetch relatedPosts", "LambdaFailure", $context.result)
```

這會產生類似下列的 GraphQL 回應：

```
{
    "data": {
        "allPosts": [
            {
                "id": "2",
                "title": "Second book",
                "relatedPosts": null
            },
            ...
        ]
    },
    "errors": [
        {
            "path": [
                "allPosts",
                0,
                "relatedPosts"
            ],
            "errorType": "LambdaFailure",
            "locations": [
                {
                    "line": 5,
                    "column": 5
                }
            ],
            "message": "Failed to fetch relatedPosts",
            "data": [
                {
                  "id": "2",
                  "title": "Second book"
                },
                {
                  "id": "1",
                  "title": "First book"
                }
            ]
        }
    ]
}
```

其中的 `allPosts[0].relatedPosts` 為 *null*，因為錯誤以及 `errorMessage`、`errorType` 和 `data` 出現在 `data.errors[0]` 物件中。

### 從 Lambda 函式
<a name="from-the-lam-function"></a>

AWS AppSync 也了解 Lambda 函數擲回的錯誤。Lambda 程式設計模型可讓您引發*已處理的*錯誤。如果 Lambda 函數擲回錯誤， AWS AppSync 無法解析目前的欄位。回應中只會設定從 Lambda 傳回的錯誤訊息。目前，您無法透過從 Lambda 函數引發錯誤，將任何無關的資料傳遞回用戶端。

 **注意**：如果您的 Lambda 函數引發*未處理的*錯誤， AWS AppSync 會使用 Lambda 設定的錯誤訊息。

下列 Lambda 函式會引發錯誤：

```
exports.handler = (event, context, callback) => {
    console.log("Received event {}", JSON.stringify(event, 3));
    callback("I fail. Always.");
};
```

這會傳回類似下列的 GraphQL 回應：

```
{
    "data": {
        "allPosts": [
            {
                "id": "2",
                "title": "Second book",
                "relatedPosts": null
            },
            ...
        ]
    },
    "errors": [
        {
            "path": [
                "allPosts",
                0,
                "relatedPosts"
            ],
            "errorType": "Lambda:Handled",
            "locations": [
                {
                    "line": 5,
                    "column": 5
                }
            ],
            "message": "I fail. Always."
        }
    ]
}
```

## 進階使用案例：批次處理
<a name="advanced-use-case-batching"></a>

此範例中的 Lambda 函數有一個`relatedPosts`欄位，可傳回指定文章的相關文章清單。在範例查詢中，來自 Lambda 函數`allPosts`的欄位調用會傳回五個文章。因為我們指定了也要`relatedPosts`解析每個傳回的文章，所以會叫用 `relatedPosts` 欄位操作五次。

```
query allPosts {
    allPosts {   // 1 Lambda invocation - yields 5 Posts
        id
        author
        title
        content
        url
        ups
        downs
        relatedPosts {   // 5 Lambda invocations - each yields 5 posts
            id
            title
        }
    }
}
```

雖然這在此特定範例中可能聽起來並不重要，但這種複合式過度擷取可能會快速破壞應用程式。

如果您要在同一查詢中，再次擷取傳回之相關 `Posts` 的 `relatedPosts`，那麼叫用的次數將大幅增加。

```
query allPosts {
    allPosts {   // 1 Lambda invocation - yields 5 Posts
        id
        author
        title
        content
        url
        ups
        downs
        relatedPosts {   // 5 Lambda invocations - each yield 5 posts = 5 x 5 Posts
            id
            title
            relatedPosts {  // 5 x 5 Lambda invocations - each yield 5 posts = 25 x 5 Posts
                id
                title
                author
            }
        }
    }
}
```

在此相對簡單的查詢中， AWS AppSync 會叫用 Lambda 函數 1 \$1 5 \$1 25 = 31 次。

這是一個相當常見的挑戰，通常稱為 N\$11 問題 (在此例中，N = 5)，它可能會增加應用程式的延遲和成本。

解決此問題的方法之一，是將類似的欄位解析程式請求一起批次處理。在此範例中，它可以改為解析指定批次文章的相關文章清單，而不是讓 Lambda 函數解析單一指定文章的相關文章清單。

為了示範，讓我們將 `Post.relatedPosts: [Post]` 解析程式切換為啟用批次的解析程式。

在 AWS AppSync 主控台的右側，選擇現有的`Post.relatedPosts: [Post]`解析程式。將請求映射範本變更為以下內容：

```
{
    "version": "2017-02-28",
    "operation": "BatchInvoke",
    "payload": {
        "field": "relatedPosts",
        "source":  $utils.toJson($context.source)
    }
}
```

只有 `operation` 欄位從 `Invoke` 變更為 `BatchInvoke`。承載欄位現在會成為範本中指定之任何項目的陣列。在此範例中，Lambda 函數會收到下列項目做為輸入：

```
[
    {
        "field": "relatedPosts",
        "source": {
            "id": 1
        }
    },
    {
        "field": "relatedPosts",
        "source": {
            "id": 2
        }
    },
    ...
]
```

在請求映射範本中指定 `BatchInvoke` 時，Lambda 函數會收到請求清單，並傳回結果清單。

具體而言，結果清單必須符合請求承載項目的大小和順序，以便 AWS AppSync 可以相應地符合結果。

在此批次範例中，Lambda 函數會傳回一批結果，如下所示：

```
[
    [{"id":"2","title":"Second book"}, {"id":"3","title":"Third book"}],   // relatedPosts for id=1
    [{"id":"3","title":"Third book"}]                                                             // relatedPosts for id=2
]
```

Node.js 中的下列 Lambda 函數示範 `Post.relatedPosts` 欄位的此批次處理功能，如下所示：

```
exports.handler = (event, context, callback) => {
    console.log("Received event {}", JSON.stringify(event, 3));
    var 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"} };

    var relatedPosts = {
        "1": [posts['4']],
        "2": [posts['3'], posts['5']],
        "3": [posts['2'], posts['1']],
        "4": [posts['2'], posts['1']],
        "5": []
    };

    console.log("Got a BatchInvoke Request. The payload has %d items to resolve.", event.length);
    // event is now an array
    var field = event[0].field;
    switch(field) {
        case "relatedPosts":
            var results = [];
            // the response MUST contain the same number
            // of entries as the payload array
            for (var i=0; i< event.length; i++) {
                console.log("post {}", JSON.stringify(event[i].source));
                results.push(relatedPosts[event[i].source.id]);
            }
            console.log("results {}", JSON.stringify(results));
            callback(null, results);
            break;
        default:
            callback("Unknown field, unable to resolve" + field, null);
            break;
    }
};
```

### 傳回個別錯誤
<a name="returning-individual-errors"></a>

上述範例顯示，您可以從 Lambda 函數傳回單一錯誤，或從映射範本引發錯誤。對於批次叫用，從 Lambda 函數引發錯誤會將整個批次標記為失敗。對於發生無法復原錯誤的特定案例，例如與資料存放區的連線失敗，這可能是可接受的。不過，如果批次中的某些項目成功，而其他項目失敗，則有可能同時傳回錯誤和有效資料。Because AWS AppSync 需要批次回應來列出符合批次原始大小的元素，您必須定義可以區分有效資料與錯誤的資料結構。

例如，如果 Lambda 函數預期會傳回一批相關文章，您可以選擇傳回`Response`物件清單，其中每個物件都有選用*的資料*、*errorMessage* 和 *errorType* 欄位。如果出現 *errorMessage* 欄位，表示發生錯誤。

下列程式碼顯示如何更新 Lambda 函數：

```
exports.handler = (event, context, callback) => {
    console.log("Received event {}", JSON.stringify(event, 3));
    var 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"} };

    var relatedPosts = {
        "1": [posts['4']],
        "2": [posts['3'], posts['5']],
        "3": [posts['2'], posts['1']],
        "4": [posts['2'], posts['1']],
        "5": []
    };

    console.log("Got a BatchInvoke Request. The payload has %d items to resolve.", event.length);
    // event is now an array
    var field = event[0].field;
    switch(field) {
        case "relatedPosts":
            var results = [];
            results.push({ 'data': relatedPosts['1'] });
            results.push({ 'data': relatedPosts['2'] });
            results.push({ 'data': null, 'errorMessage': 'Error Happened', 'errorType': 'ERROR' });
            results.push(null);
            results.push({ 'data': relatedPosts['3'], 'errorMessage': 'Error Happened with last result', 'errorType': 'ERROR' });
            callback(null, results);
            break;
        default:
            callback("Unknown field, unable to resolve" + field, null);
            break;
    }
};
```

在此範例中，下列回應映射範本會剖析 Lambda 函數的每個項目，並引發任何發生的錯誤：

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

此範例會傳回類似下列的 GraphQL 回應：

```
{
  "data": {
    "allPosts": [
      {
        "id": "1",
        "relatedPostsPartialErrors": [
          {
            "id": "4",
            "title": "Fourth book"
          }
        ]
      },
      {
        "id": "2",
        "relatedPostsPartialErrors": [
          {
            "id": "3",
            "title": "Third book"
          },
          {
            "id": "5",
            "title": "Fifth book"
          }
        ]
      },
      {
        "id": "3",
        "relatedPostsPartialErrors": null
      },
      {
        "id": "4",
        "relatedPostsPartialErrors": null
      },
      {
        "id": "5",
        "relatedPostsPartialErrors": null
      }
    ]
  },
  "errors": [
    {
      "path": [
        "allPosts",
        2,
        "relatedPostsPartialErrors"
      ],
      "errorType": "ERROR",
      "locations": [
        {
          "line": 4,
          "column": 9
        }
      ],
      "message": "Error Happened"
    },
    {
      "path": [
        "allPosts",
        4,
        "relatedPostsPartialErrors"
      ],
      "data": [
        {
          "id": "2",
          "title": "Second book"
        },
        {
          "id": "1",
          "title": "First book"
        }
      ],
      "errorType": "ERROR",
      "locations": [
        {
          "line": 4,
          "column": 9
        }
      ],
      "message": "Error Happened with last result"
    }
  ]
}
```

### 設定批次大小上限
<a name="configure-max-batch-size"></a>

根據預設，使用 時`BatchInvoke`， AWS AppSync 會以最多五個項目的批次傳送請求到您的 Lambda 函數。您可以設定 Lambda 解析程式的批次大小上限。

若要在解析程式上設定批次大小上限，請在 AWS Command Line Interface () 中使用下列命令AWS CLI：

```
$ aws appsync create-resolver --api-id <api-id> --type-name Query --field-name relatedPosts \
 --request-mapping-template "<template>" --response-mapping-template "<template>" --data-source-name "<lambda-datasource>" \ 
 --max-batch-size X
```

**注意**  
提供請求映射範本時，您必須使用 `BatchInvoke`操作來使用批次處理。

您也可以使用下列命令來啟用和設定 Direct Lambda 解析程式上的批次處理：

```
$ aws appsync create-resolver --api-id <api-id> --type-name Query --field-name relatedPosts \
 --data-source-name "<lambda-datasource>" \ 
 --max-batch-size X
```

### 使用 VTL 範本的批次大小上限組態
<a name="configure-max-batch-size-vtl"></a>

對於具有 VTL 請求中範本的 Lambda 解析程式，除非其已直接指定為 VTL 中的`BatchInvoke`操作，否則最大批次大小不會生效。同樣地，如果您執行最上層變動，則不會針對變動執行批次處理，因為 GraphQL 規格需要依序執行平行變動。

例如，採取下列變動：

```
type Mutation {
    putItem(input: Item): Item
    putItems(inputs: [Item]): [Item]
}
```

使用第一個變動，我們可以建立 10`Items`，如以下程式碼片段所示：

```
mutation MyMutation {
    v1: putItem($someItem1) {
        id,
        name
    }
    v2: putItem($someItem2) {
        id,
        name
    }
    v3: putItem($someItem3) {
        id,
        name
    } 
    v4: putItem($someItem4) {
        id,
        name
    }
    v5: putItem($someItem5) {
        id,
        name
    }
    v6: putItem($someItem6) {
        id,
        name
    } 
    v7: putItem($someItem7) {
        id,
        name
    }
    v8: putItem($someItem8) {
        id,
        name
    }
    v9: putItem($someItem9) {
        id,
        name
    }
    v10: putItem($someItem10) {
        id,
        name
    }
}
```

在此範例中，即使 Lambda Resolver 中的批次大小上限設為 10，也不會在 10 的`Items`群組中批次處理 。相反地，它們會根據 GraphQL 規格循序執行。

若要執行實際批次變動，您可以使用第二個變動遵循下列範例：

```
mutation MyMutation {
    putItems([$someItem1, $someItem2, $someItem3,$someItem4, $someItem5, $someItem6, 
    $someItem7, $someItem8, $someItem9, $someItem10]) {
    id,
    name
    }
}
```

如需搭配 Direct Lambda 解析程式使用批次處理的詳細資訊，請參閱 [Direct Lambda 解析程式](resolver-mapping-template-reference-lambda.md#direct-lambda-resolvers)。