

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

# での AWS Lambda リゾルバーの使用 AWS AppSync
<a name="tutorial-lambda-resolvers-js"></a>

 AWS Lambda with AWS AppSync を使用して、GraphQL フィールドを解決できます。例えば、GraphQL クエリが Amazon Relational Database Service (Amazon RDS) インスタンスを呼び出し、GraphQL のミューテーションを Amazon Kinesis ストリームに書き込むことができます。このセクションでは、GraphQL フィールド処理の呼び出しに応じてビジネスロジックを実行する Lambda 関数を記述する方法について説明します。

## の Powertools AWS Lambda
<a name="powertools-graphql"></a>

Powertools for AWS Lambda GraphQL イベントハンドラーは、Lambda 関数での GraphQL イベントのルーティングと処理を簡素化します。Python と Typescript で使用できます。Powertools for AWS Lambda の GraphQL API イベントハンドラーのドキュメントの詳細については、以下のリファレンスを参照してください。
+ [Powertools for AWS Lambda GraphQL イベントハンドラー (Python) ](https://docs.aws.amazon.com/powertools/python/latest/core/event_handler/appsync/)
+ [Powertools for AWS Lambda GraphQL イベントハンドラー (Typescript)](https://docs.aws.amazon.com/powertools/typescript/latest/features/event-handler/appsync-graphql/) 

## Lambda 関数を作成する
<a name="create-a-lam-function-js"></a>

以下の例は、`Node.js` (runtime: Node.js 18.x) に記述された、ブログ投稿アプリケーションの一部としてブログ投稿に関するさまざまな処理を実行する Lambda 関数を示しています。コードは、.mis 拡張子の付いたファイル名で保存する必要があることに注意してください。

```
export const handler = async (event) => {
console.log('Received event {}', JSON.stringify(event, 3))

  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: [],
  }

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

この Lambda 関数は、ID による投稿の取得、投稿の追加、投稿のリストの取得、および指定した投稿に関連する投稿の取得を処理します。

**注記**  
`event.field` の `switch` ステートメントにより、Lambda 関数は現在解決しているフィールドを確認することができます。

 AWS マネジメントコンソールを使用して、この Lambda 関数を作成します。

## Lambda のデータソースを設定する
<a name="configure-data-source-for-lamlong-js"></a>

Lambda 関数を作成した後、 AWS AppSync コンソールで GraphQL API に移動し、**[データソース]** タブを選択します。

**[データソースの作成]** を選択し、**[データソース名]**としてわかりやすい名前 (**Lambda** など) を入力してから、**[データソースタイプ]** に対して **[AWS Lambda 関数]**を選択します。**[リージョン]** で、関数と同じリージョンを選択します。**[関数 ARN]** で、Lambda 関数の Amazon リソースネーム (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-js"></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-js"></a>

Lambda のデータソースと有効な GraphQL スキーマが登録されたので、リゾルバーを使用して GraphQL フィールドを Lambda のデータソースに接続することができます。

 AWS AppSync JavaScript (`APPSYNC_JS`) ランタイムを使用して Lambda 関数を操作するリゾルバーを作成します。JavaScript を使用した AWS AppSync リゾルバーと関数の記述の詳細については、[「リゾルバーと関数の JavaScript ランタイム機能](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-util-reference-js.html)」を参照してください。

Lambda のマッピングテンプレートの詳細については、「[ Lambda 向け JavaScript のリゾルバー関数リファレンス](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-lambda-js.html)」を参照してください。

このステップでは、`getPost(id:ID!): Post`、`allPosts: [Post]`、`addPost(id: ID!, author: String!, title: String, content: String, url: String): Post!`、および `Post.relatedPosts: [Post]` の各フィールドで Lambda 関数にリゾルバーをアタッチします。 AWS AppSync コンソールの**スキーマ**エディタの**リゾルバー**ペインで、`getPost(id:ID!): Post`フィールドの横にある**ア**タッチを選択します。Lambda データソースを選択します。そして、次のコードを入力します。

```
import { util } from '@aws-appsync/utils';

export function request(ctx) {
  const {source, args} = ctx
  return {
    operation: 'Invoke',
    payload: { field: ctx.info.fieldName, arguments: args, source },
  };
}

export function response(ctx) {
  return ctx.result;
}
```

このリゾルバーコードは、ソースオブジェクトを呼び出すときに、フィールド名、引数のリスト、ソースオブジェクトに関するコンテキストを Lambda 関数に渡します。**[保存]** を選択します。

最初のリゾルバーが正常に追加されました。残りのフィールドについてこの操作を繰り返します。

## GraphQL API をテストする
<a name="testing-your-graphql-api-js"></a>

これで Lambda 関数が GraphQL リゾルバーに接続されたので、コンソールまたはクライアントアプリケーションを使用してミューテーションまたはクエリが実行できます。

 AWS AppSync コンソールの左側でクエリを選択し****、次のコードを貼り付けます。

### addPost ミューテーション
<a name="addpost-mutation-js"></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 クエリ
<a name="getpost-query-js"></a>

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

### allPosts クエリ
<a name="allposts-query-js"></a>

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

## エラーを返す
<a name="returning-errors-js"></a>

指定したフィールドの解決でエラーが発生する場合があります。 AWS AppSync を使用すると、次のソースからエラーを生成できます。
+ リゾルバーレスポンスハンドラー
+ Lambda function

### リゾルバーレスポンスハンドラーから
<a name="from-the-resolver-response-handler-js"></a>

意図的なエラーを発生させるには、`util.error` ユーティリティメソッドを使用できます。これには引数として、`errorMessage`、`errorType`、および必要に応じて `data` の各値を使用します。`data` は、エラーの発生時にクライアントに追加のデータを返す場合に利用できます。`data` オブジェクトは GraphQL の最終レスポンスで `errors` に追加されます。

次の例は、`Post.relatedPosts: [Post]` リゾルバーのレスポンスハンドラーでこれを使用する方法を示しています。

```
// the Post.relatedPosts response handler
export function response(ctx) {
    util.error("Failed to fetch relatedPosts", "LambdaFailure", ctx.result)
    return ctx.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"
                }
            ]
        }
    ]
}
```

この場合、エラーおよび `errorMessage`、`errorType`、`data` が `data.errors[0]` オブジェクトに存在するため、`allPosts[0].relatedPosts` は *null* になります。

### Lambda 関数から
<a name="from-the-lam-function-js"></a>

AWS AppSync は、Lambda 関数がスローするエラーも理解します。Lambda プログラミングモデルを使用し、*処理される*エラーを発生させることができます。Lambda 関数からエラーがスローされた場合、 AWS AppSync は現在のフィールドの解決に失敗します。Lambda から返されたエラーメッセージのみがレスポンスに設定されます。また現在のところ、Lambda 関数からエラーを発生させて、クライアントにエラー関連以外のデータを渡すことはできません。

**注記**  
注意 : Lambda 関数が*処理されない*エラーを発生させた場合、 AWS AppSync は によって設定されたエラーメッセージを使用します。

以下の Lambda 関数はエラーを発生させます。

```
export const handler = async (event) => {
  console.log('Received event {}', JSON.stringify(event, 3))
  throw new Error('I always fail.')
}
```

エラーはレスポンスハンドラーで受信されます。`util.appendError` でレスポンスにエラーを追加することで、GraphQL レスポンスで返すことができます。これを行うには、 AWS AppSync 関数レスポンスハンドラーを次のように変更します。

```
// the lambdaInvoke response handler
export function response(ctx) {
  const { error, result } = ctx;
  if (error) {
    util.appendError(error.message, error.type, result);
  }
  return result;
}
```

これにより、以下のような GraphQL レスポンスが返されます。

```
{
  "data": {
    "allPosts": null
  },
  "errors": [
    {
      "path": [
        "allPosts"
      ],
      "data": null,
      "errorType": "Lambda:Unhandled",
      "errorInfo": null,
      "locations": [
        {
          "line": 2,
          "column": 3,
          "sourceName": null
        }
      ],
      "message": "I fail. always"
    }
  ]
}
```

## 高度なユースケース: バッチ処理
<a name="advanced-use-case-batching-js"></a>

この例の Lambda 関数には、指定した投稿に関連する投稿のリストを返す `relatedPosts` フィールドが含まれています。この例のクエリでは、Lambda 関数からの `allPosts` フィールドの呼び出しにより 5 件の投稿が返されます。返された各投稿に対して `relatedPosts` の解決も指定しているので、`relatedPosts` フィールドの処理が続けて 5 回呼び出されます。

```
query {
    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 {   // 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)。これによりアプリケーションのレイテンシーとコストが増大します。

この問題を解決する 1 つの方法は、同様なフィールドのリゾルバーリクエストを同時にバッチ処理することです。この例では、Lambda 関数は指定された 1 つの投稿に関連する投稿のリストを解決するのではなく、指定された一連の投稿に関連する投稿のリストを解決できます。

これを実証するために、`relatedPosts` に対するバッチ処理を行うようにリゾルバーを更新してみましょう。

```
import { util } from '@aws-appsync/utils';

export function request(ctx) {
  const {source, args} = ctx
  return {
    operation: ctx.info.fieldName === 'relatedPosts' ? 'BatchInvoke' : 'Invoke',
    payload: { field: ctx.info.fieldName, arguments: args, source },
  };
}

export function response(ctx) {
  const { error, result } = ctx;
  if (error) {
    util.appendError(error.message, error.type, result);
  }
  return result;
}
```

このコードでは、解決対象の`fieldName` が `relatedPosts` である場合に、オペレーションが `Invoke` から `BatchInvoke` に変更されます。次に、**[バッチ処理の設定]** セクションで関数のバッチ処理を有効にします。最大バッチサイズを `5` に設定します。**[保存]** を選択します。

この変更により、Lambda 関数は `relatedPosts` の解決時に入力として以下を受け取ります。

```
[
    {
        "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
]
```

Lambda コードを更新して、`relatedPosts` に対するバッチ処理を行うことができます。

```
export const handler = async (event) => {
  console.log('Received event {}', JSON.stringify(event, 3))
  //throw new Error('I fail. always')

  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: [],
  }
  
  if (!event.field && event.length){
    console.log(`Got a BatchInvoke Request. The payload has ${event.length} items to resolve.`);
    return event.map(e => relatedPosts[e.source.id])
  }

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

### 個々のエラーを返す
<a name="returning-individual-errors-js"></a>

Lambda 関数から単一のエラーを返せることや、レスポンスハンドラーから 1 つのエラーを生成できることは以前の例で説明しました。バッチ処理を呼び出した場合、Lambda 関数からエラーが発生すると、バッチ処理全体が失敗としてフラグ付けされます。これは、データストアとの接続が切れた場合など、回復不可能なエラーが発生するシナリオでは問題ないかもしれません。ここでは、バッチ処理の一部が成功し、他が失敗した場合、エラーと有効なデータの両方を返すことができます。 AWS AppSync では、バッチ処理のレスポンスがバッチの元のサイズと一致する要素のリストとなるように要求されるため、エラーから有効なデータが識別できるようなデータ構造を定義する必要があります。

例えば、関連する一連の投稿が返されることを Lambda 関数が期待している場合には、`Response` オブジェクトのリストを返すように選択できます。この場合、各オブジェクトに任意の *data*、*errorMessage*、および *errorType* フィールドが含まれます。*errorMessage* フィールドが存在する場合は、エラーが発生したことを意味します。

次のコードは Lambda 関数の更新方法を示しています。

```
export const handler = async (event) => {
console.log('Received event {}', JSON.stringify(event, 3))
  // throw new Error('I fail. always')
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: [],
  }
  
  if (!event.field && event.length){
console.log(`Got a BatchInvoke Request. The payload has ${event.length} items to resolve.`);
    return event.map(e => {
// return an error for post 2
if (e.source.id === '2') {
return { 'data': null, 'errorMessage': 'Error Happened', 'errorType': 'ERROR' }
      }
      return {data: relatedPosts[e.source.id]}
      })
  }

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

`relatedPosts` リゾルバーコードを更新します。

```
import { util } from '@aws-appsync/utils';

export function request(ctx) {
  const {source, args} = ctx
  return {
    operation: ctx.info.fieldName === 'relatedPosts' ? 'BatchInvoke' : 'Invoke',
    payload: { field: ctx.info.fieldName, arguments: args, source },
  };
}

export function response(ctx) {
  const { error, result } = ctx;
  if (error) {
    util.appendError(error.message, error.type, result);
  } else if (result.errorMessage) {
    util.appendError(result.errorMessage, result.errorType, result.data)
  } else if (ctx.info.fieldName === 'relatedPosts') {
      return result.data
  } else {
      return result
  }
}
```

レスポンスハンドラーは、`Invoke` オペレーションで Lambda 関数から返されるエラーをチェックし、`BatchInvoke` オペレーションの個々の項目について返されたエラーをチェックしてから、最後に `fieldName` をチェックするようになりました。`relatedPosts`に対して、関数は `result.data` を返します。その他のすべてのフィールドでは、関数は `result` を返すだけです。例えば、以下のクエリを参照してください。

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

このクエリでは、次のような GraphQL レスポンスが返されます。

```
{
  "data": {
    "allPosts": [
      {
        "id": "1",
        "relatedPosts": [
          {
            "id": "4"
          }
        ]
      },
      {
        "id": "2",
        "relatedPosts": null
      },
      {
        "id": "3",
        "relatedPosts": [
          {
            "id": "2"
          },
          {
            "id": "1"
          }
        ]
      },
      {
        "id": "4",
        "relatedPosts": [
          {
            "id": "2"
          },
          {
            "id": "1"
          }
        ]
      },
      {
        "id": "5",
        "relatedPosts": []
      }
    ]
  },
  "errors": [
    {
      "path": [
        "allPosts",
        1,
        "relatedPosts"
      ],
      "data": null,
      "errorType": "ERROR",
      "errorInfo": null,
      "locations": [
        {
          "line": 4,
          "column": 5,
          "sourceName": null
        }
      ],
      "message": "Error Happened"
    }
  ]
}
```

### 最大バッチサイズの設定
<a name="configure-max-batch-size-js"></a>

リゾルバーで最大バッチサイズを設定するには、 AWS Command Line Interface () で次のコマンドを使用しますAWS CLI。

```
$ aws appsync create-resolver --api-id <api-id> --type-name Query --field-name relatedPosts \
 --code "<code-goes-here>" \
 --runtime name=APPSYNC_JS,runtimeVersion=1.0.0 \
 --data-source-name "<lambda-datasource>" \ 
 --max-batch-size X
```

**注記**  
リクエストマッピングテンプレートを提供するときは、バッチ処理を使用する `BatchInvoke` オペレーションを使用する必要があります。