

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# 에서 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 AppSync AWS Lambda 와 함께 사용하여 모든 GraphQL 필드를 확인할 수 있습니다. 예를 들어, GraphQL 쿼리는 Amazon Relational Database Service(Amazon RDS) 인스턴스로 호출을 보내고, GraphQL 뮤테이션은 Amazon Kinesis 스트림에 쓸 수 있습니다. 이 단원에서는 GraphQL 필드 작업의 호출에 따라 비즈니스 로직을 수행하는 Lambda 함수의 작성 방법을 설명합니다.

## Lambda 함수 생성
<a name="create-a-lam-function"></a>

다음 예는 블로그 게시물 애플리케이션의 일부로 블로그 게시물에 대해 다양한 연산을 수행하는 `Node.js`로 작성된 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 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별로 게시물을 검색하고, 게시물을 추가하고, 게시물 목록을 가져오고, 지정된 게시물에 대해 관련 게시물을 가져오는 작업을 처리합니다.

 **참고:** `event.field`에 대해 `switch` 명령문을 사용하면 Lambda 함수가 현재 해석 중인 필드를 확인할 수 있습니다.

 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) 단원을 참조하세요.

이 단계에서는 `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`.

그런 다음 **작업 메뉴**에서 **런타임 업데이트**를 선택한 다음 **단위 해석기(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 변형
<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 쿼리
<a name="getpost-query"></a>

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

### allPosts 쿼리
<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`는 오류가 발생한 경우 외부 데이터를 클라이언트로 반환할 때 유용합니다. GraphQL 최종 응답에서 `errors`에 `data` 객체가 추가됩니다.

다음 예시는 `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 프로그래밍 모델은 *handled* 오류를 발생시킵니다. 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` 필드 호출은 5개 게시물을 반환합니다. 각각의 반환된 게시물에 대해 `relatedPosts`를 해석하도록 지정했으므로 `relatedPosts` 필드 작업이 5회 호출됩니다.

```
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 함수에서 오류가 발생하면 전체 배치가 실패로 플래그 지정됩니다. 이는 데이터 스토어와의 연결 중단 같은 취소 불가능한 오류가 발생하는 특정 시나리오를 잘 설명할 수 있습니다. 하지만 배치의 일부 항목이 성공하고 다른 항목이 실패하는 경우, 오류 및 유효한 데이터를 모두 반환할 수 있습니다. 배치의 원래 크기와 일치하는 요소를 나열하려면 AWS AppSync에 배치 응답이 필요하므로 유효한 데이터를 오류와 구분할 수 있는 데이터 구조를 정의해야 합니다.

예를 들어 Lambda 함수가 관련 게시물의 일괄 처리를 반환해야 하는 경우 각 객체에 선택적 *data*, *errorMessage* 및 *errorType* 필드가 있는 `Response` 객체 목록을 반환하도록 선택할 수 있습니다. *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 함수에 최대 5개 항목의 배치로 요청을 보냅니다. 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` 작업을 사용하여 일괄 처리를 사용해야 합니다.

다음 명령을 사용하여 직접 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 해석기에서 최대 일괄 처리 크기가 10으로 설정되어 있어도 `Items`는 10개의 그룹으로 일괄 처리되지 않습니다. 대신 GraphQL 사양에 따라 순차적으로 실행됩니다.

실제 배치 뮤테이션을 수행하려면 다음 예제를 따라 두 번째 뮤테이션을 사용할 수 있습니다.

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

직접 Lambda 해석기를 사용한 일괄 처리 사용에 대한 자세한 내용은 [Direct Lambda 해석기](resolver-mapping-template-reference-lambda.md#direct-lambda-resolvers) 단원을 참조하세요.