

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

# AWS AppSync 해석기 매핑 템플릿 참조(VTL)
<a name="resolver-mapping-template-reference"></a>

**참고**  
이제 우리는 주로 APPSYNC\$1JS 런타임과 해당 문서를 지원합니다. [여기](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)에서 APPSYNC\$1JS 런타임과 해당 안내서를 사용해 보세요.

다음 섹션에서는 매핑 템플릿에서 유틸리티 작업을 사용하는 방법을 설명합니다.
+  [ 해석기 매핑 템플릿 개요 ](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-overview.html) - 해석기가 AWS AppSync에서 작동하는 방법을 자세히 알아봅니다.
+  [ 해석기 매핑 템플릿 프로그래밍 설명서 ](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-programming-guide.html) - 기본 VTL 데이터 구조 및 로직 처리에 대해 자세히 알아봅니다.
+  [ 해석기 매핑 템플릿 컨텍스트 참조 ](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference.html) - 컨텍스트 맵과 이 맵이 해석기에 사용되는 방식을 자세히 알아봅니다.
+  [ 해석기 매핑 템플릿 유틸리티 참조 ](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-util-reference.html) - 유틸리티를 사용하여 코드를 단순화하는 방법을 자세히 알아봅니다.
+  [ DynamoDB용 해석기 매핑 템플릿 참조 ](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-dynamodb.html) - 해석기가 DynamoDB와 상호 작용하는 방식을 자세히 알아봅니다.
+  [ RDS용 해석기 매핑 템플릿 참조 ](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-rds.html) - 해석기 구조 및 RDS와의 상호 작용에 대해 자세히 알아봅니다.
+  [ OpenSearch용 해석기 매핑 템플릿 참조 ](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-elasticsearch.html) - 해석기 요청 및 응답 구조와 OpenSearch Service와의 상호 작용에 대해 자세히 알아봅니다.
+  [ Lambda용 해석기 매핑 템플릿 참조 ](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-lambda.html) - 해석기 요청 및 응답 구조와 Lambda와의 상호 작용에 대해 자세히 알아봅니다.
+  [ EventBridge용 해석기 매핑 템플릿 참조 ](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-eventbridge.html) - 해석기 요청 및 응답 구조와 EventBridge와의 상호 작용에 대해 자세히 알아봅니다.
+  [ None 데이터 소스용 해석기 매핑 템플릿 참조 ](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-none.html) - 해석기 요청 및 응답 구조와 NONE 데이터 소스와의 상호 작용에 대해 자세히 알아봅니다.
+  [ HTTP용 해석기 매핑 템플릿 참조 ](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-http.html) - 해석기 요청 및 응답 구조와 HTTP 엔드포인트와의 상호 작용에 대해 자세히 알아봅니다.

# AWS AppSync 해석기 매핑 템플릿 개요
<a name="resolver-mapping-template-reference-overview"></a>

**참고**  
이제 우리는 주로 APPSYNC\$1JS 런타임과 해당 문서를 지원합니다. [여기](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)에서 APPSYNC\$1JS 런타임과 해당 안내서를 사용해 보세요.

AWS AppSync를 사용하면 리소스에 대한 작업을 수행하여 GraphQL 요청에 응답할 수 있습니다. 쿼리 또는 변형을 실행하려는 각 GraphQL 필드에 대해 데이터 소스와 통신하려면 해석기를 연결해야 합니다. 일반적으로 이 통신은 데이터 소스에 대해 고유한 파라미터 또는 작업을 통해 이루어집니다.

해석기는 GraphQL과 데이터 소스를 연결하는 커넥터입니다. 수신되는 GraphQL 요청을 백엔드 데이터 소스에 대한 지침으로 변환하는 방법과 해당 데이터 소스의 응답을 다시 GraphQL 응답으로 변환하는 방법을 AWS AppSync에 알려줍니다. 매핑 템플릿은 [Apache Velocity Template Language(VTL)](https://velocity.apache.org/engine/1.7/user-guide.html)로 작성되는데, VTL에서는 요청을 입력으로 받아서 해석기에 대한 명령문을 포함하는 JSON 문서를 출력합니다. GraphQL 필드의 인수 전달과 같은 단순 명령은 물론, 항목을 DynamoDB에 삽입하기 전에 인수를 루핑하여 항목을 빌드하는 등 복잡한 명령에도 매핑 템플릿을 사용할 수 있습니다.

 AWS AppSync에는 매핑 템플릿을 약간 다른 방식으로 활용하는 두 가지 유형의 해석기가 있습니다.
+ 유닛 해석기
+ 파이프라인 해석기

## 유닛 해석기
<a name="unit-resolvers"></a>

유닛 해석기는 요청 및 응답 템플릿만 포함하는 독립형 객체입니다. 단일 데이터 원본에서 항목 나열과 같은 간단한 단일 작업에 사용합니다.
+ 요청 템플릿: GraphQL 작업이 구문 분석된 후 들어오는 요청을 받아서 선택한 데이터 소스 작업에 대한 요청 구성으로 변환합니다.
+ 응답 템플릿: 데이터 소스의 응답을 해석하여 GraphQL 필드 출력 유형의 셰이프에 매핑합니다.

## 파이프라인 해석기
<a name="pipeline-resolvers"></a>

파이프라인 해석기에는 순차적으로 실행되는 *함수*가 하나 이상 포함되어 있습니다. 각 함수에는 요청 템플릿과 응답 템플릿이 포함되어 있습니다. 파이프라인 해석기에는 템플릿에 포함된 함수 시퀀스를 둘러싸는 *이전* 템플릿과 *이후* 템플릿도 있습니다. *이후* 템플릿은 GraphQL 필드 출력 유형에 매핑됩니다. 파이프라인 해석기는 응답 템플릿이 출력을 매핑하는 방식이 유닛 해석기와 다릅니다. 파이프라인 해석기는 다른 함수의 입력값이나 파이프라인 해석기의 *이후* 템플릿을 포함하여 원하는 모든 출력에 매핑할 수 있습니다.

 파이프라인 해석기 *함수*를 사용하면 스키마의 여러 해석기에서 재사용할 수 있는 공통 로직을 작성할 수 있습니다. 함수는 데이터 소스에 직업 연결되고 유닛 해석기와 마찬가지로 동일한 요청 및 응답 매핑 템플릿 형식을 포함하고 있습니다.

다음 다이어그램은 왼쪽은 유닛 해석기, 오른쪽은 파이프라인 해석기의 프로세스 흐름을 보여줍니다.

![\[단일 데이터 소스와 통신하는 유닛 해석기 다이어그램과 여러 데이터 소스와 통신하는 파이프라인 해석기 다이어그램입니다.\]](http://docs.aws.amazon.com/ko_kr/appsync/latest/devguide/images/unit-pipeline-resolver.png)


파이프라인 해석기에는 유닛 해석기가 지원하는 기능의 상위 집합이 포함되어 있지만 약간 더 복잡합니다.

### 파이프라인 해석기의 구조
<a name="anatomy-of-a-pipeline-resolver"></a>

파이프라인 해석기는 **이전** 매핑 템플릿, **이후** 매핑 템플릿과 함수 목록으로 구성됩니다. 각 함수에는 데이터 소스에 대해 실행되는 **요청** 및 **응답** 매핑 템플릿이 있습니다. 파이프라인 해석기는 함수 목록에 실행을 위임하기 때문에 자신은 어떠한 데이터 원본에도 연결되지 않습니다. 유닛 해석기와 함수는 데이터 원본에 대해 작업을 실행하는 기본 요소입니다. 자세한 내용은 [해석기 매핑 템플릿 개요](#aws-appsync-resolver-mapping-template-reference-overview)를 참조하세요.

#### 이전 매핑 템플릿
<a name="before-mapping-template"></a>

이 파이프라인 해석기의 요청 매핑 템플릿(또는 **이전** 단계)을 사용하면 정의된 함수를 실행하기 전에 몇 가지 준비 로직을 수행할 수 있습니다.

#### 함수 목록
<a name="functions-list"></a>

파이프라인 해석기가 순서대로 실행하는 함수 목록입니다. 파이프라인 해석기 요청 매핑 템플릿 평가 결과는 첫 번째 함수에 `$ctx.prev.result`로 사용할 수 있습니다. 각 함수 출력은 다음 함수에 `$ctx.prev.result`로 사용할 수 있습니다.

#### After 매핑 템플릿
<a name="after-mapping-template"></a>

이 파이프라인 해석기의 응답 매핑 템플릿(또는 **이후** 단계)을 사용하면 마지막 함수의 출력에서 예상 GraphQL 필드 유형으로 몇 가지 최종 매핑 로직을 수행할 수 있습니다. 함수 목록의 마지막 함수 출력은 파이프라인 해석기 매핑 템플릿에서 `$ctx.prev.result` 또는 `$ctx.result`로 사용할 수 있습니다.

#### 실행 흐름
<a name="execution-flow"></a>

함수 2개로 구성된 파이프라인 해석기의 경우, 아래 목록은 해석기 간접 호출 시 실행 흐름을 나타냅니다.

![\[GraphQL request flow diagram showing template processing and data source interactions.\]](http://docs.aws.amazon.com/ko_kr/appsync/latest/devguide/images/PipelineResolver.jpg)


1. 파이프라인 해석기 이전 매핑 템플릿

1. 함수 1: 함수 요청 매핑 템플릿

1. 함수 1: 데이터 원본 호출

1. 함수 1: 함수 응답 매핑 템플릿

1. 함수 2: 함수 요청 매핑 템플릿

1. 함수 2: 데이터 원본 호출

1. 함수 2: 함수 응답 매핑 템플릿

1. 파이프라인 해석기 이후 매핑 템플릿

**참고**  
파이프라인 해석기 실행 흐름은 단방향이고 해석기에서 정적으로 정의됩니다.

#### 유용한 Apache Velocity Template Language(VTL) 유틸리티
<a name="useful-apache-velocity-template-language-vtl-utilities"></a>

애플리케이션의 복잡성이 증가함에 따라 개발 생산성을 높이기 위해 여기서 VTL 유틸리티 및 명령이 사용됩니다. 다음 유틸리티는 파이프라인 해석기로 작업할 때 유용할 수 있습니다.

##### \$1ctx.stash
<a name="ctx-stash"></a>

stash는 각 해석기 및 함수 매핑 템플릿 내에서 사용할 수 있는 `Map`입니다. 단일 해석기가 실행되는 동안에는 동일한 stash 인스턴스가 사용됩니다. 이는 파이프라인 해석기 내에서 stash를 사용해 요청 및 응답 매핑 템플릿 간에 그리고 함수 간에 임의 데이터를 전달할 수 있다는 의미입니다. stash는 동일한 메서드를 [Java 맵](https://docs.oracle.com/javase/8/docs/api/java/util/Map.html) 데이터 구조로 노출합니다.

##### \$1ctx.prev.result
<a name="ctx-prev-result"></a>

`$ctx.prev.result`는 파이프라인 해석기에서 실행된 이전 작업의 결과를 나타냅니다.

이전 작업이 파이프라인 해석기의 이전 매핑 템플릿인 경우 `$ctx.prev.result`는 템플릿 평가의 출력을 나타내며 파이프라인의 첫 번째 함수에서 사용할 수 있게 됩니다. 이전 작업이 첫 번째 함수였으면 `$ctx.prev.result`는 첫 번째 함수의 결과를 나타내고, 파이프라인의 두 번째 함수에 사용할 수 있습니다. 이전 작업이 마지막 함수였으면 `$ctx.prev.result`는 마지막 함수의 결과를 나타내고, 파이프라인 해석기 이후 매핑 템플릿에 사용할 수 있습니다.

##### \$1return(data: Object)
<a name="return-data-object"></a>

`#return(data: Object)` 명령은 임의의 매핑 템플릿에서 영구적으로 반환해야 하는 경우 유용합니다. 로직의 가장 가까운 범위 지정 블록에서 반환하기 때문에 `#return(data: Object)`은 프로그래밍 언어의 *return* 키워드와 유사합니다. 이는 해석기 매핑 템플릿 내에서 `#return`을 사용하면 해석기에서 반환함을 의미합니다. 해석기 매핑 템플릿에서 `#return(data: Object)`를 사용하면 GraphQL 필드에 `data`가 설정됩니다. 또는 함수 매핑 템플릿의 `#return(data: Object)`를 사용하면 함수에서 반환하고, 파이프라인의 다음 함수 또는 해석기 응답 매핑 템플릿으로 실행합니다.

##### \$1return
<a name="return"></a>

이는 `#return(data: Object)`와 동일하지만 대신 `null`이 반환됩니다.

##### \$1util.error
<a name="util-error"></a>

`$util.error` 유틸리티는 필드 오류를 발생시키는 데 유용합니다. 함수 매핑 템플릿 내에서 `$util.error`를 사용하면 즉시 필드 오류가 발생해 후속 함수가 실행되지 않도록 방지합니다. 세부 정보 및 기타 `$util.error` 서명은 [해석기 매핑 템플릿 유틸리티 참조](resolver-util-reference.md#aws-appsync-resolver-mapping-template-util-reference)를 참조하세요.

##### \$1util.appendError
<a name="util-appenderror"></a>

`$util.appendError`는 `$util.error()`와 유사하지만 매핑 템플릿 평가를 중단하지 않는다는 큰 차이점이 있습니다. 대신 필드에 오류가 있다는 신호를 보내지만 템플릿이 계속해서 평가되도록 하고 이어서 데이터를 반환합니다. 함수 내에서 `$util.appendError`를 사용하면 파이프라인의 실행 흐름이 중단되지 않습니다. 세부 정보 및 기타 `$util.error` 서명은 [해석기 매핑 템플릿 유틸리티 참조](resolver-util-reference.md#aws-appsync-resolver-mapping-template-util-reference)를 참조하세요.

## 예제 템플릿
<a name="example-template"></a>

다음 GraphQL 쿼리를 사용하여 `Post` 유형을 반환하는 `getPost(id:ID!)`라는 필드에 DynamoDB 데이터 소스와 **단위** 해석기가 있다고 가정해 보겠습니다.

```
getPost(id:1){
    id
    title
    content
}
```

해석기 템플릿은 다음과 같습니다.

```
{
    "version" : "2018-05-29",
    "operation" : "GetItem",
    "key" : {
        "id" : $util.dynamodb.toDynamoDBJson($ctx.args.id)
    }
}
```

이 템플릿은 `id` 입력 파라미터 값 `1`을 `${ctx.args.id}` 대신에 사용하고 다음 JSON을 생성합니다.

```
{
    "version" : "2018-05-29",
    "operation" : "GetItem",
    "key" : {
        "id" : { "S" : "1" }
    }
}
```

AWS AppSync는이 템플릿을 사용하여 DynamoDB와 통신하고 데이터를 가져오는(또는 적절한 경우 다른 작업을 수행하는) 지침을 생성합니다. 데이터가 반환된 후에는 AWS AppSync에서 선택적 응답 매핑 템플릿을 실행합니다. 이 템플릿은 데이터 셰이핑 또는 로직을 수행할 때 사용할 수 있습니다. 예를 들어 DynamoDB에서 결과를 가져오는 경우 결과는 다음과 같습니다.

```
{
        "id" : 1,
        "theTitle" : "AWS AppSync works offline!",
        "theContent-part1" : "It also has realtime functionality",
        "theContent-part2" : "using GraphQL"
}
```

다음 응답 매핑 템플릿을 사용하여 필드 중 두 개를 단일 필드로 결합할 수 있습니다.

```
{
        "id" : $util.toJson($context.data.id),
        "title" : $util.toJson($context.data.theTitle),
        "content" : $util.toJson("${context.data.theContent-part1} ${context.data.theContent-part2}")
}
```

템플릿이 데이터에 적용된 이후의 데이터 형태 형성은 다음과 같습니다.

```
{
        "id" : 1,
        "title" : "AWS AppSync works offline!",
        "content" : "It also has realtime functionality using GraphQL"
}
```

이 데이터는 다음과 같이 클라이언트에 대한 응답으로 제공됩니다.

```
{
        "data": {
                "getPost":      {
                        "id" : 1,
                        "title" : "AWS AppSync works offline!",
                        "content" : "It also has realtime functionality using GraphQL"
                }
        }
}
```

대부분 환경에서 응답 매핑 템플릿은 데이터의 단순 전달로, 개별 항목 또는 항목 목록을 반환하는 경우 대부분 달라집니다. 개별 항목에 대한 전달:

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

목록에 대한 전달:

```
$util.toJson($context.result.items)
```

유닛 해석기와 파이프라인 해석기 둘 다에 대한 예를 더 보려면 [해석기 자습서](tutorials.md#aws-appsync-tutorials)를 참조하세요.

## 평가된 맵핑 템플릿 역직렬화 규칙
<a name="evaluated-mapping-template-deserialization-rules"></a>

매핑 템플릿은 문자열로 평가됩니다. AWS AppSync에서 출력 문자열은 JSON 구조를 따라야 유효합니다.

또한 다음과 같은 역직렬화 규칙이 적용됩니다.

### JSON 객체에는 중복 키가 허용되지 않습니다.
<a name="duplicate-keys-are-not-allowed-in-json-objects"></a>

평가된 매핑 템플릿 문자열이 JSON 객체를 나타내거나 중복 키가 있는 객체를 포함하는 경우 매핑 템플릿은 다음 오류 메시지를 반환합니다.

 `Duplicate field 'aField' detected on Object. Duplicate JSON keys are not allowed.` 

평가된 요청 매핑 템플릿의 중복 키 예:

```
{
    "version": "2018-05-29",
    "operation": "Invoke",
    "payload": {
        "field": "getPost",
        "postId": "1",
        "field": "getPost" ## key 'field' has been redefined
    }
}
```

이 오류를 수정하려면 JSON 객체에서 키를 다시 정의하지 마십시오.

### 후행 문자는 JSON 객체에서 허용되지 않습니다.
<a name="trailing-characters-are-not-allowed-in-json-objects"></a>

평가된 매핑 템플릿 문자열이 JSON 객체를 나타내며 후행 외부 문자를 포함하는 경우 매핑 템플릿은 다음 오류 메시지를 반환합니다.

 `Trailing characters at the end of the JSON string are not allowed.` 

평가된 요청 매핑 템플릿의 후행 문자 예:

```
{
    "version": "2018-05-29",
    "operation": "Invoke",
    "payload": {
        "field": "getPost",
        "postId": "1",
    }
}extraneouschars
```

이 오류를 수정하려면 평가된 템플릿이 JSON으로 엄격하게 평가되는지 확인합니다.

# AWS AppSync 해석기 매핑 템플릿 프로그래밍 가이드
<a name="resolver-mapping-template-reference-programming-guide"></a>

**참고**  
이제 우리는 주로 APPSYNC\$1JS 런타임과 해당 문서를 지원합니다. [여기](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)에서 APPSYNC\$1JS 런타임과 해당 안내서를 사용해 보세요.

Apache Velocity 템플릿 언어(VTL)를 사용한 프로그래밍에 대한 쿡북 스타일의 자습서입니다 AWS AppSync. JavaScript, C 또는 Java 같은 다른 프로그래밍에 대해 잘 알고 있다면 매우 쉬울 것입니다.

AWS AppSync는 VTL을 사용하여 클라이언트의 GraphQL 요청을 데이터 소스에 대한 요청으로 변환합니다. 그런 다음 이 프로세스를 역순으로 수행하여 데이터 원본 응답을 GraphQL 응답으로 다시 변환합니다. VTL은 다음과 같은 기술을 사용하여 웹 애플리케이션의 표준 요청/응답 흐름 요청과 응답을 둘 다 처리할 수 있는 논리적인 템플릿 언어입니다.
+ 새 항목의 기본값
+ 입력 확인 및 서식 지정
+ 데이터 변환 및 셰이핑
+ 목록, 맵 및 배열을 반복하여 값을 추출하거나 변경
+ 사용자 자격 증명 기반 응답 필터링/변경
+ 복잡한 권한 부여 검사

예를 들면 GraphQL 인수에서 서비스의 전화번호를 확인하거나 DynamoDB에 저장하기 전에 입력 파라미터를 대문자로 변환해야 할 수도 있습니다. 또는 클라이언트 시스템에서 GraphQL 인수, JWT 토큰 클레임 또는 HTTP 헤더에 코드를 포함시켜 제공하도록 하거나, 코드가 목록의 특정 문자열과 일치할 경우에만 데이터로 응답하도록 할 수 있습니다. 이는 모두 VTL in AWS AppSync로 수행할 수 있는 논리적 검사입니다.

VTL에서는 익숙한 프로그래밍 기술로 로직을 적용할 수 있습니다. 하지만 사용자 기반의 성장에 따라 GraphQL API를 확장하려면 표준 요청/응답 흐름 내에서만 실행해야 합니다. 또한 AWS AppSync는 해석기로를 지원 AWS Lambda 하므로 유연성이 더 필요한 경우 선택한 프로그래밍 언어(Node.js, Python, Go, Java 등)로 Lambda 함수를 작성할 수 있습니다.

## 설정
<a name="setup"></a>

언어 학습 시 사용하는 일반적인 기술 중 하나는 결과(예: JavaScript의 `console.log(variable)`)를 출력하여 어떻게 되는지 보는 것입니다. 이 자습서에서는 단순 GraphQL 스키마를 생성하고 값 맵을 Lambda 함수에 전달함으로써 이 기술을 설명합니다. Lambda 함수가 값을 출력하고 나서 값에 응답합니다. 따라서 요청/응답 흐름을 이해하고 다양한 프로그래밍 기법을 볼 수 있습니다.

다음 GraphQL 스키마를 생성하는 것부터 시작합니다.

```
type Query {
    get(id: ID, meta: String): Thing
}

type Thing {
    id: ID!
    title: String!
    meta: String
}

schema {
    query: Query
}
```

이제 Node.js를 언어로 사용하여 다음 AWS Lambda 함수를 생성합니다.

```
exports.handler = (event, context, callback) => {
    console.log('VTL details: ', event);
    callback(null, event);
};
```

 AWS AppSync 콘솔의 **데이터 소스** 창에서이 Lambda 함수를 새 데이터 소스로 추가합니다. 콘솔의 **스키마** 페이지로 돌아가서 오른쪽 `get(...):Thing` 쿼리 옆에 있는 **연결** 버튼을 클릭합니다. 요청 템플릿으로는 **Invoke and forward arguments(인수 호출 및 전달)** 메뉴에서 기존 템플릿을 선택합니다. 응답 템플릿으로는 **Lambda 결과 반환(Return Lambda result)**을 선택합니다.

Lambda 함수에 대한 Amazon CloudWatch Logs를 한 위치에서 열고 AWS AppSync 콘솔의 **쿼리** 탭에서 다음 GraphQL 쿼리를 실행합니다.

```
query test {
  get(id:123 meta:"testing"){
    id
    meta
  }
}
```

Lambda 함수가 `id:123` 및 `meta:testing`를 다시 되풀이하여 표시하므로 GraphQL 응답에 이 두 요소가 포함되어야 합니다. 몇 초 후에는 CloudWatch Logs에서 이러한 세부 정보와 함께 레코드를 볼 수 있습니다.

## 변수
<a name="variables"></a>

VTL은 [참조](https://velocity.apache.org/engine/1.7/user-guide.html#references)를 사용합니다. 이 참조는 데이터를 저장하거나 조작하는 데 사용할 수 있습니다. VTL에는 변수, 속성 및 메서드라는 세 가지 유형이 있습니다. 변수는 앞에 `$` 기호가 붙으며 `#set` 지시문을 사용하여 생성됩니다.

```
#set($var = "a string")
```

변수는 숫자, 문자열, 배열, 목록 및 맵 등 다른 언어에서 친숙한 유형과 비슷한 유형을 저장합니다. Lambda 해석기의 기본 요청 템플릿에서 JSON 페이로드가 전송됨을 눈치채셨을 것입니다.

```
"payload": $util.toJson($context.arguments)
```

여기에서 알아두어야 할 몇 가지 사항이 있습니다. 먼저 AWS AppSync는 일반적인 작업을 위한 몇 가지 편의 기능을 제공합니다. 이 예에서는 `$util.toJson`이 변수를 JSON으로 변환합니다. 두 번째, `$context.arguments` 변수가 GraphQL 요청에서 맵 객체로 자동 채워집니다. 다음과 같이 새 맵을 생성할 수 있습니다.

```
#set( $myMap = {
  "id": $context.arguments.id,
  "meta": "stuff",
  "upperMeta" : $context.arguments.meta.toUpperCase()
} )
```

이제 `$myMap`이라는 변수를 만들었으며, 이 변수에는 `id`, `meta` 및`upperMeta` 키가 있습니다. 이 코드는 몇 가지 다른 것도 보여줍니다.
+  `id`가 GraphQL 인수의 키로 채워집니다. VTL에서는 클라이언트의 인수를 가져오기 위해 일반적으로 이렇게 작동합니다.
+  `meta`가 기본값을 보여주는 값으로 하드코딩됩니다.
+  `upperMeta`가 `meta` 메서드를 사용하여 `.toUpperCase()` 인수로 변환됩니다.

요청 템플릿 맨 위에 이전 코드를 추가하고 `payload`를 새 `$myMap` 변수로 변경합니다.

```
"payload": $util.toJson($myMap)
```

Lambda 함수를 실행하고 나면 CloudWatch logs에서 응답 변경 내용은 물론 이 데이터도 확인할 수 있습니다. 이 자습서의 나머지를 진행하면서 비슷한 테스트를 실행할 수 있도록 `$myMap`을 채운 상태로 유지하겠습니다.

또한 변수에서 *properties\$1*를 설정할 수도 있습니다. 이러한 항목은 단순 문자열, 배열 또는 JSON입니다.

```
#set($myMap.myProperty = "ABC")
#set($myMap.arrProperty = ["Write", "Some", "GraphQL"])
#set($myMap.jsonProperty = {
    "AppSync" : "Offline and Realtime",
    "Cognito" : "AuthN and AuthZ"
})
```

### 자동 참조
<a name="quiet-references"></a>

VTL은 기본적으로 템플릿 언어이므로 개발자가 제공하는 모든 참조가 `.toString()`을 수행합니다. 참조가 정의되지 않은 경우 실제 참조 표현을 문자열로 출력합니다. 예제:

```
#set($myValue = 5)
##Prints '5'
$myValue

##Prints '$somethingelse'
$somethingelse
```

이를 해결하도록 VTL에 *quiet reference* 또는 *silent reference* 구문이 있으며, 이 구문은 템플릿 엔진에 이 동작을 숨기도록 지시합니다. 이에 대한 구문은 `$!{}`입니다. 예를 들어 `$!{somethingelse}`를 사용하도록 이전 코드를 조금 변경한 경우 출력이 표시되지 않습니다.

```
#set($myValue = 5)
##Prints '5'
$myValue

##Nothing prints out
$!{somethingelse}
```

## 메서드 직접 호출
<a name="calling-methods"></a>

이전 예제에서 변수를 생성하고 동시에 값을 설정하는 방법을 보여드렸습니다. 맵에 데이터를 추가하여 이 작업을 다음과 같이 두 단계로 수행할 수도 있었습니다.

```
#set ($myMap = {})
#set ($myList = [])

##Nothing prints out
$!{myMap.put("id", "first value")}
##Prints "first value"
$!{myMap.put("id", "another value")}
##Prints true
$!{myList.add("something")}
```

 **하지만** 이 동작에 대해 알아야 할 것이 있습니다. 위와 같이 자동 참조 표기 `$!{}`를 사용하여 메서드를 호출할 수 있더라도, 실행된 메서드의 반환 값은 숨길 수 없습니다. 위에서 `##Prints "first value"` 및 `##Prints true`를 사용한 이유는 바로 이 때문입니다. 이 문으로 키가 이미 존재하는 값을 삽입하는 등 맵이나 목록을 반복하려 할 때 오류가 발생할 수 있습니다. 출력이 평가 시 예기치 않은 문자열을 템플릿에 추가하기 때문입니다.

경우에 따라 `#set` 지시문을 사용하여 메서드를 호출하고 변수를 무시하는 것이 이 문제를 해결하는 방법이 되기도 합니다. 예제:

```
#set ($myMap = {})
#set($discard = $myMap.put("id", "first value"))
```

예상치 못한 문자열이 템플릿에 인쇄되지 않도록 하므로 템플릿에서이 기술을 사용할 수 있습니다. AWS AppSync는 더 간결한 표기법으로 동일한 동작을 제공하는 대체 편의 함수를 제공합니다. 이 함수를 사용하면 이러한 구현 세부 사항에 대해 개발자가 생각할 필요가 없습니다. `$util.quiet()` 또는 `$util.qr()` 별칭으로 이 함수에 액세스할 수 있습니다. 예제:

```
#set ($myMap = {})
#set ($myList = [])

##Nothing prints out
$util.quiet($myMap.put("id", "first value"))
##Nothing prints out
$util.qr($myList.add("something"))
```

## 문자열
<a name="strings"></a>

여러 프로그래밍 언어와 마찬가지로, 문자열을 다루기가 어려울 수 있으며, 특히 변수에서 문자열을 구성하려는 경우에는 더욱 더 그렇습니다. VTL과 함께 제공되는 공통된 사항이 있습니다.

DynamoDB 같은 데이터 소스에 데이터를 문자열로 삽입하려 하지만 이 문자열이 GraphQL 인수 같은 변수에서 채워진다고 가정해 보겠습니다. 문자열에는 큰따옴표가 있으며 문자열에서 변수를 참조하려면 `"${}"`만 있으면 됩니다(따라서 [자동 참조 표기](https://velocity.apache.org/engine/1.7/user-guide.html#quiet-reference-notation)에서는 `!`가 없습니다). 이 형태는 JavaScript의 템플릿 리터럴과 비슷합니다([https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template\$1literals](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals)).

```
#set($firstname = "Jeff")
$!{myMap.put("Firstname", "${firstname}")}
```

`"id" : { "S" : "$util.autoId()"}`와 같은 자동 ID를 생성하려 할 때 또는 GraphQL 클라이언트에서 인수를 사용할 때 `"author": { "S" : "${context.arguments.author}"}`처럼 DynamoDB 요청 템플릿에서 이 형태를 볼 수 있습니다. 다시 말해서 문자열 내부에서 메서드의 결과나 변수를 참조하여 데이터를 채울 수 있다는 뜻입니다.

또한 하위 문자열을 추출하는 등 Java [String 클래스](https://docs.oracle.com/javase/6/docs/api/java/lang/String.html)의 퍼블릭 메서드를 사용할 수도 있습니다.

```
#set($bigstring = "This is a long string, I want to pull out everything after the comma")
#set ($comma = $bigstring.indexOf(','))
#set ($comma = $comma +2)
#set ($substring = $bigstring.substring($comma))

$util.qr($myMap.put("substring", "${substring}"))
```

문자열 연결도 매우 일반적인 작업입니다. 변수 참조만을 사용하여 또는 정적 값과 함께 이 작업을 수행할 수 있습니다.

```
#set($s1 = "Hello")
#set($s2 = " World")

$util.qr($myMap.put("concat","$s1$s2"))
$util.qr($myMap.put("concat2","Second $s1 World"))
```

## Loops
<a name="loops"></a>

이제 변수를 생성하고 메서드를 호출했으므로 몇 가지 로직을 코드에 추가할 수 있습니다. 다른 언어와는 달리, VTL에서는 루프만 허용됩니다. 루프에서 반복 횟수는 미리 지정되어 있습니다. Velocity에는 `do..while`이 없습니다. 이 설계는 평가 프로세스가 항상 종료되도록 하고 GraphQL 작업 실행 시 확장성 범위를 제공합니다.

루프는 `#foreach`와 함께 생성되며 **루프 변수**와 **반복 가능한 객체**(예: 배열, 목록, 맵 또는 모음)를 제공해야 합니다. `#foreach` 루프와 관련된 클래식 프로그래밍 예제는 모음에서 항목을 반복하고 출력하는 것이므로, 여기서는 이러한 항목을 추출하여 맵에 추가합니다.

```
#set($start = 0)
#set($end = 5)
#set($range = [$start..$end])

#foreach($i in $range)
   ##$util.qr($myMap.put($i, "abc"))
   ##$util.qr($myMap.put($i, $i.toString()+"foo")) ##Concat variable with string
   $util.qr($myMap.put($i, "${i}foo"))     ##Reference a variable in a string with "${varname}"
#end
```

이 예제는 몇 가지 사항을 보여줍니다. 첫 번째는 범위 `[..]` 연산자와 함께 변수를 사용하여 반복 가능한 객체를 생성합니다. 그러고 각 항목이 작업에 사용할 수 있는 변수 `$i`에 의해 참조됩니다. 이전 예제에서는 2파운드 `##`으로 표시된 **주석**도 볼 수 있습니다. 또한 이 예제는 키 또는 값의 루프 변수 사용과 문자열을 사용한 다양한 연결 방법도 보여줍니다.

`$i`는 정수이므로 `.toString()` 메서드를 직접적으로 호출할 수 있습니다. GraphQL INT 유형의 경우 이 메서드가 유용할 수 있습니다.

또한 범위 연산자를 직접 사용할 수도 있습니다. 예를 들면 다음과 같습니다.

```
#foreach($item in [1..5])
    ...
#end
```

## 배열
<a name="arrays"></a>

지금까지는 맵을 잘 조작해 왔지만, VTL에서는 배열도 일반적으로 사용합니다. 아래와 같이 배열을 사용하여 `.isEmpty()`, `.size()`, `.set()`, `.get()` 및 `.add()` 같은 기본 메서드에 액세스할 수도 있습니다.

```
#set($array = [])
#set($idx = 0)

##adding elements
$util.qr($array.add("element in array"))
$util.qr($myMap.put("array", $array[$idx]))

##initialize array vals on create
#set($arr2 = [42, "a string", 21, "test"])

$util.qr($myMap.put("arr2", $arr2[$idx]))
$util.qr($myMap.put("isEmpty", $array.isEmpty()))  ##isEmpty == false
$util.qr($myMap.put("size", $array.size()))

##Get and set items in an array
$util.qr($myMap.put("set", $array.set(0, 'changing array value')))
$util.qr($myMap.put("get", $array.get(0)))
```

이전 예에서는 배열 인덱스 표기를 사용하여 `arr2[$idx]`가 있는 요소를 검색했습니다. 비슷한 방법으로 맵/딕셔너리에서 이름별로 조회할 수 있습니다.

```
#set($result = {
    "Author" : "Nadia",
    "Topic" : "GraphQL"
})

$util.qr($myMap.put("Author", $result["Author"]))
```

이 방법은 조건 사용 시 응답 템플릿의 데이터 원본에서 가져오는 결과를 필터링할 때 매우 일반적으로 사용합니다.

## 조건부 확인
<a name="conditional-checks"></a>

`#foreach`에 관한 이전 단원에서는 VTL에서 로직을 사용하여 데이터를 변환하는 몇 가지 예를 살펴보았습니다. 또한 실행 시간에 조건부 확인을 적용하여 데이터를 평가할 수 있습니다.

```
#if(!$array.isEmpty())
    $util.qr($myMap.put("ifCheck", "Array not empty"))
#else
    $util.qr($myMap.put("ifCheck", "Your array is empty"))
#end
```

부울 표현식에 대한 위의 `#if()` 점검은 잘 작동하지만, 연산자와 `#elseif()`를 사용하여 분기시킬 수도 있습니다.

```
#if ($arr2.size() == 0)
    $util.qr($myMap.put("elseIfCheck", "You forgot to put anything into this array!"))
#elseif ($arr2.size() == 1)
    $util.qr($myMap.put("elseIfCheck", "Good start but please add more stuff"))
#else
    $util.qr($myMap.put("elseIfCheck", "Good job!"))
#end
```

이 두 가지 예제에는 부정(\$1) 및 같음(==)이 나와 있습니다. 또한 \$1\$1, &&, >, <, >=, <= 및 \$1=을 사용할 수 있습니다.

```
#set($T = true)
#set($F = false)

#if ($T || $F)
  $util.qr($myMap.put("OR", "TRUE"))
#end

#if ($T && $F)
  $util.qr($myMap.put("AND", "TRUE"))
#end
```

 **참고:** `Boolean.FALSE` 및 `null`만 조건문에서 false로 간주됩니다. 제로(0)와 빈 문자열("")은 false로 간주되지 않습니다.

## 연산자
<a name="operators"></a>

작업자가 연산자 없이 산술 작업을 수행할 수 있는 완벽한 프로그래밍 언어는 없습니다. 다음은 시작하는 데 도움이 될 몇 가지 예제입니다.

```
#set($x = 5)
#set($y = 7)
#set($z = $x + $y)
#set($x-y = $x - $y)
#set($xy = $x * $y)
#set($xDIVy = $x / $y)
#set($xMODy = $x % $y)

$util.qr($myMap.put("z", $z))
$util.qr($myMap.put("x-y", $x-y))
$util.qr($myMap.put("x*y", $xy))
$util.qr($myMap.put("x/y", $xDIVy))
$util.qr($myMap.put("x|y", $xMODy))
```

### 루프와 조건부 함께 사용
<a name="loops-and-conditionals-together"></a>

데이터 원본 쓰기 또는 읽기 등 VTL에서 데이터를 변환할 때는 객체를 루핑하고 나서 확인을 수행한 다음 작업을 수행하는 것이 일반적입니다. 이전 단원의 도구 중 일부를 결합하여 다양한 기능을 이용할 수 있습니다. 한 가지 유용한 점이라면, `#foreach`가 각 항목에 `.count`를 자동으로 제공한다는 사실입니다.

```
#foreach ($item in $arr2)
  #set($idx = "item" + $foreach.count)
  $util.qr($myMap.put($idx, $item))
#end
```

예를 들면 단순히 맵에서 특정 크기 이하인 값을 추출하고자 하는 경우가 있습니다. 이 개수 값에 조건문 및 `#break` 문을 사용하여 다음을 수행할 수 있습니다.

```
#set($hashmap = {
  "DynamoDB" : "https://aws.amazon.com/dynamodb/",
  "Amplify" : "https://github.com/aws/aws-amplify",
  "DynamoDB2" : "https://aws.amazon.com/dynamodb/",
  "Amplify2" : "https://github.com/aws/aws-amplify"
})

#foreach ($key in $hashmap.keySet())
    #if($foreach.count > 2)
    #break
  #end
    $util.qr($myMap.put($key, $hashmap.get($key)))
#end
```

이전 `#foreach`는 `.keySet()`를 사용하여 반복되는 데, 이것을 맵에서 사용할 수 있습니다. 이렇게 하면 `$key`를 가져와서 `.get($key)`를 사용하여 값을 참조할 수 있는 액세스 권한이 부여됩니다. AWS AppSync에서 클라이언트의 GraphQL 인수는 맵으로 저장됩니다. 이러한 인수는 `.entrySet()`을 통해 반복할 수 있으며, 이러한 반복을 통해 키와 값 모두에 한 번에 액세스하고, 입력 변환이나 확인 등 복잡한 조건부 검증을 수행하거나 다른 변수를 채울 수 있습니다.

```
#foreach( $entry in $context.arguments.entrySet() )
#if ($entry.key == "XYZ" && $entry.value == "BAD")
    #set($myvar = "...")
  #else
    #break
  #end
#end
```

다른 일반적인 예제에서는 데이터 동기화 시 초기 객체 버전(충돌 해결 시 매우 중요) 또는 권한 부여 확인을 위한 객체의 기본 소유자(이 블록 게시물을 생성한 Mary) 같은 기본 정보가 자동으로 채워지므로, 다음과 같습니다.

```
#set($myMap.owner ="Mary")
#set($myMap.defaultOwners = ["Admins", "Editors"])
```

## 컨텍스트
<a name="context"></a>

VTL을 사용하여 AWS AppSync 해석기에서 로직 점검을 수행하는 데 익숙해지셨을 테니, 지금부터는 컨텍스트 객체를 살펴보겠습니다.

```
$util.qr($myMap.put("context", $context))
```

여기에는 GraphQL 요청에서 액세스할 수 있는 모든 정보가 들어 있습니다. 자세한 설명은 [컨텍스트 참조](resolver-context-reference.md#aws-appsync-resolver-mapping-template-context-reference)를 참조하십시오.

## 필터링
<a name="filtering"></a>

지금까지 이 자습서에서는 매우 단순한 JSON 변환을 사용하여 Lambda 함수의 모든 정보가 GraphQL 쿼리로 반환되었습니다.

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

VTL 로직은 데이터 원본에서 응답을 가져올 때, 특히 리소스에 대한 권한 부여 확인을 수행할 때 매우 유용합니다. 몇 가지 예를 살펴보겠습니다. 먼저 다음과 같이 응답 템플릿을 변경해 보겠습니다.

```
#set($data = {
    "id" : "456",
    "meta" : "Valid Response"
})

$util.toJson($data)
```

GraphQL 작업에서 어떤 일이 일어나든, 하드코딩된 값이 클라이언트로 반환됩니다. 이 자습서의 앞부분에서 조건문에 대해 알아볼 때 `meta` 값에서 설정했던 Lambda 응답으로 `elseIfCheck` 필드가 채워지도록 이 코드를 조금 변경합니다.

```
#set($data = {
    "id" : "456"
})

#foreach($item in $context.result.entrySet())
    #if($item.key == "elseIfCheck")
        $util.qr($data.put("meta", $item.value))
    #end
#end

$util.toJson($data)
```

 `$context.result`는 맵이므로 `entrySet()`을 사용하여 반환된 키나 값에 대해 로직을 수행할 수 있습니다. `$context.identity`에는 GraphQL 작업을 수행한 사용자에 대한 정보가 포함되어 있으므로, 데이터 원본에서 권한 부여 정보를 반환할 때 로직에 근거하여 사용자에게 데이터 전체 또는 일부를 반환하거나 데이터를 반환하지 않을 수 있습니다. 응답 템플릿을 다음과 같은 형태로 변경합니다.

```
#if($context.result["id"] == 123)
    $util.toJson($context.result)
  #else
    $util.unauthorized()
#end
```

GraphQL 쿼리를 실행할 경우 데이터가 보통 때처럼 반환됩니다. 하지만 ID 인수를 123(`query test { get(id:456 meta:"badrequest"){} }`) 이외의 것으로 변경할 경우 권한 부여 실패 메시지가 표시됩니다.

[권한 부여 사용 사례](security-authorization-use-cases.md#aws-appsync-security-authorization-use-cases) 단원에서 권한 부여 시나리오의 다른 예를 확인할 수 있습니다.

### 템플릿 샘플
<a name="appendix-template-sample"></a>

자습서를 따라 진행했다면 단계별로 이 템플릿을 빌드했을 것입니다. 그렇지 않은 경우, 테스트를 위해 복사할 수 있는 템플릿이 아래에 포함되어 있습니다.

 **요청 템플릿** 

```
#set( $myMap = {
  "id": $context.arguments.id,
  "meta": "stuff",
  "upperMeta" : "$context.arguments.meta.toUpperCase()"
} )

##This is how you would do it in two steps with a "quiet reference" and you can use it for invoking methods, such as .put() to add items to a Map
#set ($myMap2 = {})
$util.qr($myMap2.put("id", "first value"))

## Properties are created with a dot notation
#set($myMap.myProperty = "ABC")
#set($myMap.arrProperty = ["Write", "Some", "GraphQL"])
#set($myMap.jsonProperty = {
    "AppSync" : "Offline and Realtime",
    "Cognito" : "AuthN and AuthZ"
})

##When you are inside a string and just have ${} without ! it means stuff inside curly braces are a reference
#set($firstname = "Jeff")
$util.qr($myMap.put("Firstname", "${firstname}"))

#set($bigstring = "This is a long string, I want to pull out everything after the comma")
#set ($comma = $bigstring.indexOf(','))
#set ($comma = $comma +2)
#set ($substring = $bigstring.substring($comma))
$util.qr($myMap.put("substring", "${substring}"))

##Classic for-each loop over N items:
#set($start = 0)
#set($end = 5)
#set($range = [$start..$end])
#foreach($i in $range)          ##Can also use range operator directly like #foreach($item in [1...5])
   ##$util.qr($myMap.put($i, "abc"))
   ##$util.qr($myMap.put($i, $i.toString()+"foo")) ##Concat variable with string
   $util.qr($myMap.put($i, "${i}foo"))     ##Reference a variable in a string with "${varname)"
#end

##Operators don't work
#set($x = 5)
#set($y = 7)
#set($z = $x + $y)
#set($x-y = $x - $y)
#set($xy = $x * $y)
#set($xDIVy = $x / $y)
#set($xMODy = $x % $y)
$util.qr($myMap.put("z", $z))
$util.qr($myMap.put("x-y", $x-y))
$util.qr($myMap.put("x*y", $xy))
$util.qr($myMap.put("x/y", $xDIVy))
$util.qr($myMap.put("x|y", $xMODy))

##arrays
#set($array = ["first"])
#set($idx = 0)
$util.qr($myMap.put("array", $array[$idx]))
##initialize array vals on create
#set($arr2 = [42, "a string", 21, "test"])
$util.qr($myMap.put("arr2", $arr2[$idx]))
$util.qr($myMap.put("isEmpty", $array.isEmpty()))  ##Returns false
$util.qr($myMap.put("size", $array.size()))
##Get and set items in an array
$util.qr($myMap.put("set", $array.set(0, 'changing array value')))
$util.qr($myMap.put("get", $array.get(0)))

##Lookup by name from a Map/dictionary in a similar way:
#set($result = {
    "Author" : "Nadia",
    "Topic" : "GraphQL"
})
$util.qr($myMap.put("Author", $result["Author"]))


##Conditional examples
#if(!$array.isEmpty())
$util.qr($myMap.put("ifCheck", "Array not empty"))
#else
$util.qr($myMap.put("ifCheck", "Your array is empty"))
#end

#if ($arr2.size() == 0)
$util.qr($myMap.put("elseIfCheck", "You forgot to put anything into this array!"))
#elseif ($arr2.size() == 1)
$util.qr($myMap.put("elseIfCheck", "Good start but please add more stuff"))
#else
$util.qr($myMap.put("elseIfCheck", "Good job!"))
#end

##Above showed negation(!) and equality (==), we can also use OR, AND, >, <, >=, <=, and !=
#set($T = true)
#set($F = false)
#if ($T || $F)
  $util.qr($myMap.put("OR", "TRUE"))
#end

#if ($T && $F)
  $util.qr($myMap.put("AND", "TRUE"))
#end

##Using the foreach loop counter - $foreach.count
#foreach ($item in $arr2)
  #set($idx = "item" + $foreach.count)
  $util.qr($myMap.put($idx, $item))
#end

##Using a Map and plucking out keys/vals
#set($hashmap = {
    "DynamoDB" : "https://aws.amazon.com/dynamodb/",
    "Amplify" : "https://github.com/aws/aws-amplify",
    "DynamoDB2" : "https://aws.amazon.com/dynamodb/",
    "Amplify2" : "https://github.com/aws/aws-amplify"
})

#foreach ($key in $hashmap.keySet())
    #if($foreach.count > 2)
        #break
    #end
    $util.qr($myMap.put($key, $hashmap.get($key)))
#end

##concatenate strings
#set($s1 = "Hello")
#set($s2 = " World")
$util.qr($myMap.put("concat","$s1$s2"))
$util.qr($myMap.put("concat2","Second $s1 World"))

$util.qr($myMap.put("context", $context))

{
    "version" : "2017-02-28",
    "operation": "Invoke",
    "payload": $util.toJson($myMap)
}
```

 **응답 템플릿** 

```
#set($data = {
"id" : "456"
})
#foreach($item in $context.result.entrySet())   ##$context.result is a MAP so we use entrySet()
    #if($item.key == "ifCheck")
        $util.qr($data.put("meta", "$item.value"))
    #end
#end

##Uncomment this out if you want to test and remove the below #if check
##$util.toJson($data)

#if($context.result["id"] == 123)
    $util.toJson($context.result)
  #else
    $util.unauthorized()
#end
```

# AWS AppSync 해석기 매핑 템플릿 컨텍스트 참조
<a name="resolver-context-reference"></a>

**참고**  
이제 우리는 주로 APPSYNC\$1JS 런타임과 해당 문서를 지원합니다. [여기](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)에서 APPSYNC\$1JS 런타임과 해당 안내서를 사용해 보세요.

AWS AppSync 는 해석기 매핑 템플릿 작업을 위한 변수 및 함수 집합을 정의합니다. 이렇게 하면 GraphQL을 사용하는 데이터에 대한 논리적 조작이 더 쉬워집니다. 이 문서에서는 이러한 함수를 설명하고 템플릿을 사용하는 예를 제공합니다.

## `$context`에 액세스
<a name="accessing-the-context"></a>

`$context` 변수는 해석기 간접 호출에 대한 모든 컨텍스트 정보를 보관하는 맵입니다. 이 변수의 구조는 다음과 같습니다.

```
{
   "arguments" : { ... },
   "source" : { ... },
   "result" : { ... },
   "identity" : { ... },
   "request" : { ... },
   "info": { ... }
}
```

**참고**  
값을 검색하기 위해 키로 사전/맵 항목(예: `context`의 항목)에 액세스하려는 경우 Velocity Template Language(VTL)를 통해 `<dictionary-element>.<key-name>` 표기법을 직접 사용할 수 있습니다. 하지만 이는 키 이름이 특수 문자인 경우(예: 밑줄(\$1))와 같이 모든 경우에서 작동하지 않을 수 있습니다. 항상 `<dictionary-element>.get("<key-name>")` 주석을 사용하는 것이 좋습니다.

`$context` 맵의 각 필드는 다음과 같이 정의됩니다.

### `$context` 필드
<a name="accessing-the-context-list"></a>

** `arguments` **  
이 필드에 대한 모든 GraphQL 인수를 포함하는 맵입니다.

** `identity` **  
호출자에 대한 정보를 포함하는 객체입니다. 이 필드의 구조에 대한 자세한 내용은 [자격 증명](#aws-appsync-resolver-context-reference-identity)을 참조하십시오.

** `source` **  
상위 필드의 해결 방법을 포함하는 맵입니다.

** `stash` **  
stash는 각 해석기 및 함수 매핑 템플릿 내에서 사용할 수 있는 맵입니다. 단일 해석기가 실행되는 동안에는 동일한 stash 인스턴스가 사용됩니다. 이는 파이프라인 해석기 내에서 stash를 사용해 요청 및 응답 매핑 템플릿 간에 그리고 함수 간에 임의 데이터를 전달할 수 있다는 의미입니다. stash는 동일한 메서드를 [Java Map](https://docs.oracle.com/javase/8/docs/api/java/util/Map.html) 데이터 구조로 노출합니다.

** `result` **  
해석기의 결과를 포함하고 있는 컨테이너입니다. 이 필드는 매핑 템플릿에 응답하는 경우에만 사용할 수 있습니다.  
예를 들어, 다음 쿼리의 `author` 필드를 해석하는 경우:  

```
query {
    getPost(id: 1234) {
        postId
        title
        content
        author {
            id
            name
        }
    }
}
```
응답 매핑 템플릿을 처리하는 경우 사용할 수 있는 전체 `$context` 변수는 다음과 같습니다.  

```
{
  "arguments" : {
    id: "1234"
  },
  "source": {},
  "result" : {
      "postId": "1234",
      "title": "Some title",
      "content": "Some content",
      "author": {
        "id": "5678",
        "name": "Author Name"
      }
  },
  "identity" : {
      "sourceIp" : ["x.x.x.x"],
      "userArn" : "arn:aws:iam::123456789012:user/appsync",
      "accountId" : "666666666666",
      "user" : "AIDAAAAAAAAAAAAAAAAAA"
  }
}
```

** `prev.result` **  
파이프라인 해석기에서 실행된 이전 작업의 결과입니다.  
이전 작업이 파이프라인 해석기 이전 매핑 템플릿이었으면 `$ctx.prev.result`는 템플릿의 평가 결과를 나타내고 파이프라인의 첫 번째 함수에 사용할 수 있습니다.  
이전 작업이 첫 번째 함수였으면 `$ctx.prev.result`는 첫 번째 함수의 결과를 나타내고, 파이프라인의 두 번째 함수에 사용할 수 있습니다.  
이전 작업이 마지막 함수였으면 `$ctx.prev.result`는 마지막 함수의 결과를 나타내고, 파이프라인 해석기 이후 매핑 템플릿에 사용할 수 있습니다.

** `info` **  
GraphQL 요청에 대한 정보가 포함된 객체입니다. 이 필드의 구조는 [정보](#aws-appsync-resolver-context-reference-info)를 참조하십시오.

### ID
<a name="aws-appsync-resolver-context-reference-identity"></a>

`identity` 섹션에는 호출자에 대한 정보가 포함되어 있습니다. 이 섹션의 모양은 AWS AppSync API의 권한 부여 유형에 따라 다릅니다.

 AWS AppSync 보안 옵션에 대한 자세한 내용은 [권한 부여 및 인증을](security-authz.md#aws-appsync-security) 참조하세요.

** `API_KEY` 권한 부여**  
`identity` 필드는 채워져 있지 않습니다.

**`AWS_LAMBDA` 권한 부여**  
`identity`에는 요청을 승인하는 Lambda 함수가 반환한 동일한 `resolverContext` 콘텐츠가 포함된 `resolverContext` 키가 포함되어 있습니다.

** `AWS_IAM` 권한 부여**  
`identity`의 형식은 다음과 같습니다.  

```
{
    "accountId" : "string",
    "cognitoIdentityPoolId" : "string",
    "cognitoIdentityId" : "string",
    "sourceIp" : ["string"],
    "username" : "string", // IAM user principal
    "userArn" : "string",
    "cognitoIdentityAuthType" : "string", // authenticated/unauthenticated based on the identity type
    "cognitoIdentityAuthProvider" : "string" // the auth provider that was used to obtain the credentials
}
```

** `AMAZON_COGNITO_USER_POOLS` 권한 부여**  
`identity`의 형식은 다음과 같습니다.  

```
{
    "sub" : "uuid",
    "issuer" : "string",
    "username" : "string"
    "claims" : { ... },
    "sourceIp" : ["x.x.x.x"],
    "defaultAuthStrategy" : "string"
}
```

각 필드는 다음과 같이 정의됩니다.

** `accountId` **  
호출자의 AWS 계정 ID입니다.

** `claims` **  
사용자의 클레임입니다.

** `cognitoIdentityAuthType` **  
자격 증명 유형을 기반으로 인증되거나 인증되지 않습니다.

** `cognitoIdentityAuthProvider` **  
요청에 서명하는 데 사용되는 보안 인증 정보를 얻는 데 사용되는 외부 자격 증명 공급자 정보를 쉼표로 구분한 목록입니다.

** `cognitoIdentityId` **  
호출자의 Amazon Cognito 자격 증명 ID입니다.

** `cognitoIdentityPoolId` **  
호출자와 연결된 Amazon Cognito 자격 증명 풀 ID입니다.

** `defaultAuthStrategy` **  
이 호출자의 기본 권한 부여 전략(`ALLOW` 또는 `DENY`)입니다.

** `issuer` **  
토큰 발행자입니다.

** `sourceIp` **  
가 AWS AppSync 수신하는 호출자의 소스 IP 주소입니다. 요청에 `x-forwarded-for` 헤더가 포함되어 있지 않으면 소스 IP 값에 TCP 연결의 단일 IP 주소만 포함됩니다. 요청에 `x-forwarded-for` 헤더가 포함되어 있으면 소스 IP는 TCP 연결의 IP 주소 이외에 `x-forwarded-for` 헤더의 IP 주소 목록입니다.

** `sub` **  
인증된 사용자의 UUID입니다.

** `user` **  
IAM 사용자입니다.

** `userArn` **  
IAM 사용자의 Amazon 리소스 이름(ARN)입니다.

** `username` **  
인증된 사용자의 사용자 이름입니다. `AMAZON_COGNITO_USER_POOLS` 권한 부여 시 *username*의 값은 *cognito:username* 속성의 값입니다. `AWS_IAM` 권한 부여의 경우 *사용자 이름*의 값은 AWS 사용자 보안 주체의 값입니다. Amazon Cognito 자격 증명 풀에서 판매된 자격 증명으로 IAM 인증을 사용하는 경우 `cognitoIdentityId`를 사용하는 것이 좋습니다.

### 요청 헤더에 액세스
<a name="aws-appsync-resolver-context-reference-util"></a>

AWS AppSync는 클라이언트에서 사용자 지정 헤더를 전달하고를 사용하여 GraphQL 해석기에서 액세스할 수 있도록 지원합니다`$context.request.headers`. 그런 다음 데이터 소스에 데이터 삽입 또는 권한 부여 검사 등과 같은 작업에 헤더 값을 사용할 수 있습니다. 다음 예에 표시된 것처럼 명령줄에서 API 키와 함께 `$curl`을 사용하여 단일 또는 다중 요청 헤더를 사용할 수 있습니다.

**단일 헤더의 예** 

다음과 같이 값이 `nadia`인 `custom`의 헤더를 설정한다고 가정해 보겠습니다.

```
curl -XPOST -H "Content-Type:application/graphql" -H "custom:nadia" -H "x-api-key:<API-KEY-VALUE>" -d '{"query":"mutation { createEvent(name: \"demo\", when: \"Next Friday!\", where: \"Here!\") {id name when where description}}"}' https://<ENDPOINT>/graphql
```

그러면 `$context.request.headers.custom`을 사용하여 이 헤더에 액세스할 수 있습니다. 예를 들어, DynamoDB에 대한 다음 VTL에 있을 수 있습니다.

```
"custom": $util.dynamodb.toDynamoDBJson($context.request.headers.custom)
```

**다중 헤더의 예** 

또한 단일 요청에서 여러 헤더를 전달하고 해석기 매핑 템플릿에서 이러한 헤더에 액세스할 수 있습니다. 예를 들어, `custom` 헤더가 다음 두 값으로 설정되어 있는 경우:

```
curl -XPOST -H "Content-Type:application/graphql" -H "custom:bailey" -H "custom:nadia" -H "x-api-key:<API-KEY-VALUE>" -d '{"query":"mutation { createEvent(name: \"demo\", when: \"Next Friday!\", where: \"Here!\") {id name when where description}}"}' https://<ENDPOINT>/graphql
```

이러한 두 값에는 배열(예: `$context.request.headers.custom[1]`)로 액세스할 수 있습니다.

**참고**  
AWS AppSync 는에 쿠키 헤더를 노출하지 않습니다`$context.request.headers`.

### 사용자 지정 도메인 이름 요청 액세스
<a name="aws-access-requested-custom-domain-names"></a>

AWS AppSync 는 APIs의 GraphQL 및 실시간 엔드포인트에 액세스하는 데 사용할 수 있는 사용자 지정 도메인 구성을 지원합니다. 사용자 지정 도메인 이름으로 요청하는 경우 `$context.request.domainName`을 사용하여 도메인 이름을 가져올 수 있습니다.

기본 GraphQL 엔드포인트 도메인 이름을 사용하는 경우 값은 `null`입니다.

### 정보
<a name="aws-appsync-resolver-context-reference-info"></a>

이 `info` 섹션에는 GraphQL 요청에 대한 정보가 포함되어 있습니다. 이 섹션은 다음과 같은 형식으로 되어 있습니다.

```
{
    "fieldName": "string",
    "parentTypeName": "string",
    "variables": { ... },
    "selectionSetList": ["string"],
    "selectionSetGraphQL": "string"
}
```

각 필드는 다음과 같이 정의됩니다.

** `fieldName` **  
현재 확인 중인 필드의 이름입니다.

** `parentTypeName` **  
현재 확인 중인 필드에 대한 상위 유형의 이름입니다.

** `variables` **  
GraphQL 요청에 전달된 모든 변수를 포함하는 맵입니다.

** `selectionSetList` **  
GraphQL 선택 세트에 있는 필드의 목록 표현입니다. 별칭이 있는 필드는 필드 이름이 아닌 별칭 이름으로만 참조됩니다. 다음 예제는 이 구조를 자세히 보여 줍니다.

** `selectionSetGraphQL` **  
GraphQL 스키마 정의 언어(SDL)로 형식이 지정된 선택 세트의 문자열 표현입니다. 조각이 선택 세트에 병합되지는 않지만 다음 예제와 같이 인라인 조각은 유지됩니다.

**참고**  
`context.info`에서 `$utils.toJson()`을 사용하는 경우 `selectionSetGraphQL` 및 `selectionSetList`가 반환하는 값은 기본적으로 직렬화되지 않습니다.

예를 들어, 다음 쿼리의 `getPost` 필드를 해석하는 경우:

```
query {
  getPost(id: $postId) {
    postId
    title
    secondTitle: title
    content
    author(id: $authorId) {
      authorId
      name
    }
    secondAuthor(id: "789") {
      authorId
    }
    ... on Post {
      inlineFrag: comments: {
        id
      }
    }
    ... postFrag
  }
}

fragment postFrag on Post {
  postFrag: comments: {
    id
  }
}
```

매핑 템플릿을 처리할 때 사용할 수 있는 전체 `$context.info` 변수는 다음과 같습니다.

```
{
  "fieldName": "getPost",
  "parentTypeName": "Query",
  "variables": {
    "postId": "123",
    "authorId": "456"
  },
  "selectionSetList": [
    "postId",
    "title",
    "secondTitle"
    "content",
    "author",
    "author/authorId",
    "author/name",
    "secondAuthor",
    "secondAuthor/authorId",
    "inlineFragComments",
    "inlineFragComments/id",
    "postFragComments",
    "postFragComments/id"
  ],
  "selectionSetGraphQL": "{\n  getPost(id: $postId) {\n    postId\n    title\n    secondTitle: title\n    content\n    author(id: $authorId) {\n      authorId\n      name\n    }\n    secondAuthor(id: \"789\") {\n      authorId\n    }\n    ... on Post {\n      inlineFrag: comments {\n        id\n      }\n    }\n    ... postFrag\n  }\n}"
}
```

`selectionSetList`는 현재 유형에 속하는 필드만 노출합니다. 현재 유형이 인터페이스 또는 집합인 경우 인터페이스에 속하는 선택된 필드만 노출됩니다. 예를 들어 다음과 같은 스키마가 있습니다.

```
type Query {
    node(id: ID!): Node
}

interface Node {
    id: ID
}

type Post implements Node {
    id: ID
    title: String
    author: String
}

type Blog implements Node {
    id: ID
    title: String
    category: String
}
```

그리고 다음과 같은 쿼리가 있습니다.

```
query {
    node(id: "post1") {
        id
        ... on Post {
            title
        }

        ... on Blog {
            title
        }
    }
}
```

`Query.node` 필드 해상도에서 `$ctx.info.selectionSetList`를 호출하면 `id`만 노출됩니다.

```
"selectionSetList": [
    "id"
]
```

## 입력 삭제
<a name="sanitizing-inputs"></a>

애플리케이션은 외부 대상이 원래 목적 외에 애플리케이션을 사용하지 못하도록 신뢰할 수 없는 입력을 삭제해야 합니다. `$context`에는 `$context.arguments`, `$context.identity`, `$context.result`, `$context.info.variables` 및 `$context.request.headers`와 같은 속성의 사용자 입력이 포함되어 있으므로 매핑 템플릿에서 해당 값을 삭제하는 데 주의를 기울여야 합니다.

매핑 템플릿은 JSON을 나타내므로, 입력 삭제는 사용자 입력을 나타내는 문자열에서 JSON 예약 문자를 이스케이프 처리하는 형식을 사용합니다. 매핑 템플릿에 배치할 때 민감한 문자열 값에서 JSON 예약 문자를 이스케이프 처리하는 데 `$util.toJson()` 유틸리티를 사용하는 것이 좋습니다.

예를 들어 다음의 Lambda 요청 매핑 템플릿에서 안전하지 않은 고객 입력 문자열(`$context.arguments.id`)에 액세스했기 때문에 이스케이프 처리되지 않은 JSON 문자가 JSON 템플릿을 손상시키지 않도록 `$util.toJson()`으로 이 문자열을 래핑했습니다.

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

아래의 매핑 템플릿과는 반대로, 삭제 없이 `$context.arguments.id`를 직접 삽입합니다. 이러한 작업은 이스케이프 처리되지 않은 따옴표 또는 다른 JSON 예약 문자가 포함되어 있는 문자열에는 사용할 수 없으며, 수행할 경우 템플릿을 열지 못할 수도 있습니다.

```
## DO NOT DO THIS
{
    "version": "2017-02-28",
    "operation": "Invoke",
    "payload": {
        "field": "getPost",
        "postId": "$context.arguments.id" ## Unsafe! Do not insert $context string values without escaping JSON characters.
    }
}
```

# AWS AppSync 해석기 매핑 템플릿 유틸리티 참조
<a name="resolver-util-reference"></a>

**참고**  
이제 우리는 주로 APPSYNC\$1JS 런타임과 해당 문서를 지원합니다. [여기](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)에서 APPSYNC\$1JS 런타임과 해당 안내서를 사용해 보세요.

AWS AppSync는 GraphQL 해석기 내에서 데이터 소스와의 상호 작용을 간소화하는 데 사용할 수 있는 유틸리티 세트를 정의합니다. 이러한 유틸리티 중 일부는 ID 또는 타임스탬프 생성과 같이 모든 데이터 소스에서 일반적으로 사용됩니다. 다른 유틸리티는 데이터 소스 유형에 따라 다릅니다. 다음 유틸리티를 사용할 수 있습니다.
+  [ \$1util의 유틸리티 도우미 ](https://docs.aws.amazon.com/appsync/latest/devguide/utility-helpers-in-util.html) - \$1util 변수에는 데이터 작업에 도움이 되는 일반 유틸리티 메서드가 포함되어 있습니다. 달리 지정하지 않는 한, 모든 유틸리티는 UTF-8 문자 집합을 사용합니다.
+ [ AppSync 지침 ](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-directives.html) - AppSync는 개발자의 생산성을 높이기 위해 VTL 작성 시 지시문을 표시합니다.
+  [ \$1util.time의 시간 도우미 ](https://docs.aws.amazon.com/appsync/latest/devguide/time-helpers-in-util-time.html) - \$1util.time 변수에는 타임스탬프를 생성하고, 날짜 및 시간 형식 간에 변환하고, 날짜 및 시간 문자열을 구문 분석하는 데 도움이 되는 날짜 및 시간 메서드가 포함되어 있습니다. 날짜 및 시간 형식 구문은 [DateTimeFormatter](https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html)를 기반으로 하며, 여기서 자세한 설명을 참조할 수 있습니다.
+ [ \$1util.list의 목록 도우미 ](https://docs.aws.amazon.com/appsync/latest/devguide/list-helpers-in-util-list.html) - \$1util.list에는 사용 사례 필터링을 위해 목록에서 항목을 제거하거나 유지하는 등과 같은 일반적인 목록 작업에 유용한 메서드가 포함되어 있습니다.
+  [ \$1util.map의 맵 도우미 ](https://docs.aws.amazon.com/appsync/latest/devguide/utility-helpers-in-map.html) - \$1util.map에는 사용 사례 필터링을 위해 맵에서 항목을 제거하거나 유지하는 등과 같은 일반적인 맵 작업에 유용한 메서드가 포함되어 있습니다.
+  [ \$1util.dynamodb의 DynamoDB 도우미 ](https://docs.aws.amazon.com/appsync/latest/devguide/dynamodb-helpers-in-util-dynamodb.html) - \$1util.dynamodb에는 Amazon DynamoDB에 데이터 쓰기 및 읽기를 더 용이하게 하는 도우미 메서드가 포함되어 있습니다(예: 자동 유형 매핑 및 형식 지정).
+  [ \$1util.rds의 Amazon RDS 도우미 ](https://docs.aws.amazon.com/appsync/latest/devguide/rds-helpers-in-util-rds.html) - \$1util.rds에는 결과 출력에서 불필요한 데이터를 제거하여 RDS 작업의 형식을 지정하는 도우미 메서드가 포함되어 있습니다.
+  [ \$1util.http의 HTTP 도우미 ](https://docs.aws.amazon.com/appsync/latest/devguide/http-helpers-in-utils-http.html) - \$1util.http 유틸리티는 HTTP 요청 파라미터를 관리하고 응답 헤더를 추가하는 데 사용할 수 있는 도우미 메서드를 제공합니다.
+  [ \$1util.xml의 XML 도우미 ](https://docs.aws.amazon.com/appsync/latest/devguide/xml-helpers-in-utils-xml.html) - \$1util.xml에는 XML 응답을 JSON 또는 딕셔너리로 쉽게 변환할 수 있도록 하는 도우미 메서드가 포함되어 있습니다.
+  [ \$1util.transform의 변환 도우미 ](https://docs.aws.amazon.com/appsync/latest/devguide/transformation-helpers-in-utils-transform.html) - \$1util.transform에는 DynamoDB 필터 작업 등 데이터 소스에 대해 복잡한 작업을 더 쉽게 수행할 수 있는 도우미 메서드가 포함되어 있습니다.
+  [ \$1util.math의 수학 도우미](https://docs.aws.amazon.com/appsync/latest/devguide/math-helpers-in-util-math.html) - \$1util.math에는 일반적인 수학 작업에 도움이 되는 방법이 포함되어 있습니다.
+  [ \$1util.str의 문자열 도우미](https://docs.aws.amazon.com/appsync/latest/devguide/str-helpers-in-util-str.html) - \$1util.str에는 일반적인 문자열 작업에 도움이 되는 메서드가 포함되어 있습니다.
+  [ 확장 ](https://docs.aws.amazon.com/appsync/latest/devguide/extensions.html) - \$1extensions에는 해석기 내에서 추가 작업을 수행할 수 있는 일련의 메서드가 있습니다.

# \$1util의 유틸리티 도우미
<a name="utility-helpers-in-util"></a>

**참고**  
이제 우리는 주로 APPSYNC\$1JS 런타임과 해당 문서를 지원합니다. [여기](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)에서 APPSYNC\$1JS 런타임과 해당 안내서를 사용해 보세요.

`$util` 변수에는 데이터 작업에 도움이 되는 일반 유틸리티 메서드가 포함되어 있습니다. 달리 지정하지 않는 한, 모든 유틸리티는 UTF-8 문자 집합을 사용합니다.

## JSON 구문 분석 유틸리티
<a name="utility-helpers-in-json-parsing"></a>

### JSON 구문 분석 유틸리티 목록
<a name="utility-helpers-in-json-parsing-list"></a>

** **`$util.parseJson(String) : Object`** **  
‘문자열화된’ JSON을 가져와서 결과의 객체 표현을 반환합니다.

** **`$util.toJson(Object) : String`** **  
객체를 받아 해당 객체의 ‘문자열화된’ JSON 표현을 반환합니다.

## 인코딩 유틸리티
<a name="utility-helpers-in-encoding"></a>

### 인코딩 유틸리티 목록
<a name="utility-helpers-in-encoding-list"></a>

** **`$util.urlEncode(String) : String`** **  
입력 문자열을 `application/x-www-form-urlencoded` 인코딩 문자열로 반환합니다.

** **`$util.urlDecode(String) : String`** **  
`application/x-www-form-urlencoded` 인코딩 문자열을 인코딩되지 않은 형식으로 다시 디코딩합니다.

** **`$util.base64Encode( byte[] ) : String`** **  
입력을 base64 인코딩 문자열로 인코딩합니다.

** **`$util.base64Decode(String) : byte[]`** **  
데이터를 base64 인코딩 문자열에서 디코딩합니다.

## ID 생성 유틸리티
<a name="utility-helpers-in-id-gen"></a>

### ID 생성 유틸리티
<a name="utility-helpers-in-id-gen-list"></a>

** **`$util.autoId() : String`** **  
임의로 생성된 128비트 UUID를 반환합니다.

****`$util.autoUlid() : String`****  
무작위로 생성된 128비트 ULID(Universally Unique Lexicographically Sortable Identifier)를 반환합니다.

****`$util.autoKsuid() : String`****  
길이가 27인 문자열로 인코딩된 무작위로 생성된 128비트 KSUID(K-Sortable Unique Identifier) base62를 반환합니다.

## 오류 유틸리티
<a name="utility-helpers-in-error"></a>

### 오류 유틸리티 목록
<a name="utility-helpers-in-error-list"></a>

** `$util.error(String)` **  
사용자 지정 오류를 발생시킵니다. 요청 또는 응답 매핑 템플릿에서 사용하여 요청 또는 호출 결과와 관련된 오류를 감지할 수 있습니다.

** `$util.error(String, String)` **  
사용자 지정 오류를 발생시킵니다. 요청 또는 응답 매핑 템플릿에서 사용하여 요청 또는 호출 결과와 관련된 오류를 감지할 수 있습니다. `errorType`도 지정할 수 있습니다.

** `$util.error(String, String, Object)` **  
사용자 지정 오류를 발생시킵니다. 요청 또는 응답 매핑 템플릿에서 사용하여 요청 또는 호출 결과와 관련된 오류를 감지할 수 있습니다. `errorType` 및 `data` 필드를 지정할 수도 있습니다. GraphQL 응답에서 `data` 값은 `error` 내 해당 `errors` 블록에 추가됩니다.  
참고: `data`는 쿼리 선택 세트를 기반으로 필터링됩니다.

** `$util.error(String, String, Object, Object)` **  
사용자 지정 오류를 발생시킵니다. 이 필드는 요청 또는 응답 매핑 템플릿에서 템플릿이 요청 또는 호출 결과와 관련된 오류를 감지하는 경우 사용할 수 있습니다. 또한 `errorType`, `data` 및 `errorInfo` 필드를 지정할 수 있습니다. GraphQL 응답에서 `data` 값은 `error` 내 해당 `errors` 블록에 추가됩니다.  
참고: `data`는 쿼리 선택 세트를 기반으로 필터링됩니다. GraphQL 응답에서 `errorInfo` 값은 `error` 내 해당 `errors` 블록에 추가됩니다.  
`errorInfo`는 쿼리 선택 세트를 기반으로 필터링되지 **않습니다**.

** `$util.appendError(String)` **  
사용자 지정 오류를 추가합니다. 이 필드는 요청 또는 응답 매핑 템플릿에서 템플릿이 요청 또는 호출 결과와 관련된 오류를 감지하는 경우 사용할 수 있습니다. `$util.error(String)`와 달리 템플릿 평가가 중단되지 않기 때문에 데이터를 호출자에게 반환할 수 있습니다.

** `$util.appendError(String, String)` **  
사용자 지정 오류를 추가합니다. 이 필드는 요청 또는 응답 매핑 템플릿에서 템플릿이 요청 또는 호출 결과와 관련된 오류를 감지하는 경우 사용할 수 있습니다. 또한 `errorType`을 지정할 수 있습니다. `$util.error(String, String)`와 달리 템플릿 평가가 중단되지 않기 때문에 데이터를 호출자에게 반환할 수 있습니다.

** `$util.appendError(String, String, Object)` **  
사용자 지정 오류를 추가합니다. 이 필드는 요청 또는 응답 매핑 템플릿에서 템플릿이 요청 또는 호출 결과와 관련된 오류를 감지하는 경우 사용할 수 있습니다. 또한 `errorType`과 `data` 필드를 지정할 수 있습니다. `$util.error(String, String, Object)`와 달리 템플릿 평가가 중단되지 않기 때문에 데이터를 호출자에게 반환할 수 있습니다. GraphQL 응답에서 `data` 값은 `error` 내 해당 `errors` 블록에 추가됩니다.  
참고: `data`는 쿼리 선택 세트를 기반으로 필터링됩니다.

** `$util.appendError(String, String, Object, Object)` **  
사용자 지정 오류를 추가합니다. 이 필드는 요청 또는 응답 매핑 템플릿에서 템플릿이 요청 또는 호출 결과와 관련된 오류를 감지하는 경우 사용할 수 있습니다. 또한 `errorType`, `data` 및 `errorInfo` 필드를 지정할 수 있습니다. `$util.error(String, String, Object, Object)`와 달리 템플릿 평가가 중단되지 않기 때문에 데이터를 호출자에게 반환할 수 있습니다. GraphQL 응답에서 `data` 값은 `error` 내 해당 `errors` 블록에 추가됩니다.  
참고: `data`는 쿼리 선택 세트를 기반으로 필터링됩니다. GraphQL 응답에서 `errorInfo` 값은 `error` 내 해당 `errors` 블록에 추가됩니다.  
`errorInfo`는 쿼리 선택 세트를 기반으로 필터링되지 **않습니다**.

## 조건 검증 유틸리티
<a name="utility-helpers-in-condition"></a>

### 조건 검증 유틸리티 목록
<a name="utility-helpers-in-condition-list"></a>

** `$util.validate(Boolean, String) : void` **  
조건이 false이면 지정된 메시지와 함께 CustomTemplateException이 발생합니다.

** `$util.validate(Boolean, String, String) : void` **  
조건이 false이면 지정된 메시지 및 오류 유형과 함께 CustomTemplateException이 발생합니다.

** `$util.validate(Boolean, String, String, Object) : void` **  
조건이 false이면 지정된 메시지 및 오류 유형 그리고 응답에서 반환할 데이터와 함께 CustomTemplateException이 발생합니다.

## Null 동작 유틸리티
<a name="utility-helpers-in-null-behavior"></a>

### Null 동작 유틸리티 목록
<a name="utility-helpers-in-null-behavior-list"></a>

** `$util.isNull(Object) : Boolean` **  
제공되는 객체가 null이면 true를 반환합니다.

** `$util.isNullOrEmpty(String) : Boolean` **  
제공되는 데이터가 null이거나 빈 문자열이면 true를 반환합니다. 그렇지 않을 경우 false를 반환합니다.

** `$util.isNullOrBlank(String) : Boolean` **  
제공되는 데이터가 null이거나 빈 문자열이면 true를 반환합니다. 그렇지 않을 경우 false를 반환합니다.

** `$util.defaultIfNull(Object, Object) : Object` **  
첫 번째 객체가 null이 아니면 첫 번째 객체를 반환합니다. 그렇지 않은 경우 두 번째 객체를 ‘기본 객체’로 반환합니다.

** `$util.defaultIfNullOrEmpty(String, String) : String` **  
첫 번째 문자열이 null이 아니거나 비어 있지 않으면 첫 번째 문자열을 반환합니다. 그렇지 않은 경우 두 번째 문자열을 ‘기본 문자열’로 반환합니다.

** `$util.defaultIfNullOrBlank(String, String) : String` **  
첫 번째 문자열이 null이 아니거나 공백이 아니면 첫 번째 문자열을 반환합니다. 그렇지 않은 경우 두 번째 문자열을 ‘기본 문자열’로 반환합니다.

## 패턴 매칭 유틸리티
<a name="utility-helpers-in-pattern-matching"></a>

### 유형 및 패턴 매칭 유틸리티 목록
<a name="utility-helpers-in-type-pattern-matching-list"></a>

** `$util.typeOf(Object) : String` **  
객체 유형을 설명하는 문자열을 반환합니다. 지원되는 유형 식별은 ‘Null’, ‘숫자’, ‘문자열’, ‘맵’, ‘목록’, ‘부울’입니다. 유형을 식별할 수 없는 경우 반환 유형은 ‘객체’입니다.

** `$util.matches(String, String) : Boolean` **  
첫 번째 인수의 지정된 패턴이 두 번째 인수에서 제공되는 데이터와 일치하는 경우 true를 반환합니다. 패턴은 `$util.matches("a*b", "aaaaab")` 등과 같은 정규식이어야 합니다. 이 기능은 [Pattern](https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html)을 기반으로 하며, 여기서 자세한 설명을 참조할 수 있습니다.

** `$util.authType() : String` **  
요청에 사용되는 다중 인증 유형을 설명하는 문자열을 반환하고 'IAM 권한 부여', '사용자 풀 권한 부여', 'Open ID Connect 권한 부여' 또는 'API 키 인증'을 반환합니다.

## 객체 검증 유틸리티
<a name="utility-helpers-in-object-validation"></a>

### 객체 검증 유틸리티 목록
<a name="utility-helpers-in-object-validation-list"></a>

** `$util.isString(Object) : Boolean` **  
객체가 문자열인 경우 true를 반환합니다.

** `$util.isNumber(Object) : Boolean` **  
객체가 숫자인 경우 true를 반환합니다.

** `$util.isBoolean(Object) : Boolean` **  
객체가 부울인 경우 true를 반환합니다.

** `$util.isList(Object) : Boolean` **  
객체가 목록인 경우 true를 반환합니다.

** `$util.isMap(Object) : Boolean` **  
객체가 맵인 경우 true를 반환합니다.

## CloudWatch 로깅 유틸리티
<a name="utility-helpers-in-logging"></a>

### CloudWatch 로깅 유틸리티 목록
<a name="utility-helpers-in-cloudwatch-logs"></a>

**`$util.log.info(Object) : Void`**  
API에서 로그 수준 `ALL`, `INFO` 또는 `DEBUG`로 요청 수준 및 필드 수준 CloudWatch 로깅이 활성화된 경우 제공된 객체의 문자열 표현을 요청된 로그 스트림에 기록합니다.

**`$util.log.info(String, Object...) : Void`**  
API에서 로그 수준 `ALL`로 요청 수준 및 필드 수준 CloudWatch 로깅이 활성화된 경우 제공된 객체의 문자열 표현을 요청된 로그 스트림에 기록합니다. 이 유틸리티는 첫 번째 입력 형식 문자열에서 '\$1\$1'로 표시된 모든 변수를 제공된 객체의 문자열 표현으로 순서대로 바꿉니다.

**`$util.log.debug(Object) : Void`**  
API에서 로그 수준 `ALL` 또는 `DEBUG`로 요청 수준 및 필드 수준 CloudWatch 로깅이 활성화된 경우 제공된 객체의 문자열 표현을 요청된 로그 스트림에 기록합니다.

**`$util.log.debug(String, Object...) : Void`**  
API에서 로그 수준 `DEBUG` 또는 로그 수준 `ALL`로 필드 수준 CloudWatch 로깅이 활성화된 경우 제공된 객체의 문자열 표현을 요청된 로그 스트림에 기록합니다. 이 유틸리티는 첫 번째 입력 형식 문자열에서 '\$1\$1'로 표시된 모든 변수를 제공된 객체의 문자열 표현으로 순서대로 바꿉니다.

**`$util.log.error(Object) : Void`**  
API에서 로그 수준(`ALL`, `INFO`, `DEBUG` 등)으로 필드 수준 CloudWatch 로깅이 활성화된 경우 제공된 객체의 문자열 표현을 요청된 로그 스트림에 기록합니다.

**`$util.log.error(String, Object...) : Void`**  
API에서 로그 수준 `ERROR` 또는 로그 수준 `ALL`로 필드 수준 CloudWatch 로깅이 활성화된 경우 제공된 객체의 문자열 표현을 요청된 로그 스트림에 기록합니다. 이 유틸리티는 첫 번째 입력 형식 문자열에서 '\$1\$1'로 표시된 모든 변수를 제공된 객체의 문자열 표현으로 순서대로 바꿉니다.

## 반환 값 동작 유틸리티
<a name="utility-helpers-in-return-behavior"></a>

### 반환 값 동작 유틸리티 목록
<a name="utility-helpers-in-behavior-list"></a>

****`$util.qr()`** 및 `$util.quiet()` **  
반환된 값을 제한하면서 VTL 문을 실행합니다. 이는 맵에 항목 추가와 같이 임시 자리 표시자를 사용하지 않고 메서드를 실행하고자 하는 경우 유용합니다. 예제:  

```
#set ($myMap = {})
#set($discard = $myMap.put("id", "first value"))
```
Becomes:  

```
#set ($myMap = {})
$util.qr($myMap.put("id", "first value"))
```  
** `$util.escapeJavaScript(String) : String` **  
입력 문자열을 JavaScript 의 이스케이프된 문자열로 반환합니다.  
** `$util.urlEncode(String) : String` **  
입력 문자열을 `application/x-www-form-urlencoded` 인코딩 문자열로 반환합니다.  
** `$util.urlDecode(String) : String` **  
`application/x-www-form-urlencoded` 인코딩 문자열을 인코딩되지 않은 형식으로 다시 디코딩합니다.  
** `$util.base64Encode( byte[] ) : String` **  
입력을 base64 인코딩 문자열로 인코딩합니다.  
** `$util.base64Decode(String) : byte[]` **  
데이터를 base64 인코딩 문자열에서 디코딩합니다.  
** `$util.parseJson(String) : Object` **  
‘문자열화된’ JSON을 가져와서 결과의 객체 표현을 반환합니다.  
** `$util.toJson(Object) : String` **  
객체를 받아 해당 객체의 ‘문자열화된’ JSON 표현을 반환합니다.  
** `$util.autoId() : String` **  
임의로 생성된 128비트 UUID를 반환합니다.  
****`$util.autoUlid() : String`****  
무작위로 생성된 128비트 ULID(Universally Unique Lexicographically Sortable Identifier)를 반환합니다.  
****`$util.autoKsuid() : String`****  
길이가 27인 문자열로 인코딩된 무작위로 생성된 128비트 KSUID(K-Sortable Unique Identifier) base62를 반환합니다.  
** `$util.unauthorized()` **  
해석 중인 필드에 대해 `Unauthorized`를 발생시킵니다. 요청 또는 응답 매핑 템플릿에서 이를 사용하여 호출자가 필드를 확인하도록 허용할지 여부를 결정합니다.  
** `$util.error(String)` **  
사용자 지정 오류를 발생시킵니다. 요청 또는 응답 매핑 템플릿에서 사용하여 요청 또는 호출 결과와 관련된 오류를 감지할 수 있습니다.  
** `$util.error(String, String)` **  
사용자 지정 오류를 발생시킵니다. 요청 또는 응답 매핑 템플릿에서 사용하여 요청 또는 호출 결과와 관련된 오류를 감지할 수 있습니다. `errorType`도 지정할 수 있습니다.  
** `$util.error(String, String, Object)` **  
사용자 지정 오류를 발생시킵니다. 요청 또는 응답 매핑 템플릿에서 사용하여 요청 또는 호출 결과와 관련된 오류를 감지할 수 있습니다. `errorType` 및 `data` 필드를 지정할 수도 있습니다. GraphQL 응답에서 `data` 값은 `error` 내 해당 `errors` 블록에 추가됩니다. **참고**: `data`는 쿼리 선택 세트를 기반으로 필터링됩니다.  
** `$util.error(String, String, Object, Object)` **  
사용자 지정 오류를 발생시킵니다. 이 필드는 요청 또는 응답 매핑 템플릿에서 템플릿이 요청 또는 호출 결과와 관련된 오류를 감지하는 경우 사용할 수 있습니다. 또한 `errorType`, `data` 및 `errorInfo` 필드를 지정할 수 있습니다. GraphQL 응답에서 `data` 값은 `error` 내 해당 `errors` 블록에 추가됩니다. **참고**: `data`는 쿼리 선택 세트를 기반으로 필터링됩니다. GraphQL 응답에서 `errorInfo` 값은 `error` 내 해당 `errors` 블록에 추가됩니다. **참고**: `errorInfo`는 쿼리 선택 세트를 기반으로 필터링되지 **않습니다**.  
** `$util.appendError(String)` **  
사용자 지정 오류를 추가합니다. 이 필드는 요청 또는 응답 매핑 템플릿에서 템플릿이 요청 또는 호출 결과와 관련된 오류를 감지하는 경우 사용할 수 있습니다. `$util.error(String)`와 달리 템플릿 평가가 중단되지 않기 때문에 데이터를 호출자에게 반환할 수 있습니다.  
** `$util.appendError(String, String)` **  
사용자 지정 오류를 추가합니다. 이 필드는 요청 또는 응답 매핑 템플릿에서 템플릿이 요청 또는 호출 결과와 관련된 오류를 감지하는 경우 사용할 수 있습니다. 또한 `errorType`을 지정할 수 있습니다. `$util.error(String, String)`와 달리 템플릿 평가가 중단되지 않기 때문에 데이터를 호출자에게 반환할 수 있습니다.  
** `$util.appendError(String, String, Object)` **  
사용자 지정 오류를 추가합니다. 이 필드는 요청 또는 응답 매핑 템플릿에서 템플릿이 요청 또는 호출 결과와 관련된 오류를 감지하는 경우 사용할 수 있습니다. 또한 `errorType`과 `data` 필드를 지정할 수 있습니다. `$util.error(String, String, Object)`와 달리 템플릿 평가가 중단되지 않기 때문에 데이터를 호출자에게 반환할 수 있습니다. GraphQL 응답에서 `data` 값은 `error` 내 해당 `errors` 블록에 추가됩니다. **참고**: `data`는 쿼리 선택 세트를 기반으로 필터링됩니다.  
** `$util.appendError(String, String, Object, Object)` **  
사용자 지정 오류를 추가합니다. 이 필드는 요청 또는 응답 매핑 템플릿에서 템플릿이 요청 또는 호출 결과와 관련된 오류를 감지하는 경우 사용할 수 있습니다. 또한 `errorType`, `data` 및 `errorInfo` 필드를 지정할 수 있습니다. `$util.error(String, String, Object, Object)`와 달리 템플릿 평가가 중단되지 않기 때문에 데이터를 호출자에게 반환할 수 있습니다. GraphQL 응답에서 `data` 값은 `error` 내 해당 `errors` 블록에 추가됩니다. **참고**: `data`는 쿼리 선택 세트를 기반으로 필터링됩니다. GraphQL 응답에서 `errorInfo` 값은 `error` 내 해당 `errors` 블록에 추가됩니다. **참고**: `errorInfo`는 쿼리 선택 세트를 기반으로 필터링되지 **않습니다**.  
** `$util.validate(Boolean, String) : void` **  
조건이 false이면 지정된 메시지와 함께 CustomTemplateException이 발생합니다.  
** `$util.validate(Boolean, String, String) : void` **  
조건이 false이면 지정된 메시지 및 오류 유형과 함께 CustomTemplateException이 발생합니다.  
** `$util.validate(Boolean, String, String, Object) : void` **  
조건이 false이면 지정된 메시지 및 오류 유형 그리고 응답에서 반환할 데이터와 함께 CustomTemplateException이 발생합니다.  
** `$util.isNull(Object) : Boolean` **  
제공되는 객체가 null이면 true를 반환합니다.  
** `$util.isNullOrEmpty(String) : Boolean` **  
제공되는 데이터가 null이거나 빈 문자열이면 true를 반환합니다. 그렇지 않을 경우 false를 반환합니다.  
** `$util.isNullOrBlank(String) : Boolean` **  
제공되는 데이터가 null이거나 빈 문자열이면 true를 반환합니다. 그렇지 않을 경우 false를 반환합니다.  
** `$util.defaultIfNull(Object, Object) : Object` **  
첫 번째 객체가 null이 아니면 첫 번째 객체를 반환합니다. 그렇지 않은 경우 두 번째 객체를 ‘기본 객체’로 반환합니다.  
** `$util.defaultIfNullOrEmpty(String, String) : String` **  
첫 번째 문자열이 null이 아니거나 비어 있지 않으면 첫 번째 문자열을 반환합니다. 그렇지 않은 경우 두 번째 문자열을 ‘기본 문자열’로 반환합니다.  
** `$util.defaultIfNullOrBlank(String, String) : String` **  
첫 번째 문자열이 null이 아니거나 공백이 아니면 첫 번째 문자열을 반환합니다. 그렇지 않은 경우 두 번째 문자열을 ‘기본 문자열’로 반환합니다.  
** `$util.isString(Object) : Boolean` **  
객체가 문자열인 경우 true를 반환합니다.  
** `$util.isNumber(Object) : Boolean` **  
객체가 숫자인 경우 true를 반환합니다.  
** `$util.isBoolean(Object) : Boolean` **  
객체가 부울인 경우 true를 반환합니다.  
** `$util.isList(Object) : Boolean` **  
객체가 목록인 경우 true를 반환합니다.  
** `$util.isMap(Object) : Boolean` **  
객체가 맵인 경우 true를 반환합니다.  
** `$util.typeOf(Object) : String` **  
객체 유형을 설명하는 문자열을 반환합니다. 지원되는 유형 식별은 ‘Null’, ‘숫자’, ‘문자열’, ‘맵’, ‘목록’, ‘부울’입니다. 유형을 식별할 수 없는 경우 반환 유형은 ‘객체’입니다.  
** `$util.matches(String, String) : Boolean` **  
첫 번째 인수의 지정된 패턴이 두 번째 인수에서 제공되는 데이터와 일치하는 경우 true를 반환합니다. 패턴은 `$util.matches("a*b", "aaaaab")` 등과 같은 정규식이어야 합니다. 이 기능은 [Pattern](https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html)을 기반으로 하며, 여기서 자세한 설명을 참조할 수 있습니다.  
** `$util.authType() : String` **  
요청에 사용되는 다중 인증 유형을 설명하는 문자열을 반환하고 'IAM 권한 부여', '사용자 풀 권한 부여', 'Open ID Connect 권한 부여' 또는 'API 키 인증'을 반환합니다.  
****`$util.log.info(Object) : Void`****  
API에서 로그 수준 `ALL`로 요청 수준 및 필드 수준 CloudWatch 로깅이 활성화된 경우 제공된 객체의 문자열 표현을 요청된 로그 스트림에 기록합니다.  
****`$util.log.info(String, Object...) : Void`****  
API에서 로그 수준 `ALL`로 요청 수준 및 필드 수준 CloudWatch 로깅이 활성화된 경우 제공된 객체의 문자열 표현을 요청된 로그 스트림에 기록합니다. 이 유틸리티는 첫 번째 입력 형식 문자열에서 '\$1\$1'로 표시된 모든 변수를 제공된 객체의 문자열 표현으로 순서대로 바꿉니다.  
****`$util.log.error(Object) : Void`****  
API에서 로그 수준 `ERROR` 또는 로그 수준 `ALL`로 필드 수준 CloudWatch 로깅이 활성화된 경우 제공된 객체의 문자열 표현을 요청된 로그 스트림에 기록합니다.  
****`$util.log.error(String, Object...) : Void`****  
API에서 로그 수준 `ERROR` 또는 로그 수준 `ALL`로 필드 수준 CloudWatch 로깅이 활성화된 경우 제공된 객체의 문자열 표현을 요청된 로그 스트림에 기록합니다. 이 유틸리티는 첫 번째 입력 형식 문자열에서 '\$1\$1'로 표시된 모든 변수를 제공된 객체의 문자열 표현으로 순서대로 바꿉니다.

** `$util.escapeJavaScript(String) : String` **  
입력 문자열을 JavaScript 의 이스케이프된 문자열로 반환합니다.

## 해석기 권한 부여
<a name="utility-helpers-in-resolver-auth"></a>

### 해석기 권한 부여 목록
<a name="utility-helpers-in-resolver-auth-list"></a>

** `$util.unauthorized()` **  
해석 중인 필드에 대해 `Unauthorized`를 발생시킵니다. 요청 또는 응답 매핑 템플릿에서 이를 사용하여 호출자가 필드를 확인하도록 허용할지 여부를 결정합니다.

# AWS AppSync 지시문
<a name="aws-appsync-directives"></a>

**참고**  
이제 우리는 주로 APPSYNC\$1JS 런타임과 해당 문서를 지원합니다. [여기](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)에서 APPSYNC\$1JS 런타임과 해당 안내서를 사용해 보세요.

AWS AppSync는 VTL로 작성할 때 개발자 생산성을 높이기 위해 지시문을 노출합니다.

## 지시문 유틸리티
<a name="utility-helpers-in-directives"></a>

****`#return(Object)`****  
`#return(Object)`를 사용하면 모든 매핑 템플릿에서 조기에 돌아올 수 있습니다. `#return(Object)`는 가장 가까운 범위의 로직 블록에서 반환된다는 점에서 프로그래밍 언어의 *return* 키워드와 유사합니다. 해석기 매핑 템플릿 내에서 `#return(Object)`를 사용하면 해석기에서 반환함을 의미합니다. 또는 함수 매핑 템플릿의 `#return(Object)`를 사용하면 함수에서 반환하고, 파이프라인의 다음 함수 또는 해석기 응답 매핑 템플릿으로 실행합니다.

****`#return`****  
`#return` 지시문은 `#return(Object)`와 동일한 동작을 나타내지만 `null`이 대신 반환됩니다.

# \$1util.time의 시간 도우미
<a name="time-helpers-in-util-time"></a>

**참고**  
이제 우리는 주로 APPSYNC\$1JS 런타임과 해당 문서를 지원합니다. [여기](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)에서 APPSYNC\$1JS 런타임과 해당 안내서를 사용해 보세요.

`$util.time` 변수에는 타임스탬프를 생성하고, 날짜 및 시간 형식 간에 변환하고, 날짜 및 시간 문자열을 구문 분석하는 데 도움이 되는 날짜 및 시간 메서드가 포함되어 있습니다. 날짜 및 시간 형식 구문은 [DateTimeFormatter](https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html)를 기반으로 하며, 여기서 자세한 설명을 참조할 수 있습니다. 아래에서는 몇 가지 예와 사용 가능한 메서드 목록 및 설명을 제공합니다.

## 시간 유틸리티
<a name="utility-helpers-in-time"></a>

### 시간 유틸리티 목록
<a name="utility-helpers-in-time-list"></a>

** `$util.time.nowISO8601() : String` **  
UTC의 문자열 표현을 [ISO8601 형식](https://en.wikipedia.org/wiki/ISO_8601)으로 반환합니다.

** `$util.time.nowEpochSeconds() : long` **  
1970-01-01T00:00:00Z의 epoch부터 지금까지의 시간을 초로 반환합니다.

** `$util.time.nowEpochMilliSeconds() : long` **  
1970-01-01T00:00:00Z의 epoch부터 지금까지의 시간을 밀리초로 반환합니다.

** `$util.time.nowFormatted(String) : String` **  
문자열 입력 유형의 지정된 형식을 사용하여 현재 타임스탬프의 문자열을 UTC로 반환합니다.

** `$util.time.nowFormatted(String, String) : String` **  
문자열 입력 유형의 지정된 형식 및 시간대를 사용하여 시간대의 현재 타임스탬프 문자열을 반환합니다.

** `$util.time.parseFormattedToEpochMilliSeconds(String, String) : Long` **  
형식 및 시간대를 포함한 문자열로 전달된 타임스탬프를 구문 분석하고 에포크 이후 타임스탬프를 밀리초로 반환합니다.

** `$util.time.parseFormattedToEpochMilliSeconds(String, String, String) : Long` **  
형식 및 시간대와 함께 문자열로 전달된 타임스탬프를 구문 분석하고 epoch 이후 타임스탬프를 밀리초로 반환합니다.

** `$util.time.parseISO8601ToEpochMilliSeconds(String) : Long` **  
문자열로 전달된 ISO8601 타임스탬프를 구문 분석하고 epoch 이후 타임스탬프를 밀리초로 반환합니다.

** `$util.time.epochMilliSecondsToSeconds(long) : long` **  
epoch 밀리초 타임스탬프를 epoch 초 타임스탬프로 변환합니다.

** `$util.time.epochMilliSecondsToISO8601(long) : String` **  
epoch 밀리초 타임스탬프를 ISO8601 타임스탬프로 변환합니다.

** `$util.time.epochMilliSecondsToFormatted(long, String) : String` **  
long으로 전달된 epoch 밀리초 타임스탬프를 UTC의 제공된 형식에 따라 형식이 지정된 타임스탬프로 변환합니다.

** `$util.time.epochMilliSecondsToFormatted(long, String, String) : String` **  
long으로 전달된 epoch 밀리초 타임스탬프를 제공된 시간대의 제공된 형식에 따라 형식이 지정된 타임스탬프로 변환합니다.

## 독립 실행형 함수 예제
<a name="standalone-function-examples"></a>

```
$util.time.nowISO8601()                                            : 2018-02-06T19:01:35.749Z
$util.time.nowEpochSeconds()                                       : 1517943695
$util.time.nowEpochMilliSeconds()                                  : 1517943695750
$util.time.nowFormatted("yyyy-MM-dd HH:mm:ssZ")                    : 2018-02-06 19:01:35+0000
$util.time.nowFormatted("yyyy-MM-dd HH:mm:ssZ", "+08:00")          : 2018-02-07 03:01:35+0800
$util.time.nowFormatted("yyyy-MM-dd HH:mm:ssZ", "Australia/Perth") : 2018-02-07 03:01:35+0800
```

## 변환 예제
<a name="conversion-examples"></a>

```
#set( $nowEpochMillis = 1517943695758 )
$util.time.epochMilliSecondsToSeconds($nowEpochMillis)                                     : 1517943695
$util.time.epochMilliSecondsToISO8601($nowEpochMillis)                                     : 2018-02-06T19:01:35.758Z
$util.time.epochMilliSecondsToFormatted($nowEpochMillis, "yyyy-MM-dd HH:mm:ssZ")           : 2018-02-06 19:01:35+0000
$util.time.epochMilliSecondsToFormatted($nowEpochMillis, "yyyy-MM-dd HH:mm:ssZ", "+08:00") : 2018-02-07 03:01:35+0800
```

## 구문 분석 예제
<a name="parsing-examples"></a>

```
$util.time.parseISO8601ToEpochMilliSeconds("2018-02-01T17:21:05.180+08:00")                          : 1517476865180
$util.time.parseFormattedToEpochMilliSeconds("2018-02-02 01:19:22+0800", "yyyy-MM-dd HH:mm:ssZ")     : 1517505562000
$util.time.parseFormattedToEpochMilliSeconds("2018-02-02 01:19:22", "yyyy-MM-dd HH:mm:ss", "+08:00") : 1517505562000
```

## AWS AppSync 정의된 스칼라 사용
<a name="usage-with-aws-scalars"></a>

다음 형식은 `AWSDate`, `AWSDateTime` 및 `AWSTime`과 호환됩니다.

```
$util.time.nowFormatted("yyyy-MM-dd[XXX]", "-07:00:30")               : 2018-07-11-07:00
$util.time.nowFormatted("yyyy-MM-dd'T'HH:mm:ss[XXXXX]", "-07:00:30")  : 2018-07-11T15:14:15-07:00:30
```

# \$1util.list의 목록 도우미
<a name="list-helpers-in-util-list"></a>

**참고**  
이제 우리는 주로 APPSYNC\$1JS 런타임과 해당 문서를 지원합니다. [여기](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)에서 APPSYNC\$1JS 런타임과 해당 안내서를 사용해 보세요.

`$util.list`에는 사용 사례 필터링을 위해 목록에서 항목을 제거하거나 유지하는 등과 같은 일반적인 목록 작업에 유용한 메서드가 포함되어 있습니다.

## 목록 유틸리티
<a name="utility-helpers-in-list-utils"></a>

** `$util.list.copyAndRetainAll(List, List) : List` **  
첫 번째 인수에 제공된 목록의 단순 복사본을 생성하고 두 번째 인수에 지정된 항목(있는 경우)만 유지합니다. 기타 모든 항목은 이 복사본에서 제거됩니다.

** `$util.list.copyAndRemoveAll(List, List) : List` **  
첫 번째 인수에 제공된 목록의 단순 복사본을 생성하고 두 번째 인수에 지정된 항목(있는 경우)만 제거합니다. 기타 모든 항목은 이 복사본에 보유됩니다.

** `$util.list.sortList(List, Boolean, String) : List` **  
첫 번째 인수에 제공된 객체 목록을 정렬합니다. 두 번째 인수가 true인 경우 목록은 내림차순으로 정렬되고, 두 번째 인수가 false인 경우 목록은 오름차순으로 정렬됩니다. 세 번째 인수는 사용자 지정 객체 목록을 정렬하는 데 사용되는 속성의 문자열 이름입니다. 문자열, 정수, 부동 소수점 또는 배수인 경우 세 번째 인수는 임의의 문자열일 수 있습니다. 모든 객체가 같은 클래스에 속하지 않는 경우 원래 목록이 반환됩니다. 최대 1000개의 객체를 포함하는 목록만 지원됩니다. 다음은 이 유틸리티 사용 예제입니다.  

```
 INPUT:      $util.list.sortList([{"description":"youngest", "age":5},{"description":"middle", "age":45}, {"description":"oldest", "age":85}], false, "description")
 OUTPUT:     [{"description":"middle", "age":45}, {"description":"oldest", "age":85}, {"description":"youngest", "age":5}]
```

# \$1util.map의 맵 도우미
<a name="utility-helpers-in-map"></a>

**참고**  
이제 우리는 주로 APPSYNC\$1JS 런타임과 해당 문서를 지원합니다. [여기](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)에서 APPSYNC\$1JS 런타임과 해당 안내서를 사용해 보세요.

 `$util.map`에는 사용 사례 필터링을 위해 맵에서 항목을 제거하거나 유지하는 등과 같은 일반적인 맵 작업에 유용한 메서드가 포함되어 있습니다.

## 맵 유틸리티
<a name="utility-helpers-in-map-list"></a>

** `$util.map.copyAndRetainAllKeys(Map, List) : Map` **  
첫 번째 맵의 단순 복사본을 생성하고 목록에 지정된 키(있는 경우)만 유지합니다. 기타 모든 키는 이 복사본에서 제거됩니다.

** `$util.map.copyAndRemoveAllKeys(Map, List) : Map` **  
첫 번째 맵의 단순 복사본을 생성하고 목록에서 키가 지정된 항목(있는 경우)을 제거합니다. 기타 모든 키는 이 복사본에 보유됩니다.

# \$1util.dynamodb의 DynamoDB 도우미
<a name="dynamodb-helpers-in-util-dynamodb"></a>

**참고**  
이제 우리는 주로 APPSYNC\$1JS 런타임과 해당 문서를 지원합니다. [여기](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)에서 APPSYNC\$1JS 런타임과 해당 안내서를 사용해 보세요.

`$util.dynamodb`에는 Amazon DynamoDB에 데이터 쓰기 및 읽기를 더 용이하게 하는 도우미 메서드가 포함되어 있습니다(예: 자동 유형 매핑 및 형식 지정). 이러한 메서드는 기본 유형 및 목록을 적절한 DynamoDB 입력 형식(`{ "TYPE" : VALUE }` 형식의 `Map`)에 자동으로 매핑하도록 설계되어 있습니다.

예를 들어, 이전에는 DynamoDB에서 새 항목을 생성하는 요청 매핑 템플릿은 다음과 같았습니다.

```
{
    "version" : "2017-02-28",
    "operation" : "PutItem",
    "key": {
        "id" : { "S" : "$util.autoId()" }
    },
    "attributeValues" : {
         "title" : { "S" : $util.toJson($ctx.args.title) },
         "author" : { "S" : $util.toJson($ctx.args.author) },
         "version" : { "N", $util.toJson($ctx.args.version) }
    }
}
```

객체에 필드를 추가하려는 경우 스키마에서 GraphQL 쿼리를 업데이트하고 요청 매핑 템플릿도 업데이트해야 했습니다. 그러나 이제는 스키마에 추가되는 새 필드를 자동으로 선택해 올바른 형식으로 DynamoDB에 추가하도록 요청 매핑 템플릿을 재구성할 수 있습니다.

```
{
    "version" : "2017-02-28",
    "operation" : "PutItem",
    "key": {
        "id" : $util.dynamodb.toDynamoDBJson($util.autoId())
    },
    "attributeValues" : $util.dynamodb.toMapValuesJson($ctx.args)
}
```

이전 예에서는 `$util.dynamodb.toDynamoDBJson(...)` 도우미를 사용하여 생성된 ID를 자동으로 받아 문자열 속성의 DynamoDB 표현으로 변환했습니다. 그런 다음 모든 인수를 받아 DynamoDB 표현으로 변환하고 템플릿의 `attributeValues` 필드에 출력했습니다.

각 도우미에는 객체(예: `$util.dynamodb.toString(...)`)를 반환하는 버전과 객체를 JSON 문자열(예: `$util.dynamodb.toStringJson(...)`)로 반환하는 버전 두 가지가 있습니다. 이전 예에서는 데이터를 JSON 문자열로 반환하는 버전을 사용했습니다. 템플릿에 사용하기 전에 객체를 조작하려는 경우 다음과 같이 대신 객체를 반환하도록 선택할 수 있습니다.

```
{
    "version" : "2017-02-28",
    "operation" : "PutItem",
    "key": {
        "id" : $util.dynamodb.toDynamoDBJson($util.autoId())
    },

    #set( $myFoo = $util.dynamodb.toMapValues($ctx.args) )
    #set( $myFoo.version = $util.dynamodb.toNumber(1) )
    #set( $myFoo.timestamp = $util.dynamodb.toString($util.time.nowISO8601()))

    "attributeValues" : $util.toJson($myFoo)
}
```

이전 예에서는 최종적으로 `version`을 사용하여 템플릿의 `timestamp` 필드에 출력하기 전에 JSON 문자열 대신 맵으로 변환된 인수를 반환한 다음 `attributeValues` 및 `$util.toJson(...)` 필드에 추가합니다.

각 도우미의 JSON 버전은 `$util.toJson(...)`에서 JSON 이외 버전을 래핑하는 것과 동일합니다. 예를 들어 다음 문은 정확하게 동일합니다.

```
$util.toStringJson("Hello, World!")
$util.toJson($util.toString("Hello, World!"))
```

## toDynamoDB
<a name="utility-helpers-in-toDynamoDB"></a>

### toDynamoDB 유틸리티 목록
<a name="utility-helpers-in-toDynamoDB-list"></a>

** `$util.dynamodb.toDynamoDB(Object) : Map` **  
입력 객체를 적절한 DynamoDB 표현으로 변환하는 DynamoDB용 일반 객체 변환 도구입니다. 이 도구는 몇 가지 형식을 표현하는 방법에 대해 독자적인 방식을 가지고 있습니다. 예를 들어 집합(‘SS’, ‘NS’, ‘BS’)보다는 목록(‘L’)을 사용합니다. DynamoDB 속성 값을 설명하는 객체를 반환합니다.  
**문자열 예제**  

```
Input:      $util.dynamodb.toDynamoDB("foo")
Output:     { "S" : "foo" }
```
**숫자 예제**  

```
Input:      $util.dynamodb.toDynamoDB(12345)
Output:     { "N" : 12345 }
```
**부울 예제**  

```
Input:      $util.dynamodb.toDynamoDB(true)
Output:     { "BOOL" : true }
```
**록 예제**  

```
Input:      $util.dynamodb.toDynamoDB([ "foo", 123, { "bar" : "baz" } ])
Output:     {
               "L" : [
                   { "S" : "foo" },
                   { "N" : 123 },
                   {
                       "M" : {
                           "bar" : { "S" : "baz" }
                       }
                   }
               ]
           }
```
**맵 예제**  

```
Input:      $util.dynamodb.toDynamoDB({ "foo": "bar", "baz" : 1234, "beep": [ "boop"] })
Output:     {
               "M" : {
                   "foo"  : { "S" : "bar" },
                   "baz"  : { "N" : 1234 },
                   "beep" : {
                       "L" : [
                           { "S" : "boop" }
                       ]
                   }
               }
           }
```

****`$util.dynamodb.toDynamoDBJson(Object) : String`** **  
`$util.dynamodb.toDynamoDB(Object) : Map`과 동일하지만 DynamoDB 속성 값을 JSON 인코딩 문자열로 반환합니다.

## toString 유틸리티
<a name="utility-helpers-in-toString"></a>

### toString 유틸리티 목록
<a name="utility-helpers-in-toString-list"></a>

****`$util.dynamodb.toString(String) : String`** **  
입력 문자열을 DynamoDB 문자열 형식으로 변환합니다. DynamoDB 속성 값을 설명하는 객체를 반환합니다.  

```
Input:      $util.dynamodb.toString("foo")
Output:     { "S" : "foo" }
```

** `$util.dynamodb.toStringJson(String) : Map` **  
`$util.dynamodb.toString(String) : String`과 동일하지만 DynamoDB 속성 값을 JSON 인코딩 문자열로 반환합니다.

** `$util.dynamodb.toStringSet(List<String>) : Map` **  
문자열이 포함된 목록을 DynamoDB 문자열 집합 형식으로 변환합니다. DynamoDB 속성 값을 설명하는 객체를 반환합니다.  

```
Input:      $util.dynamodb.toStringSet([ "foo", "bar", "baz" ])
Output:     { "SS" : [ "foo", "bar", "baz" ] }
```

** `$util.dynamodb.toStringSetJson(List<String>) : String` **  
`$util.dynamodb.toStringSet(List<String>) : Map`과 동일하지만 DynamoDB 속성 값을 JSON 인코딩 문자열로 반환합니다.

## toNumber 유틸리티
<a name="utility-helpers-in-toNumber"></a>

### toNumber 유틸리티 목록
<a name="utility-helpers-in-toNumber-list"></a>

** `$util.dynamodb.toNumber(Number) : Map` **  
숫자를 DynamoDB 숫자 형식으로 변환합니다. DynamoDB 속성 값을 설명하는 객체를 반환합니다.  

```
Input:      $util.dynamodb.toNumber(12345)
Output:     { "N" : 12345 }
```

** `$util.dynamodb.toNumberJson(Number) : String` **  
`$util.dynamodb.toNumber(Number) : Map`과 동일하지만 DynamoDB 속성 값을 JSON 인코딩 문자열로 반환합니다.

** `$util.dynamodb.toNumberSet(List<Number>) : Map` **  
숫자 목록을 DynamoDB 숫자 집합 형식으로 변환합니다. DynamoDB 속성 값을 설명하는 객체를 반환합니다.  

```
Input:      $util.dynamodb.toNumberSet([ 1, 23, 4.56 ])
Output:     { "NS" : [ 1, 23, 4.56 ] }
```

** `$util.dynamodb.toNumberSetJson(List<Number>) : String` **  
`$util.dynamodb.toNumberSet(List<Number>) : Map`과 동일하지만 DynamoDB 속성 값을 JSON 인코딩 문자열로 반환합니다.

## toBinary 유틸리티
<a name="utility-helpers-in-toBinary"></a>

### toBinary 유틸리티 목록
<a name="utility-helpers-in-toBinary-list"></a>

** `$util.dynamodb.toBinary(String) : Map` **  
base64 문자열로 인코딩된 이진 데이터를 DynamoDB 이진 형식으로 변환합니다. DynamoDB 속성 값을 설명하는 객체를 반환합니다.  

```
Input:      $util.dynamodb.toBinary("foo")
Output:     { "B" : "foo" }
```

** `$util.dynamodb.toBinaryJson(String) : String` **  
`$util.dynamodb.toBinary(String) : Map`과 동일하지만 DynamoDB 속성 값을 JSON 인코딩 문자열로 반환합니다.

** `$util.dynamodb.toBinarySet(List<String>) : Map` **  
base64 문자열로 인코딩된 이진 데이터 목록을 DynamoDB 이진수 집합 형식으로 변환합니다. DynamoDB 속성 값을 설명하는 객체를 반환합니다.  

```
Input:      $util.dynamodb.toBinarySet([ "foo", "bar", "baz" ])
Output:     { "BS" : [ "foo", "bar", "baz" ] }
```

** `$util.dynamodb.toBinarySetJson(List<String>) : String` **  
`$util.dynamodb.toBinarySet(List<String>) : Map`과 동일하지만 DynamoDB 속성 값을 JSON 인코딩 문자열로 반환합니다.

## toBoolean 유틸리티
<a name="utility-helpers-in-toBoolean"></a>

### toBoolean 유틸리티 목록
<a name="utility-helpers-in-toBoolean-list"></a>

** `$util.dynamodb.toBoolean(Boolean) : Map` **  
부울을 적절한 DynamoDB 부울 형식으로 변환합니다. DynamoDB 속성 값을 설명하는 객체를 반환합니다.  

```
Input:      $util.dynamodb.toBoolean(true)
Output:     { "BOOL" : true }
```

** `$util.dynamodb.toBooleanJson(Boolean) : String` **  
`$util.dynamodb.toBoolean(Boolean) : Map`과 동일하지만 DynamoDB 속성 값을 JSON 인코딩 문자열로 반환합니다.

## toNull 유틸리티
<a name="utility-helpers-in-toNull"></a>

### toNull 유틸리티 목록
<a name="utility-helpers-in-toNull-list"></a>

** `$util.dynamodb.toNull() : Map` **  
null을 DynamoDB null 형식으로 반환합니다. DynamoDB 속성 값을 설명하는 객체를 반환합니다.  

```
Input:      $util.dynamodb.toNull()
Output:     { "NULL" : null }
```

** `$util.dynamodb.toNullJson() : String` **  
`$util.dynamodb.toNull() : Map`과 동일하지만 DynamoDB 속성 값을 JSON 인코딩 문자열로 반환합니다.

## toList 유틸리티
<a name="utility-helpers-in-toList"></a>

### toList 유틸리티 목록
<a name="utility-helpers-in-toList-list"></a>

****`$util.dynamodb.toList(List) : Map`** **  
객체 목록을 DynamoDB 목록 형식으로 변환합니다. 목록의 각 항목 역시 적절한 DynamoDB 형식으로 변환됩니다. 이 도구는 몇 가지 중첩 객체를 표현하는 방법에 대해 독자적인 방식을 가지고 있습니다. 예를 들어 집합(‘SS’, ‘NS’, ‘BS’)보다는 목록(‘L’)을 사용합니다. DynamoDB 속성 값을 설명하는 객체를 반환합니다.  

```
Input:      $util.dynamodb.toList([ "foo", 123, { "bar" : "baz" } ])
Output:     {
               "L" : [
                   { "S" : "foo" },
                   { "N" : 123 },
                   {
                       "M" : {
                           "bar" : { "S" : "baz" }
                       }
                   }
               ]
           }
```

** `$util.dynamodb.toListJson(List) : String` **  
`$util.dynamodb.toList(List) : Map`과 동일하지만 DynamoDB 속성 값을 JSON 인코딩 문자열로 반환합니다.

## toMap 유틸리티
<a name="utility-helpers-in-toMap"></a>

### toMap 유틸리티 목록
<a name="utility-helpers-in-toMap-list"></a>

** `$util.dynamodb.toMap(Map) : Map` **  
맵을 DynamoDB 맵 형식으로 변환합니다. 맵의 각 값 역시 적절한 DynamoDB 형식으로 변환됩니다. 이 도구는 몇 가지 중첩 객체를 표현하는 방법에 대해 독자적인 방식을 가지고 있습니다. 예를 들어 집합(‘SS’, ‘NS’, ‘BS’)보다는 목록(‘L’)을 사용합니다. DynamoDB 속성 값을 설명하는 객체를 반환합니다.  

```
Input:      $util.dynamodb.toMap({ "foo": "bar", "baz" : 1234, "beep": [ "boop"] })
Output:     {
               "M" : {
                   "foo"  : { "S" : "bar" },
                   "baz"  : { "N" : 1234 },
                   "beep" : {
                       "L" : [
                           { "S" : "boop" }
                       ]
                   }
               }
           }
```

** `$util.dynamodb.toMapJson(Map) : String` **  
`$util.dynamodb.toMap(Map) : Map`과 동일하지만 DynamoDB 속성 값을 JSON 인코딩 문자열로 반환합니다.

** `$util.dynamodb.toMapValues(Map) : Map` **  
각 값이 적절한 DynamoDB 형식으로 변환된 탭의 사본을 생성합니다. 이 도구는 몇 가지 중첩 객체를 표현하는 방법에 대해 독자적인 방식을 가지고 있습니다. 예를 들어 집합(‘SS’, ‘NS’, ‘BS’)보다는 목록(‘L’)을 사용합니다.  

```
Input:      $util.dynamodb.toMapValues({ "foo": "bar", "baz" : 1234, "beep": [ "boop"] })
Output:     {
               "foo"  : { "S" : "bar" },
               "baz"  : { "N" : 1234 },
               "beep" : {
                   "L" : [
                       { "S" : "boop" }
                   ]
               }
           }
```
이는 전체 속성 값 자체가 아니라 DynamoDB 속성 값의 내용만 반환하기 때문에 `$util.dynamodb.toMap(Map) : Map`과 약간 다릅니다. 예를 들어 다음 문은 정확하게 동일합니다.  

```
$util.dynamodb.toMapValues($map)
$util.dynamodb.toMap($map).get("M")
```

** `$util.dynamodb.toMapValuesJson(Map) : String` **  
`$util.dynamodb.toMapValues(Map) : Map`과 동일하지만 DynamoDB 속성 값을 JSON 인코딩 문자열로 반환합니다.

## S3Object 유틸리티
<a name="utility-helpers-in-S3Object"></a>

### S3Object 유틸리티 목록
<a name="utility-helpers-in-S3Object-list"></a>

** `$util.dynamodb.toS3Object(String key, String bucket, String region) : Map` **  
키, 버킷 및 리전을 DynamoDB S3 객체 표현으로 변환합니다. DynamoDB 속성 값을 설명하는 객체를 반환합니다.  

```
Input:      $util.dynamodb.toS3Object("foo", "bar", region = "baz")
Output:     { "S" : "{ \"s3\" : { \"key\" : \"foo", \"bucket\" : \"bar", \"region\" : \"baz" } }" }
```

** `$util.dynamodb.toS3ObjectJson(String key, String bucket, String region) : String` **  
`$util.dynamodb.toS3Object(String key, String bucket, String region) : Map`과 동일하지만 DynamoDB 속성 값을 JSON 인코딩 문자열로 반환합니다.

** `$util.dynamodb.toS3Object(String key, String bucket, String region, String version) : Map` **  
키, 버킷, 리전 및 선택적 버전을 DynamoDB S3 객체 표현으로 변환합니다. DynamoDB 속성 값을 설명하는 객체를 반환합니다.  

```
Input:      $util.dynamodb.toS3Object("foo", "bar", "baz", "beep")
Output:     { "S" : "{ \"s3\" : { \"key\" : \"foo\", \"bucket\" : \"bar\", \"region\" : \"baz\", \"version\" = \"beep\" } }" }
```

** `$util.dynamodb.toS3ObjectJson(String key, String bucket, String region, String version) : String` **  
`$util.dynamodb.toS3Object(String key, String bucket, String region, String version) : Map`과 동일하지만 DynamoDB 속성 값을 JSON 인코딩 문자열로 반환합니다.

** `$util.dynamodb.fromS3ObjectJson(String) : Map` **  
DynamoDB S3 객체의 문자열 값을 수락하고 키, 버킷, 리전 및 선택적 버전을 포함하는 맵을 반환합니다.  

```
Input:      $util.dynamodb.fromS3ObjectJson({ "S" : "{ \"s3\" : { \"key\" : \"foo\", \"bucket\" : \"bar\", \"region\" : \"baz\", \"version\" = \"beep\" } }" })
Output:     { "key" : "foo", "bucket" : "bar", "region" : "baz", "version" : "beep" }
```

# \$1util.rds의 Amazon RDS 도우미
<a name="rds-helpers-in-util-rds"></a>

**참고**  
이제 우리는 주로 APPSYNC\$1JS 런타임과 해당 문서를 지원합니다. [여기](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)에서 APPSYNC\$1JS 런타임과 해당 안내서를 사용해 보세요.

`$util.rds`에는 결과 출력에서 불필요한 데이터를 제거하여 Amazon RDS 작업의 형식을 지정하는 도우미 메서드가 포함되어 있습니다.

## \$1util.rds 유틸리티 목록
<a name="rds-helpers-in-util-rds-list"></a>

****`$util.rds.toJsonString(String serializedSQLResult): String`****  
문자열화된 원시 Amazon Relational Database Service(RDS) 데이터 API 작업 결과 형식을 보다 간결한 문자열로 변환하여 `String`을 반환합니다. 반환 문자열은 결과 집합의 SQL 레코드의 직렬화된 목록입니다. 모든 레코드는 키-값 페어 모음으로 표시됩니다. 키는 열 이름에 해당합니다.  
입력의 해당 명령문이 변형을 수행하는 SQL 쿼리(예: INSERT, UPDATE, DELETE)인 경우 빈 목록이 반환됩니다. 예를 들어, 쿼리 `select * from Books limit 2`는 Amazon RDS 데이터 작업의 원시 결과를 제공합니다.  

```
{
    "sqlStatementResults": [
        {
            "numberOfRecordsUpdated": 0,
            "records": [
                [
                    {
                        "stringValue": "Mark Twain"
                    },
                    {
                        "stringValue": "Adventures of Huckleberry Finn"
                    },
                    {
                        "stringValue": "978-1948132817"
                    }
                ],
                [
                    {
                        "stringValue": "Jack London"
                    },
                    {
                        "stringValue": "The Call of the Wild"
                    },
                    {
                        "stringValue": "978-1948132275"
                    }
                  ]
            ],
            "columnMetadata": [
                {
                    "isSigned": false,
                    "isCurrency": false,
                    "label": "author",
                    "precision": 200,
                    "typeName": "VARCHAR",
                    "scale": 0,
                    "isAutoIncrement": false,
                    "isCaseSensitive": false,
                    "schemaName": "",
                    "tableName": "Books",
                    "type": 12,
                    "nullable": 0,
                    "arrayBaseColumnType": 0,
                    "name": "author"
                },
                {
                    "isSigned": false,
                    "isCurrency": false,
                    "label": "title",
                    "precision": 200,
                    "typeName": "VARCHAR",
                    "scale": 0,
                    "isAutoIncrement": false,
                    "isCaseSensitive": false,
                    "schemaName": "",
                    "tableName": "Books",
                    "type": 12,
                    "nullable": 0,
                    "arrayBaseColumnType": 0,
                    "name": "title"
                },
                {
                    "isSigned": false,
                    "isCurrency": false,
                    "label": "ISBN-13",
                    "precision": 15,
                    "typeName": "VARCHAR",
                    "scale": 0,
                    "isAutoIncrement": false,
                    "isCaseSensitive": false,
                    "schemaName": "",
                    "tableName": "Books",
                    "type": 12,
                    "nullable": 0,
                    "arrayBaseColumnType": 0,
                    "name": "ISBN-13"
                }
            ]
        }
    ]
}
```
`util.rds.toJsonString`은 다음과 같습니다.  

```
[
  {
    "author": "Mark Twain",
    "title": "Adventures of Huckleberry Finn",
    "ISBN-13": "978-1948132817"
  },
  {
    "author": "Jack London",
    "title": "The Call of the Wild",
    "ISBN-13": "978-1948132275"
  },
]
```

****`$util.rds.toJsonObject(String serializedSQLResult): Object`****  
이는 `util.rds.toJsonString`과 같지만 결과는 JSON `Object`입니다.

# \$1util.http의 HTTP 도우미
<a name="http-helpers-in-utils-http"></a>

**참고**  
이제 우리는 주로 APPSYNC\$1JS 런타임과 해당 문서를 지원합니다. [여기](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)에서 APPSYNC\$1JS 런타임과 해당 안내서를 사용해 보세요.

이 `$util.http` 유틸리티는 HTTP 요청 파라미터를 관리하고 응답 헤더를 추가하는 데 사용할 수 있는 도우미 메서드를 제공합니다.

## \$1util.http 유틸리티 목록
<a name="http-helpers-in-utils-http-list"></a>

** `$util.http.copyHeaders(Map) : Map` **  
다음과 같은 제한된 HTTP 헤더를 제외하고 맵에서 헤더를 복사합니다.  
+ transfer-encoding
+ connection
+ host
+ expect
+ keep-alive
+ upgrade
+ proxy-authenticate
+ proxy-authorization
+ te
+ content-length
이 유틸리티를 사용하여 요청 헤더를 다운스트림 HTTP 엔드포인트로 전달할 수 있습니다.  

```
{
    ...
    "params": {
        ...
        "headers": $util.http.copyHeaders($ctx.request.headers),
        ...
    },
    ...
}
```

**\$1util.http.addResponseHeader(문자열, 객체)**  
응답의 이름(`String`) 및 값(`Object`)이 포함된 단일 사용자 지정 헤더를 추가합니다. 다음과 같은 제한이 적용됩니다.  
+ `copyHeaders(Map)`의 제한된 헤더 목록 외에도 헤더 이름은 다음 중 하나와 일치할 수 없습니다.
  + Access-Control-Allow-Credentials
  + Access-Control-Allow-Origin
  + Access-Control-Expose-Headers
  + Access-Control-Max-Age
  + Access-Control-Allow-Methods
  + Access-Control-Allow-Headers
  + Vary
  + Content-Type
+ 헤더 이름은 `x-amzn-` 또는 `x-amz-` 같은 제한된 접두사로 시작할 수 없습니다.
+ 사용자 지정 응답 헤더의 크기는 4KB를 초과할 수 없습니다. 여기에는 헤더 이름과 값이 포함됩니다.
+ GraphQL 작업당 각 응답 헤더를 한 번씩 정의해야 합니다. 하지만 이름이 같은 사용자 지정 헤더를 여러 번 정의하면 응답에 가장 최근의 정의가 나타납니다. 이름 지정과 상관없이 모든 헤더는 헤더 크기 제한에 포함됩니다.
+ 이름 `(String)` 또는 null 값 `(Object)`가 비어 있거나 제한된 헤더는 무시되고, 작업 `errors` 출력에 추가되는 `ResponseHeaderError` 오류가 발생합니다.

```
export function request(ctx) {
  util.http.addResponseHeader('itemsCount', 7)
  util.http.addResponseHeader('render', ctx.args.render)
  return {}
}
```

****`$util.http.addResponseHeaders(Map)`****  
지정된 이름 맵 `(String)` 및 값 `(Object)`의 응답에 여러 응답 헤더를 추가합니다. `addResponseHeader(String, Object)` 메서드에 나열된 것과 동일한 제한 사항이 이 메서드에도 적용됩니다.  

```
export function request(ctx) {
  const headers = {
    headerInt: 12,
    headerString: 'stringValue',
    headerObject: {
      field1: 7,
      field2: 'string'
    }
  }
  util.http.addResponseHeaders(headers)
  return {}
}
```

# \$1util.xml의 XML 도우미
<a name="xml-helpers-in-utils-xml"></a>

**참고**  
이제 우리는 주로 APPSYNC\$1JS 런타임과 해당 문서를 지원합니다. [여기](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)에서 APPSYNC\$1JS 런타임과 해당 안내서를 사용해 보세요.

`$util.xml`에는 XML 응답을 JSON 또는 사전으로 쉽게 변환할 수 있도록 하는 도우미 메서드가 포함되어 있습니다.

## \$1util.xml 유틸리티 목록
<a name="xml-helpers-in-utils-xml-list"></a>

****`$util.xml.toMap(String) : Map`****  
XML 문자열을 사전으로 변환합니다.  

```
Input:

<?xml version="1.0" encoding="UTF-8"?>
<posts>
<post>
  <id>1</id>
  <title>Getting started with GraphQL</title>
</post>
</posts>

Output (JSON representation):

{
  "posts":{
    "post":{
      "id":1,
      "title":"Getting started with GraphQL"
    }
  }
}


Input:

<?xml version="1.0" encoding="UTF-8"?>
<posts>
<post>
  <id>1</id>
  <title>Getting started with GraphQL</title>
</post>
<post>
  <id>2</id>
  <title>Getting started with AWS AppSync</title>
</post>
</posts>

Output (JSON representation):

{
  "posts":{
    "post":[
        {
          "id":1,
          "title":"Getting started with GraphQL"
        },
        {
          "id":2,
          "title":"Getting started with AWS AppSync"
        }
    ]
  }
}
```

****`$util.xml.toJsonString(String) : String`****  
XML 문자열을 JSON 문자열로 변환합니다. 출력이 문자열인 것을 제외하면 *toMap*과 비슷합니다. 이는 HTTP 객체에서 JSON으로 XML 응답을 직접 변환하고 반환하고자 하는 경우 유용합니다.

****`$util.xml.toJsonString(String, Boolean) : String`****  
XML 문자열을 선택 사항인 부울 파라미터가 포함된 JSON 문자열로 변환하여 JSON으로 인코딩하고자 하는지 판단합니다.

# \$1util.transform의 변환 도우미
<a name="transformation-helpers-in-utils-transform"></a>

**참고**  
이제 우리는 주로 APPSYNC\$1JS 런타임과 해당 문서를 지원합니다. [여기](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)에서 APPSYNC\$1JS 런타임과 해당 안내서를 사용해 보세요.

`$util.transform`에는 Amazon DynamoDB 필터 작업과 같은 데이터 소스에 대해 복잡한 작업을 더 쉽게 수행할 수 있게 해주는 도우미 메서드가 포함되어 있습니다.

## 변환 도우미
<a name="transformation-helpers-conversions"></a>

### 변환 도우미 유틸리티 목록
<a name="transformation-helpers-in-utils-transform-list"></a>

****`$util.transform.toDynamoDBFilterExpression(Map) : Map`****  
입력 문자열을 DynamoDB에 사용할 필터 표현식으로 변환합니다.  

```
Input:

$util.transform.toDynamoDBFilterExpression({
    "title":{
      "contains":"Hello World"
    }
  })

Output:

{
    "expression" : "contains(#title, :title_contains)"
    "expressionNames" : {
        "#title" : "title",
    },
    "expressionValues" : {
        ":title_contains" : { "S" : "Hello World" }
    },
}
```

****`$util.transform.toElasticsearchQueryDSL(Map) : Map`****  
주어진 입력을 이와 동등한 OpenSearch 쿼리 DSL 표현식으로 변환하여 JSON 문자열로 반환합니다.  

```
Input:

$util.transform.toElasticsearchQueryDSL({
    "upvotes":{
        "ne":15,
        "range":[
            10,
            20
        ]
    },
    "title":{
        "eq":"hihihi",
        "wildcard":"h*i"
    }
  })

Output:
{
    "bool":{
      "must":[
          {
            "bool":{
              "must":[
                  {
                    "bool":{
                      "must_not":{
                        "term":{
                          "upvotes":15
                        }
                      }
                    }
                  },
                  {
                    "range":{
                      "upvotes":{
                        "gte":10,
                        "lte":20
                      }
                    }
                  }
              ]
            }
          },
          {
            "bool":{
              "must":[
                  {
                    "term":{
                      "title":"hihihi"
                    }
                  },
                  {
                  "wildcard":{
                      "title":"h*i"
                    }
                  }
              ]
            }
          }
      ]
    }
}
```
기본 연산자는 AND로 가정합니다.

## 변환 도우미 구독 필터
<a name="transformation-helpers-conversions-subscription-filters"></a>

### 변환 도우미 구독 필터 유틸리티 목록
<a name="transformation-helpers-in-utils-transform-list"></a>

****`$util.transform.toSubscriptionFilter(Map) : Map`****  
`Map` 입력 객체를 `SubscriptionFilter` 표현식 객체로 변환합니다. `$util.transform.toSubscriptionFilter` 메서드는 `$extensions.setSubscriptionFilter()` 확장에 대한 입력으로 사용됩니다. 자세한 내용은 [확장](https://docs.aws.amazon.com/appsync/latest/devguide/extensions)을 참조하세요.

****`$util.transform.toSubscriptionFilter(Map, List) : Map`****  
`Map` 입력 객체를 `SubscriptionFilter` 표현식 객체로 변환합니다. `$util.transform.toSubscriptionFilter` 메서드는 `$extensions.setSubscriptionFilter()` 확장에 대한 입력으로 사용됩니다. 자세한 내용은 [확장](https://docs.aws.amazon.com/appsync/latest/devguide/extensions)을 참조하세요.  
첫 번째 인수는 `SubscriptionFilter` 표현식 객체로 변환되는 `Map` 입력 객체입니다. 두 번째 인수는 `SubscriptionFilter` 표현식 객체를 구성하는 동안 첫 번째 `Map` 입력 객체에서 무시되는 필드 이름의 `List`입니다.

****`$util.transform.toSubscriptionFilter(Map, List, Map) : Map`****  
`Map` 입력 객체를 `SubscriptionFilter` 표현식 객체로 변환합니다. `$util.transform.toSubscriptionFilter` 메서드는 `$extensions.setSubscriptionFilter()` 확장에 대한 입력으로 사용됩니다. 자세한 내용은 [확장](https://docs.aws.amazon.com/appsync/latest/devguide/extensions)을 참조하세요.  
첫 번째 인수는 `SubscriptionFilter` 표현식 객체로 변환되는 `Map` 입력 객체, 두 번째 인수는 첫 번째 `Map` 입력 객체에서 무시될 필드 이름의 `List`, 세 번째 인수는 `SubscriptionFilter` 표현식 객체를 구성하는 동안 포함되는 엄격한 규칙의 `Map` 입력 객체입니다. 이러한 엄격한 규칙이 `SubscriptionFilter` 표현식 객체에 포함되므로 최소한 하나의 규칙이 충족되어 구독 필터를 통과할 수 있습니다.

## 구독 필터 인수
<a name="subscription-filter-arguments"></a>

다음 표에서는 다음 유틸리티의 인수를 정의하는 방법을 설명합니다.
+ `$util.transform.toSubscriptionFilter(Map) : Map`
+ `$util.transform.toSubscriptionFilter(Map, List) : Map`
+ `$util.transform.toSubscriptionFilter(Map, List, Map) : Map`

------
#### [ Argument 1: Map ]

인수 1은 다음과 같은 키 값을 가진 `Map` 객체입니다.
+ 필드 이름
+ ‘and’
+ ‘or’

필드 이름을 키로 사용하는 경우 해당 필드 항목의 조건은 `"operator" : "value"` 형식입니다.

다음 예에서는 `Map`에 항목을 추가하는 방법을 보여줍니다.

```
"field_name" : {
                    "operator1" : value             
               }

## We can have multiple conditions for the same field_name: 

"field_name" : {
                    "operator1" : value             
                    "operator2" : value
                    .
                    .
                    .                  
               }
```

필드에 두 개 이상의 조건이 있는 경우 이러한 모든 조건은 OR 연산을 사용하는 것으로 간주됩니다.

입력 `Map`에 ‘and’와 ‘or’를 키로 사용할 수도 있습니다. 즉, 이들 항목 내의 모든 항목은 키에 따라 AND 또는 OR 논리를 사용하여 결합되어야 합니다. 키 값 ‘and’와 ‘or’에는 일련의 조건이 필요합니다.

```
"and" : [
            
            {
                "field_name1" : {
                    "operator1" : value             
                }
             },
             
             {
                "field_name2" : {
                    "operator1" : value             
                }
             },
             .
             .
        ].
```

참고로 ‘and’와 ‘or’는 중첩되지 않습니다. 즉, 다른 ‘and’/‘or’ 블록 내에 ‘and’/‘or’를 중첩할 수 있습니다. 하지만 단순한 필드에서는 작동하지 않습니다.

```
"and" : [
            
            {
                "field_name1" : {
                    "operator" : value             
                }
             },
             
             {
                "or" : [
                            {
                                "field_name2" : {
                                    "operator" : value             
                                }
                            },
                            
                            {
                                "field_name3" : {
                                    "operator" : value             
                                }
                            }
              
                        ].
```

다음 예제에서는 `$util.transform.toSubscriptionFilter(Map) : Map`를 사용하여 인수 1을 입력하는 방법을 보여줍니다.**

**입력**

인수 1: 맵:

```
{
  "percentageUp": {
    "lte": 50,
    "gte": 20
  },
  "and": [
    {
      "title": {
        "ne": "Book1"
      }
    },
    {
      "downvotes": {
        "gt": 2000
      }
    }
  ],
  "or": [
    {
      "author": {
        "eq": "Admin"
      }
    },
    {
      "isPublished": {
        "eq": false
      }
    }
  ]
}
```

**출력**

결과는 `Map` 객체입니다.

```
{
  "filterGroup": [
    {
      "filters": [
        {
          "fieldName": "percentageUp",
          "operator": "lte",
          "value": 50
        },
        {
          "fieldName": "title",
          "operator": "ne",
          "value": "Book1"
        },
        {
          "fieldName": "downvotes",
          "operator": "gt",
          "value": 2000
        },
        {
          "fieldName": "author",
          "operator": "eq",
          "value": "Admin"
        }
      ]
    },
    {
      "filters": [
        {
          "fieldName": "percentageUp",
          "operator": "lte",
          "value": 50
        },
        {
          "fieldName": "title",
          "operator": "ne",
          "value": "Book1"
        },
        {
          "fieldName": "downvotes",
          "operator": "gt",
          "value": 2000
        },
        {
          "fieldName": "isPublished",
          "operator": "eq",
          "value": false
        }
      ]
    },
    {
      "filters": [
        {
          "fieldName": "percentageUp",
          "operator": "gte",
          "value": 20
        },
        {
          "fieldName": "title",
          "operator": "ne",
          "value": "Book1"
        },
        {
          "fieldName": "downvotes",
          "operator": "gt",
          "value": 2000
        },
        {
          "fieldName": "author",
          "operator": "eq",
          "value": "Admin"
        }
      ]
    },
    {
      "filters": [
        {
          "fieldName": "percentageUp",
          "operator": "gte",
          "value": 20
        },
        {
          "fieldName": "title",
          "operator": "ne",
          "value": "Book1"
        },
        {
          "fieldName": "downvotes",
          "operator": "gt",
          "value": 2000
        },
        {
          "fieldName": "isPublished",
          "operator": "eq",
          "value": false
        }
      ]
    }
  ]
}
```

------
#### [ Argument 2: List ]

인수 2에는 `SubscriptionFilter` 표현식 객체를 생성하는 동안 입력 `Map`(인수 1)에서 고려하면 안 되는 필드 이름의 `List`가 포함되어 있습니다. `List`도 비어 있을 수 있습니다.

다음 예제에서는 `$util.transform.toSubscriptionFilter(Map, List) : Map`을 사용하여 인수 1 및 인수 2를 입력하는 방법을 보여줍니다.

**입력**

인수 1: 맵:

```
{

  "percentageUp": {
    "lte": 50,
    "gte": 20
  },
  "and": [
    {
      "title": {
        "ne": "Book1"
      }
    },
    {
      "downvotes": {
        "gt": 20
      }
    }
  ],
  "or": [
    {
      "author": {
        "eq": "Admin"
      }
    },
    {
      "isPublished": {
        "eq": false
      }
    }
  ]
}
```

인수 2: 목록:

```
["percentageUp", "author"]
```

**출력**

결과는 `Map` 객체입니다.

```
{
  "filterGroup": [
    {
      "filters": [
        {
          "fieldName": "title",
          "operator": "ne",
          "value": "Book1"
        },
        {
          "fieldName": "downvotes",
          "operator": "gt",
          "value": 20
        },
        {
          "fieldName": "isPublished",
          "operator": "eq",
          "value": false
        }
      ]
    }
  ]
}
```

------
#### [ Argument 3: Map ]

인수 3은 필드 이름을 키 값으로 갖는 `Map` 객체입니다(‘and’ 또는 ‘or’를 가질 수 없음). 필드 이름을 키로 사용하는 경우 해당 필드의 조건은 `"operator" : "value"` 형식의 항목입니다. 인수 1과 달리 인수 3은 동일한 키에 여러 조건을 포함할 수 없습니다. 또한 인수 3에는 ‘and’ 또는 ‘or’ 절이 없으므로 중첩도 필요하지 않습니다.

인수 3은 엄격한 규칙 목록을 나타내며, 이러한 규칙 목록은 필터를 통과하기 위해 이러한 조건 **중 하나 이상이** 충족되도록 `SubscriptionFilter` 표현식 객체에 추가됩니다.

```
{
  "fieldname1": {
    "operator": value
  },
  "fieldname2": {
    "operator": value
  }
}
.
.
.
```

다음 예제에서는 `$util.transform.toSubscriptionFilter(Map, List, Map) : Map`을 사용하여 *인수 1*, *인수 2* 및 *인수 3*을 입력하는 방법을 보여줍니다.

**입력**

인수 1: 맵:

```
{
  "percentageUp": {
    "lte": 50,
    "gte": 20
  },
  "and": [
    {
      "title": {
        "ne": "Book1"
      }
    },
    {
      "downvotes": {
        "lt": 20
      }
    }
  ],
  "or": [
    {
      "author": {
        "eq": "Admin"
      }
    },
    {
      "isPublished": {
        "eq": false
      }
    }
  ]
}
```

인수 2: 목록:

```
["percentageUp", "author"]
```

인수 3: 맵:

```
{
  "upvotes": {
    "gte": 250
  },
  "author": {
    "eq": "Person1"
  }
}
```

**출력**

결과는 `Map` 객체입니다.

```
{
  "filterGroup": [
    {
      "filters": [
        {
          "fieldName": "title",
          "operator": "ne",
          "value": "Book1"
        },
        {
          "fieldName": "downvotes",
          "operator": "gt",
          "value": 20
        },
        {
          "fieldName": "isPublished",
          "operator": "eq",
          "value": false
        },
        {
          "fieldName": "upvotes",
          "operator": "gte",
          "value": 250
        }
      ]
    },
    {
      "filters": [
        {
          "fieldName": "title",
          "operator": "ne",
          "value": "Book1"
        },
        {
          "fieldName": "downvotes",
          "operator": "gt",
          "value": 20
        },
        {
          "fieldName": "isPublished",
          "operator": "eq",
          "value": false
        },
        {
          "fieldName": "author",
          "operator": "eq",
          "value": "Person1"
        }
      ]
    }
  ]
}
```

------

# \$1util.math의 수학 연산 도우미
<a name="math-helpers-in-util-math"></a>

**참고**  
이제 우리는 주로 APPSYNC\$1JS 런타임과 해당 문서를 지원합니다. [여기](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)에서 APPSYNC\$1JS 런타임과 해당 안내서를 사용해 보세요.

 `$util.math`에는 일반적인 수학 연산 작업에 도움이 되는 메서드가 있습니다.

## \$1util.math 유틸리티 목록
<a name="math-helpers-in-util-math-list"></a>

** `$util.math.roundNum(Double) : Integer` **  
배수를 가져와서 가장 가까운 정수로 반올림합니다.

** `$util.math.minVal(Double, Double) : Double` **  
두 개의 배수를 가져와서 두 배수의 최소값을 반환합니다.

** `$util.math.maxVal(Double, Double) : Double` **  
두 개의 배수를 가져와서 두 배수의 최대값을 반환합니다.

** `$util.math.randomDouble() : Double` **  
0과 1 사이의 임의의 배수를 반환합니다.  
이 함수는 높은 엔트로피 무작위화가 필요한 경우(예: 암호화)에는 사용해서는 안 됩니다.

** `$util.math.randomWithinRange(Integer, Integer) : Integer` **  
지정된 범위 내의 임의의 정수 값을 반환합니다. 첫 번째 인수는 범위의 하한값을 지정하고 두 번째 인수는 범위의 상한값을 지정합니다.  
이 함수는 높은 엔트로피 무작위화가 필요한 경우(예: 암호화)에는 사용해서는 안 됩니다.

# \$1util.str의 문자열 도우미
<a name="str-helpers-in-util-str"></a>

**참고**  
이제 우리는 주로 APPSYNC\$1JS 런타임과 해당 문서를 지원합니다. [여기](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)에서 APPSYNC\$1JS 런타임과 해당 안내서를 사용해 보세요.

 `$util.str`에는 일반적인 문자열 작업에 도움이 되는 메서드가 있습니다.

## \$1util.str 유틸리티 목록
<a name="str-helpers-in-util-str-list"></a>

** `$util.str.toUpper(String) : String` **  
문자열을 가져와서 전체 대문자로 변환합니다.

** `$util.str.toLower(String) : String` **  
문자열을 가져와서 전체 소문자로 변환합니다.

** `$util.str.toReplace(String, String, String) : String` **  
문자열 내의 하위 문자열을 다른 문자열로 바꿉니다. 첫 번째 인수는 대체 작업을 수행할 문자열을 지정합니다. 두 번째 인수는 대체할 하위 문자열을 지정합니다. 세 번째 인수는 두 번째 인수를 대체할 문자열을 지정합니다. 다음은 이 유틸리티 사용 예제입니다.  

```
 INPUT:      $util.str.toReplace("hello world", "hello", "mellow")
 OUTPUT:     "mellow world"
```

** `$util.str.normalize(String, String) : String` **  
NFC, NFD, NFKC 또는 NFKD의 네 가지 유니코드 정규화 형식 중 하나를 사용하여 문자열을 정규화합니다. 첫 번째 인수는 정규화할 문자열입니다. 두 번째 인수는 정규화 프로세스에 사용할 정규화 유형을 지정하는 'nfc', 'nfd', 'nfkc' 또는 'nfkd'입니다.

# 확장 프로그램
<a name="extensions"></a>

**참고**  
이제 우리는 주로 APPSYNC\$1JS 런타임과 해당 문서를 지원합니다. [여기](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)에서 APPSYNC\$1JS 런타임과 해당 안내서를 사용해 보세요.

`$extensions`에는 해석기 내에서 추가 작업을 수행할 수 있는 일련의 메서드가 있습니다.

## 확장 사용
<a name="caching-extensions-list"></a>

**`$extensions.evictFromApiCache(String, String, Object) : Object`**  
 AWS AppSync 서버 측 캐시에서 항목을 제거합니다. 첫 번째 인수는 형식 이름입니다. 두 번째 인수는 필드 이름입니다. 세 번째 인수는 캐싱 키 값을 지정하는 키-값 쌍 항목을 포함하는 객체입니다. 캐시된 해석기의 `cachingKey`에 있는 캐싱 키와 동일한 순서로 객체에 항목을 넣어야 합니다.  
이 유틸리티는 뮤테이션에만 작동하고 쿼리에는 작동하지 않습니다.

## 구독 확장
<a name="subscription-extensions-list"></a>

**`$extensions.setSubscriptionFilter(filterJsonObject)`**  
향상된 구독 필터를 정의합니다. 각 구독 알림 이벤트는 제공된 구독 필터에 대해 평가되고 모든 필터가 `true`로 평가되면 클라이언트에 알림을 전달합니다. 인수는 다음 섹션에 설명된 대로 `filterJsonObject`입니다.  
이 확장 메서드는 구독 해석기의 응답 매핑 템플릿에서만 사용할 수 있습니다.

**`$extensions.setSubscriptionInvalidationFilter(filterJsonObject)`**  
구독 무효화 필터를 정의합니다. 구독 필터는 무효화 페이로드에 대해 평가된 후 필터가 `true`로 평가되면 지정된 구독을 무효화합니다. 인수는 다음 섹션에 설명된 대로 `filterJsonObject`입니다.  
이 확장 메서드는 구독 해석기의 응답 매핑 템플릿에서만 사용할 수 있습니다.

**`$extensions.invalidateSubscriptions(invalidationJsonObject)`**  
뮤테이션으로부터 구독 무효화를 시작하는 데 사용됩니다. 인수는 다음 섹션에 설명된 대로 `invalidationJsonObject`입니다.  
이 확장은 뮤테이션 해석기의 응답 매핑 템플릿에서만 사용할 수 있습니다.  
단일 요청에서 고유한 `$extensions.invalidateSubscriptions()` 메서드 직접 호출을 최대 5개까지만 사용할 수 있습니다. 이 한도를 초과할 경우 GraphQL 오류가 발생합니다.

## 인수: filterJsonObject
<a name="extensions-setSubscriptionInvalidationFilter"></a>

JSON 객체는 구독 또는 무효화 필터를 정의합니다. `filterGroup`에 있는 필터 배열입니다. 각 필터는 개별 필터의 모음입니다.

```
{
    "filterGroup": [
        {
           "filters" : [
                 {
                    "fieldName" : "userId",
                    "operator" : "eq",
                    "value" : 1
                }
           ]
           
        },
        {
           "filters" : [
                {
                    "fieldName" : "group",
                    "operator" : "in",
                    "value" : ["Admin", "Developer"]
                }
           ]
           
        }
    ]
}
```

각 필터에는 다음의 세 가지 속성이 있습니다.
+ `fieldName` - GraphQL 스키마 필드
+ `operator` - 연산자 유형
+ `value` - 구독 알림 `fieldName` 값과 비교할 값.

다음은 이러한 속성에 대한 할당 예시입니다.

```
{
 "fieldName" : "severity",
 "operator" : "le",
 "value" : $context.result.severity
}
```

### 필드: fieldName
<a name="extensions-fieldName"></a>

문자열 유형 `fieldName`은 구독 알림 페이로드에서 `fieldName`과 일치하는 GraphQL 스키마에 정의된 필드를 나타냅니다. 일치가 발견되면 GraphQL 스키마 필드의 `value`는 구독 알림 필터의 `value`와 비교됩니다. 다음 예제에서 `fieldName` 필터는 주어진 GraphQL 유형에 정의된 `service` 필드와 일치합니다. 알림 페이로드에 `AWS AppSync`와 동등한 `value`가 있는 `service` 필드가 포함된 경우 필터는 `true`로 평가합니다.

```
{
 "fieldName" : "service",
 "operator" : "eq",
 "value" : "AWS AppSync"
}
```

### 필드: 값
<a name="extensions-value"></a>

값은 연산자에 따라 다른 유형일 수 있습니다.
+ 단일 숫자 또는 부울
  + 문자열 예제: `"test"`, `"service"` 
  + 숫자 예제: `1`, `2`, `45.75` 
  + 부울 예제: `true`, `false` 
+ 숫자 또는 문자열 페어
  + 문자열 페어 예제:`["test1","test2"]`, `["start","end"]` 
  + 숫자 페어 예제: `[1,4]`, `[67,89]`, `[12.45, 95.45]` 
+ 숫자 또는 문자열 배열
  + 문자열 배열 예제: `["test1","test2","test3","test4","test5"]`
  + 숫자 배열 예제: `[1,2,3,4,5]`, `[12.11,46.13,45.09,12.54,13.89]` 

### 필드: 연산자
<a name="extensions-operator"></a>

대소문자를 구분하는 문자열로, 가능한 값은 다음과 같습니다.


| 
| 
| 연산자 | 설명 | 가능한 값 유형 | 
| --- |--- |--- |
| eq | Equal | integer, float, string, Boolean | 
| ne | Not equal | integer, float, string, Boolean | 
| le | Less than or equal | integer, float, string | 
| lt | Less than | integer, float, string | 
| ge | Greater than or equal | integer, float, string | 
| gt | Greater than | integer, float, string | 
| contains | Checks for a subsequence or value in the set. | integer, float, string | 
| notContains | Checks for the absence of a subsequence or absence of a value in the set. | integer, float, string | 
| beginsWith | Checks for a prefix. | string | 
| in | Checks for matching elements that are in the list. | Array of integer, float, or string | 
| notIn | Checks for matching elements that aren't in the list. | Array of integer, float, or string | 
| between | Between two values | integer, float, string | 
| containsAny | Contains common elements | integer, float, string | 

다음 테이블에는 구독 알림에서 각 연산자가 사용되는 방식이 설명되어 있습니다.

------
#### [ eq (equal) ]

`eq` 연산자는 구독 알림 필드 값이 일치하고 필터 값과 엄격하게 동일하면 `true`로 평가됩니다. 다음 예에서 구독 알림에 `AWS AppSync`와 동등한 값을 가진 `service` 필드가 있는 경우 필터는 `true`로 평가합니다.

**가능한 값 유형:** 정수, 부동 소수점, 문자열, 부울

```
{
 "fieldName" : "service",
 "operator" : "eq",
 "value" : "AWS AppSync"
}
```

------
#### [ ne (not equal) ]

`ne` 연산자는 구독 알림 필드 값이 필터 값과 다르면 `true`로 평가됩니다. 다음 예에서는 구독 알림에 `AWS AppSync`와 다른 값을 가진 `service` 필드가 있는 경우 필터는 `true`로 평가합니다.

**가능한 값 유형:** 정수, 부동 소수점, 문자열, 부울

```
{
 "fieldName" : "service",
 "operator" : "ne",
 "value" : "AWS AppSync"
}
```

------
#### [ le (less or equal) ]

`le` 연산자는 구독 알림 필드 값이 필터 값과 같거나 그보다 작으면 `true`로 평가됩니다. 다음 예에서는 구독 알림에 `5`와 같거나 그보다 작은 값을 가진 `size` 필드가 있는 경우 필터는 `true`로 평가합니다.

**가능한 값 유형:** 정수, 부동 소수점, 문자열

```
{
 "fieldName" : "size",
 "operator" : "le",
 "value" : 5
}
```

------
#### [ lt (less than) ]

`lt` 연산자는 구독 알림 필드 값이 필터 값보다 낮으면 `true`로 평가됩니다. 다음 예에서는 구독 알림에 `5`보다 낮은 값을 가진 `size` 필드가 있는 경우 필터는 `true`로 평가합니다.

**가능한 값 유형:** 정수, 부동 소수점, 문자열

```
{
 "fieldName" : "size",
 "operator" : "lt",
 "value" : 5
}
```

------
#### [ ge (greater or equal) ]

`ge` 연산자는 구독 알림 필드 값이 필터 값과 같거나 그보다 크면 `true`로 평가됩니다. 다음 예에서는 구독 알림에 `5`와 같거나 그보다 큰 값을 가진 `size` 필드가 있는 경우 필터는 `true`로 평가합니다.

**가능한 값 유형:** 정수, 부동 소수점, 문자열

```
{
 "fieldName" : "size",
 "operator" : "ge",
 "value" : 5
}
```

------
#### [ gt (greater than) ]

`gt` 연산자는 구독 알림 필드 값이 필터 값보다 크면 `true`로 평가됩니다. 다음 예에서는 구독 알림에 `5`보다 높은 값을 가진 `size` 필드가 있는 경우 필터는 `true`로 평가합니다.

**가능한 값 유형:** 정수, 부동 소수점, 문자열

```
{
 "fieldName" : "size",
 "operator" : "gt",
 "value" : 5
}
```

------
#### [ contains ]

`contains` 연산자는 집합이나 단일 항목의 하위 문자열, 하위 시퀀스 또는 값을 확인합니다. 구독 알림 필드 값에 필터 값이 포함된 경우 `contains` 연산자가 있는 필터는 `true`로 평가됩니다. 다음 예에서는 구독 알림에 값 `10`이 포함된 배열 값이 있는 `seats` 필드가 있는 경우 필터는 `true`로 평가합니다.

**가능한 값 유형:** 정수, 부동 소수점, 문자열

```
{
 "fieldName" : "seats",
 "operator" : "contains",
 "value" : 10
}
```

다른 예로, 필터는 구독 알림에 `launch`가 하위 문자열로 포함된 `event` 필드가 있는 경우 `true`로 평가합니다.

```
{
 "fieldName" : "event",
 "operator" : "contains",
 "value" : "launch"
}
```

------
#### [ notContains ]

`notContains` 연산자는 집합이나 단일 항목에 하위 문자열, 하위 시퀀스 또는 값이 없는지 확인합니다. 구독 알림 필드 값에 필터 값이 포함되지 않은 경우 `notContains` 연산자가 있는 필터는 `true`로 평가됩니다. 다음 예에서는 구독 알림에 값 `10`이 포함되지 않은 배열 값이 있는 `seats` 필드가 있는 경우 필터는 `true`로 평가합니다.

**가능한 값 유형:** 정수, 부동 소수점, 문자열

```
{
 "fieldName" : "seats",
 "operator" : "notContains",
 "value" : 10
}
```

다른 예로, 필터는 구독 알림에 `launch`가 하위 문자열로 포함되지 않은 `event` 필드 값이 있는 경우 `true`로 평가합니다.

```
{
 "fieldName" : "event",
 "operator" : "notContains",
 "value" : "launch"
}
```

------
#### [ beginsWith ]

`beginsWith` 연산자는 문자열에서 접두사를 확인합니다. 구독 알림 필드 값이 필터 값으로 시작하는 경우 `beginsWith` 연산자가 포함된 필터는 `true`로 평가됩니다. 다음 예에서는 구독 알림에 값이 `AWS`로 시작하는 `service` 필드가 있는 경우 필터는 `true`로 평가합니다.

**가능한 값 유형:** 문자열

```
{
 "fieldName" : "service",
 "operator" : "beginsWith",
 "value" : "AWS"
}
```

------
#### [ in ]

`in` 연산자는 배열에서 일치하는 요소가 있는지 확인합니다. `in` 연산자가 포함된 필터는 구독 알림 필드 값이 배열에 존재하는 경우 `true`로 평가됩니다. 다음 예에서는 구독 알림에 `[1,2,3]` 배열에 있는 값 중 하나가 포함된 `severity` 필드가 있는 경우 필터는 `true`로 평가합니다.

**가능한 값 유형:** 정수 배열, 부동 소수점 또는 문자열

```
{
 "fieldName" : "severity",
 "operator" : "in",
 "value" : [1,2,3]
}
```

------
#### [ notIn ]

`notIn` 연산자는 배열에서 누락된 요소가 있는지 확인합니다. `notIn` 연산자가 포함된 필터는 구독 알림 필드 값이 배열에 존재하지 않는 경우 `true`로 평가됩니다. 다음 예에서는 구독 알림에 `[1,2,3]` 배열에 없는 값 중 하나가 포함된 `severity` 필드가 있는 경우 필터는 `true`로 평가합니다.

**가능한 값 유형:** 정수 배열, 부동 소수점 또는 문자열

```
{
 "fieldName" : "severity",
 "operator" : "notIn",
 "value" : [1,2,3]
}
```

------
#### [ between ]

`between` 연산자는 두 숫자 또는 문자열 사이의 값을 확인합니다. 구독 알림 필드 값이 필터의 값 페어 사이에 있는 경우 `between` 연산자가 포함된 필터는 `true`로 평가됩니다. 다음 예에서는 구독 알림에 값이 `2`,`3`,`4`인 `severity` 필드가 있는 경우 필터는 `true`로 평가합니다.

**가능한 값 유형:** 정수 페어, 부동 소수점 또는 문자열

```
{
 "fieldName" : "severity",
 "operator" : "between",
 "value" : [1,5]
}
```

------
#### [ containsAny ]

`containsAny` 연산자는 배열에서 공통된 요소가 있는지 확인합니다. 구독 알림 필드 집합 값 및 필터 집합 값의 교차점이 비어 있지 않은 경우 `containsAny` 연산자가 있는 필터는 `true`로 평가됩니다. 다음 예에서는 구독 알림에 `10` 또는 `15`를 포함하는 배열 값을 가진 `seats` 필드가 있는 경우 필터는 `true`로 평가합니다. 이는 구독 알림에 `[10,11]` 또는 `[15,20,30]`라는 `seats` 필드 값이 있는 경우 필터가 `true`로 평가한다는 의미입니다.

**가능한 값 유형:** 정수, 부동 소수점 또는 문자열

```
{
 "fieldName" : "seats",
 "operator" : "containsAny",
 "value" : [10, 15]
}
```

------

### AND 로직
<a name="extensions-AND-logic"></a>

`filterGroup` 배열의 `filters` 객체 내에 여러 항목을 정의하여 AND 논리를 사용하여 여러 필터를 결합할 수 있습니다. 다음 예에서는 구독 알림에 값이 `1`인 `userId` 필드가 있고(AND) `Admin` 또는 `Developer`인 `group` 필드 값이 있는 경우 필터는 `true`로 평가합니다.

```
{
    "filterGroup": [
        {
           "filters" : [
                 {
                    "fieldName" : "userId",
                    "operator" : "eq",
                    "value" : 1
                },
                {
                    "fieldName" : "group",
                    "operator" : "in",
                    "value" : ["Admin", "Developer"]
                }
           ]
           
        }
    ]
}
```

### OR 로직
<a name="extensions-OR-logic"></a>

`filterGroup` 배열 내에서 여러 필터 객체를 정의하면 OR 논리를 사용하여 여러 필터를 결합할 수 있습니다. 다음 예에서는 구독 알림에 값이 `1`인 `userId` 필드가 있거나(OR) `Admin` 또는 `Developer`인 `group` 필드 값이 있는 경우 필터는 `true`로 평가합니다.

```
{
    "filterGroup": [
        {
           "filters" : [
                 {
                    "fieldName" : "userId",
                    "operator" : "eq",
                    "value" : 1
                }
           ]
           
        },
        {
           "filters" : [
                {
                    "fieldName" : "group",
                    "operator" : "in",
                    "value" : ["Admin", "Developer"]
                }
           ]
           
        }
    ]
}
```

### 예외
<a name="extensions-exceptions"></a>

필터 사용에는 몇 가지 제한이 있다는 점에 유의하세요.
+ `filters` 객체에는 필터당 최대 5개의 고유 `fieldName` 항목이 있을 수 있습니다. 즉, AND 로직을 사용하여 최대 5개의 개별 `fieldName` 객체를 결합할 수 있습니다.
+ `containsAny` 연산자에는 최대 20개의 값이 있을 수 있습니다.
+ `in` 및 `notIn` 연산자에는 최대 5개의 값이 있을 수 있습니다.
+ 각 연결 문자열은 최대 256자입니다.
+ 각 문자열 비교는 대/소문자를 구분합니다.
+ 중첩된 객체 필터링은 최대 5개의 중첩 수준 필터링을 허용합니다.
+ 각 `filterGroup`에는 최대 10개의 `filters`가 있을 수 있습니다. 즉, OR 로직을 사용하여 최대 10개의 개별 `filters`를 결합할 수 있습니다.
  + `in` 연산자는 OR 논리의 특별 사례입니다. 다음 예제에서는 두 가지 `filters`가 있습니다.

    ```
    {
        "filterGroup": [
            {
               "filters" : [
                     {
                        "fieldName" : "userId",
                        "operator" : "eq",
                        "value" : 1
                    },
                    {
                        "fieldName" : "group",
                        "operator" : "in",
                        "value" : ["Admin", "Developer"]
                    }
               ]  
            }
        ]
    }
    ```

    이전 필터 그룹은 다음과 같이 평가되며 최대 필터 한도에 포함됩니다.

    ```
    {
        "filterGroup": [
            {
               "filters" : [
                     {
                        "fieldName" : "userId",
                        "operator" : "eq",
                        "value" : 1
                    },
                    {
                        "fieldName" : "group",
                        "operator" : "eq",
                        "value" : "Admin"
                    }
               ]  
            },
            {
               "filters" : [
                     {
                        "fieldName" : "userId",
                        "operator" : "eq",
                        "value" : 1
                    },
                    {
                        "fieldName" : "group",
                        "operator" : "eq",
                        "value" : "Developer"
                    }
               ]  
            }
        ]
    }
    ```

## 인수: invalidationJsonObject
<a name="extensions-invalidationJsonObject"></a>

`invalidationJsonObject`는 다음을 정의합니다.
+ `subscriptionField` - 무효화할 GraphQL 스키마 구독입니다. `subscriptionField`에서 문자열로 정의된 단일 구독은 무효화 대상으로 간주됩니다.
+ `payload` – 무효화 필터가 해당 값에 대해 `true`로 평가되는 경우 구독 무효화를 위한 입력으로 사용되는 키-값 쌍 목록입니다.

  다음 예에서는 구독 해석기에 정의된 무효화 필터가 `payload` 값에 대해 `true`로 평가될 때 `onUserDelete` 구독을 사용하여 구독 및 연결된 클라이언트를 무효화합니다.

  ```
  $extensions.invalidateSubscriptions({
          "subscriptionField": "onUserDelete",
          "payload": {
                  "group": "Developer"
                  "type" : "Full-Time"
        }
      })
  ```

# DynamoDB용 AWS AppSync 해석기 매핑 템플릿 참조
<a name="resolver-mapping-template-reference-dynamodb"></a>

**참고**  
이제 우리는 주로 APPSYNC\$1JS 런타임과 해당 문서를 지원합니다. [여기](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)에서 APPSYNC\$1JS 런타임과 해당 안내서를 사용해 보세요.

 AWS AppSync DynamoDB 함수를 사용하면 수신 [GraphQL](https://graphql.org) 요청을 DynamoDB 호출에 매핑한 다음 DynamoDB 응답을 GraphQL에 다시 매핑하여 GraphQL을 사용하여 계정의 기존 Amazon DynamoDB 테이블에 데이터를 저장하고 검색할 수 있습니다. 이 섹션에서는 지원되는 DynamoDB 작업에 대한 요청 및 응답 핸들러를 설명합니다.
+  [GetItem](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-resolver-mapping-template-reference-dynamodb-getitem.html) - GetItem 요청을 통해 DynamoDB 함수에 지시하여 DynamoDB에 GetItem 요청을 할 수 있으며, DynamoDB의 항목 키 및 일관된 읽기를 사용할지 여부를 지정할 수 있습니다.
+  [ PutItem ](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-resolver-mapping-template-reference-dynamodb-putitem.html) - PutItem 요청 매핑 문서를 사용하면 DynamoDB 함수에 지시하여 DynamoDB에 PutItem 요청을 할 수 있으며, DynamoDB의 항목 키, 항목의 전체 내용(키 및 attributeValues로 구성), 작업 성공 조건을 지정할 수 있습니다.
+  [ UpdateItem ](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-resolver-mapping-template-reference-dynamodb-updateitem.html) - UpdateItem 요청을 사용하면 DynamoDB 함수에 지시하여 DynamoDB에 UpdateItem 요청을 할 수 있으며, DynamoDB의 항목 키, DynamoDB에서 항목을 업데이트하는 방법을 설명하는 업데이트 표현식 및 작업 성공 조건을 지정할 수 있습니다.
+  [ DeleteItem ](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-resolver-mapping-template-reference-dynamodb-deleteitem.html) - DeleteItem 요청을 사용하면 DynamoDB 함수에 지시하여 DynamoDB에 DeleteItem 요청을 할 수 있으며, DynamoDB의 항목 키 및 작업 성공 조건을 지정할 수 있습니다.
+  [ 쿼리 ](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-resolver-mapping-template-reference-dynamodb-query.html) - 쿼리 요청 객체를 사용하면 DynamoDB 해석기에 지시하여 DynamoDB에 쿼리 요청을 할 수 있으며, 키 표현식, 사용할 인덱스, 추가 필터, 반환할 항목 수, 일관된 읽기 사용 여부, 쿼리 방향(앞 또는 뒤로) 및 페이지 매김 토큰을 지정할 수 있습니다.
+  [ 스캔 ](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-resolver-mapping-template-reference-dynamodb-scan.html) - 스캔 요청을 통해 DynamoDB 함수에 지시하여 DynamoDB에 스캔 요청을 할 수 있으며, 결과를 제외하는 필터, 사용할 인덱스, 반환할 항목 수, 일관된 읽기 사용 여부, 페이지 매김 토큰 및 병렬 스캔을 지정할 수 있습니다.
+  [ 동기화 ](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-resolver-mapping-template-reference-dynamodb-sync.html) - 동기화 요청 객체를 사용하면 DynamoDB 테이블에서 모든 결과를 가져온 다음, 마지막 쿼리(델타 업데이트) 이후에 변경된 데이터만 수신할 수 있습니다. 버전이 지정된 DynamoDB 데이터 소스에만 동기화 요청할 수 있습니다. 결과를 제외하는 필터, 반환할 항목 수, 페이지 매김 토큰 및 마지막 동기화 작업 시작 시간을 지정할 수 있습니다.
+  [ BatchGetItem ](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-resolver-mapping-template-reference-dynamodb-batch-get-item.html) - BatchGetItem 요청 객체를 사용하면 DynamoDB 함수에 지시하여 DynamoDB에 BatchGetItem 요청을 전달하고 잠재적으로 여러 테이블에 걸쳐 여러 항목을 검색할 수 있습니다. 이 요청 객체의 경우 항목을 검색할 테이블 이름과 각 테이블에서 검색할 항목의 키를 지정해야 합니다.
+  [ BatchDeleteItem ](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-resolver-mapping-template-reference-dynamodb-batch-delete-item.html) - BatchDeleteItem 요청 객체를 사용하면 DynamoDB 함수에 지시하여 DynamoDB에 BatchWriteItem 요청을 전달하고 잠재적으로 여러 테이블에 걸쳐 여러 항목을 삭제할 수 있습니다. 이 요청 객체의 경우 항목을 삭제할 테이블 이름과 각 테이블에서 삭제할 항목의 키를 지정해야 합니다.
+  [ BatchPutItem ](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-resolver-mapping-template-reference-dynamodb-batch-put-item.html) - BatchPutItem 요청 객체를 사용하면 DynamoDB 함수에 지시하여 DynamoDB에 BatchWriteItem 요청을 전달하고 잠재적으로 여러 테이블에 걸쳐 여러 항목을 배치할 수 있습니다. 이 요청 객체의 경우 항목을 배치할 테이블 이름과 각 테이블에 배치할 전체 항목을 지정해야 합니다.
+  [ TransactGetItems ](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-resolver-mapping-template-reference-dynamodb-transact-get-items.html) - TransactGetItems 요청 객체를 사용하면 DynamoDB 함수에 지시하여 DynamoDB에 TransactGetItems 요청을 전달하고 잠재적으로 여러 테이블에 걸쳐 여러 항목을 검색할 수 있습니다. 이 요청 객체의 경우 항목을 검색할 각 요청 항목의 테이블 이름과 각 테이블에서 검색할 각 요청 항목의 키를 지정해야 합니다.
+  [ TransactWriteItems ](https://docs.aws.amazon.com/appsync/latest/devguide/js-aws-appsync-resolver-reference-dynamodb-transact-write-items.html) - TransactWriteItems 요청 객체를 사용하면 DynamoDB 함수에 지시하여 DynamoDB에 TransactWriteItems 요청을 전달하고 잠재적으로 여러 테이블에 걸쳐 여러 항목을 작성할 수 있습니다. 이 요청 객체의 경우 각 요청 항목의 대상 테이블 이름, 수행할 각 요청 항목의 작업, 작성할 각 요청 항목의 키를 지정해야 합니다.
+  [ 유형 시스템(요청 매핑) ](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-request.html) - DynamoDB 입력이 AWS AppSync 요청에 통합되는 방법에 대해 자세히 알아봅니다.
+  [ 유형 시스템(응답 매핑) ](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-responses.html) - DynamoDB 유형이 응답 페이로드에서 자동으로 GraphQL 또는 JSON으로 변환되는 방식을 자세히 알아봅니다.
+  [필터](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-resolver-mapping-template-reference-dynamodb-filter.html) - 쿼리 및 스캔 작업의 필터에 대해 자세히 알아봅니다.
+  [ 조건 표현식 ](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-resolver-mapping-template-reference-dynamodb-condition-expressions.html) - PutItem, UpdateItem 및 DeleteItem 작업의 조건 표현식을 자세히 알아봅니다.
+  [ 트랜잭션 조건 표현식 ](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-resolver-mapping-template-reference-dynamodb-transaction-condition-expressions.html) - TransactWriteItems 작업의 조건 표현식을 자세히 알아봅니다.
+  [ 프로젝션 ](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-resolver-mapping-template-reference-dynamodb-projections.html) - 읽기 작업에서 특성을 지정하는 방법을 자세히 알아봅니다.

# GetItem
<a name="aws-appsync-resolver-mapping-template-reference-dynamodb-getitem"></a>

`GetItem` 요청 매핑 문서를 사용하면 AWS AppSync DynamoDB 해석기에 DynamoDB에 `GetItem` 요청하도록 지시하고 다음을 지정할 수 있습니다.
+ DynamoDB의 항목 키
+ 일관된 읽기를 사용할지 여부

`GetItem` 매핑 문서의 구조는 다음과 같습니다.

```
{
    "version" : "2017-02-28",
    "operation" : "GetItem",
    "key" : {
        "foo" : ... typed value,
        "bar" : ... typed value
    },
    "consistentRead" : true,
    "projection" : {
        ...
    }
}
```

필드는 다음과 같이 정의됩니다.

## GetItem 필드
<a name="getitem-list"></a>

### GetItem 필드 목록
<a name="getitem-list-col"></a>

 **`version`**   
템플릿 정의 버전. `2017-02-28` 및 `2018-05-29`만 현재 지원됩니다. 이 값은 필수입니다.

 **`operation`**   
수행할 DynamoDB 작업입니다. `GetItem` DynamoDB 작업을 수행하려면 이 값을 `GetItem`으로 설정해야 합니다. 이 값은 필수입니다.

 **`key`**   
DynamoDB의 항목 키입니다. DynamoDB 항목은 테이블 구조에 따라 단일 해시 키 또는 해시 키와 정렬 키를 가질 수 있습니다. '입력된 값'을 지정하는 방법에 대한 자세한 내용은 [유형 시스템(요청 매핑)](aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-request.md)을 참조하세요. 이 값은 필수입니다.

 **`consistentRead`**   
DynamoDB에서 강력히 일관된 읽기를 수행할지 여부. 선택 사항으로, 기본값은 `false`입니다.

**`projection`**  
DynamoDB 작업에서 반환할 속성을 지정하는 데 사용되는 프로젝션입니다. 프로젝션에 대한 자세한 내용은 [프로젝션](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-dynamodb.html#aws-appsync-resolver-mapping-template-reference-dynamodb-projections)을 참조하세요. 이 필드는 선택 사항입니다.

DynamoDB에서 반환된 항목은 자동으로 GraphQL 및 JSON 기본 유형으로 변환되며 매핑 컨텍스트(`$context.result`)에서 사용할 수 있습니다.

DynamoDB 형식 변환에 대한 자세한 내용은 [형식 시스템(응답 매핑)](aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-responses.md)을 참조하세요.

응답 매핑 템플릿에 대한 자세한 내용은 [해석기 매핑 템플릿 개요](resolver-mapping-template-reference-overview.md#aws-appsync-resolver-mapping-template-reference-overview)를 참조하세요.

## 예제
<a name="example"></a>

다음 예제는 GraphQL 쿼리 `getThing(foo: String!, bar: String!)`의 매핑 템플릿입니다.

```
{
    "version" : "2017-02-28",
    "operation" : "GetItem",
    "key" : {
        "foo" : $util.dynamodb.toDynamoDBJson($ctx.args.foo),
        "bar" : $util.dynamodb.toDynamoDBJson($ctx.args.bar)
    },
    "consistentRead" : true
}
```

DynamoDB `GetItem` API에 대한 자세한 내용은 [DynamoDB API 문서](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_GetItem.html)를 참조하십시오.

# PutItem
<a name="aws-appsync-resolver-mapping-template-reference-dynamodb-putitem"></a>

`PutItem` 요청 매핑 문서를 사용하면 AWS AppSync DynamoDB 해석기에 DynamoDB에 `PutItem` 요청하도록 지시하고 다음을 지정할 수 있습니다.
+ DynamoDB의 항목 키
+ 항목의 전체 내용(`key` 및 `attributeValues`로 구성됨)
+ 성공할 작업의 조건

`PutItem` 매핑 문서의 구조는 다음과 같습니다.

```
{
    "version" : "2018-05-29",
    "operation" : "PutItem",
    "customPartitionKey" : "foo",
    "populateIndexFields" : boolean value,
    "key": {
        "foo" : ... typed value,
        "bar" : ... typed value
    },
    "attributeValues" : {
        "baz" : ... typed value
    },
    "condition" : {
       ...
    },
    "_version" : 1
}
```

필드는 다음과 같이 정의됩니다.

## PutItem 필드
<a name="putitem-list"></a>

### PutItem 필드 목록
<a name="putitem-list-col"></a>

 **`version`**   
템플릿 정의 버전. `2017-02-28` 및 `2018-05-29`만 현재 지원됩니다. 이 값은 필수입니다.

 **`operation`**   
수행할 DynamoDB 작업입니다. `PutItem` DynamoDB 작업을 수행하려면 이 값을 `PutItem`으로 설정해야 합니다. 이 값은 필수입니다.

 **`key`**   
DynamoDB의 항목 키입니다. DynamoDB 항목은 테이블 구조에 따라 단일 해시 키 또는 해시 키와 정렬 키를 가질 수 있습니다. '입력된 값'을 지정하는 방법에 대한 자세한 내용은 [유형 시스템(요청 매핑)](aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-request.md)을 참조하세요. 이 값은 필수입니다.

 **`attributeValues`**   
DynamoDB에 저장할 항목의 나머지 속성. '입력된 값'을 지정하는 방법에 대한 자세한 내용은 [유형 시스템(요청 매핑)](aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-request.md)을 참조하세요. 이 필드는 선택 사항입니다.

 **`condition`**   
DynamoDB에 이미 있는 객체의 상태를 기반으로 요청의 성공 여부를 결정하는 조건. 조건을 지정하지 않으면 `PutItem` 요청이 해당 항목에 대한 기존 입력을 덮어씁니다. 조건에 대한 자세한 내용은 [조건 표현식](aws-appsync-resolver-mapping-template-reference-dynamodb-condition-expressions.md)을 참조하세요. 이 값은 선택 사항입니다.

 **`_version`**   
항목의 알려진 최신 버전을 나타내는 숫자 값입니다. 이 값은 선택 사항입니다. 이 필드는 *충돌 감지*에 사용되며 버전이 지정된 데이터 원본에만 지원됩니다.

**`customPartitionKey`**  
활성화되면 이 문자열 값은 버전 관리가 활성화되었을 때 델타 동기화 테이블에서 사용되는 `ds_sk` 및 `ds_pk` 레코드의 형식을 수정합니다(자세한 내용은 **AWS AppSync 개발자 안내서의 [충돌 감지 및 동기화](https://docs.aws.amazon.com/appsync/latest/devguide/conflict-detection-and-sync.html) 참조). 활성화되면 `populateIndexFields` 항목 처리도 활성화됩니다. 이 필드는 선택 사항입니다.

**`populateIndexFields`**  
**`customPartitionKey`와 함께** 활성화되면 델타 동기화 테이블, 특히 `gsi_ds_pk` 및 `gsi_ds_sk` 열의 각 레코드에 대해 새 항목을 생성하는 부울 값입니다. 자세한 내용은 **AWS AppSync 개발자 안내서의 [충돌 감지 및 동기화](https://docs.aws.amazon.com/appsync/latest/devguide/conflict-detection-and-sync.html)를 참조하세요. 이 필드는 선택 사항입니다.

DynamoDB에 기록된 항목은 자동으로 GraphQL 및 JSON 기본 형식으로 변환되며 매핑 컨텍스트(`$context.result`)에서 사용할 수 있습니다.

DynamoDB 형식 변환에 대한 자세한 내용은 [형식 시스템(응답 매핑)](aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-responses.md)을 참조하세요.

응답 매핑 템플릿에 대한 자세한 내용은 [해석기 매핑 템플릿 개요](resolver-mapping-template-reference-overview.md#aws-appsync-resolver-mapping-template-reference-overview)를 참조하세요.

## 예제 1.
<a name="example-1"></a>

다음 예제는 GraphQL 변형 `updateThing(foo: String!, bar: String!, name: String!, version: Int!)`의 매핑 템플릿입니다.

지정된 키가 있는 항목이 없으면 생성됩니다. 지정된 키가 있는 항목이 있으면 덮어씁니다.

```
{
    "version" : "2017-02-28",
    "operation" : "PutItem",
    "key": {
        "foo" : $util.dynamodb.toDynamoDBJson($ctx.args.foo),
        "bar" : $util.dynamodb.toDynamoDBJson($ctx.args.bar)
    },
    "attributeValues" : {
        "name"    : $util.dynamodb.toDynamoDBJson($ctx.args.name),
        "version" : $util.dynamodb.toDynamoDBJson($ctx.args.version)
    }
}
```

## 예제 2.
<a name="example-2"></a>

다음 예제는 GraphQL 변형 `updateThing(foo: String!, bar: String!, name: String!, expectedVersion: Int!)`의 매핑 템플릿입니다.

이 예에서는 현재 DynamoDB에 있는 항목의 `version` 필드가 `expectedVersion`으로 설정되어 있는지 확인합니다.

```
{
    "version" : "2017-02-28",
    "operation" : "PutItem",
    "key": {
        "foo" : $util.dynamodb.toDynamoDBJson($ctx.args.foo),
        "bar" : $util.dynamodb.toDynamoDBJson($ctx.args.bar)
    },
    "attributeValues" : {
        "name"    : $util.dynamodb.toDynamoDBJson($ctx.args.name),
        #set( $newVersion = $context.arguments.expectedVersion + 1 )
        "version" : $util.dynamodb.toDynamoDBJson($newVersion)
    },
    "condition" : {
        "expression" : "version = :expectedVersion",
        "expressionValues" : {
            ":expectedVersion" : $util.dynamodb.toDynamoDBJson($expectedVersion)
        }
    }
}
```

DynamoDB `PutItem` API에 대한 자세한 내용은 [DynamoDB API 문서](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html)를 참조하십시오.

# UpdateItem
<a name="aws-appsync-resolver-mapping-template-reference-dynamodb-updateitem"></a>

`UpdateItem` 요청 매핑 문서를 사용하면 AWS AppSync DynamoDB 해석기에 DynamoDB에 `UpdateItem` 요청을 하도록 지시하고 다음을 지정할 수 있습니다.
+ DynamoDB의 항목 키
+ DynamoDB에서 항목 업데이트 방법을 설명하는 업데이트 표현식
+ 성공할 작업의 조건

`UpdateItem` 매핑 문서의 구조는 다음과 같습니다.

```
{
    "version" : "2018-05-29",
    "operation" : "UpdateItem",
    "customPartitionKey" : "foo",
    "populateIndexFields" : boolean value,
    "key": {
        "foo" : ... typed value,
        "bar" : ... typed value
    },
    "update" : {
        "expression" : "someExpression",
        "expressionNames" : {
           "#foo" : "foo"
       },
       "expressionValues" : {
           ":bar" : ... typed value
       }
    },
    "condition" : {
        ...
    },
    "_version" : 1
}
```

필드는 다음과 같이 정의됩니다.

## UpdateItem 필드
<a name="updateitem-list"></a>

### UpdateItem 필드 목록
<a name="updateitem-list-col"></a>

 **`version`**   
템플릿 정의 버전. `2017-02-28` 및 `2018-05-29`만 현재 지원됩니다. 이 값은 필수입니다.

 **`operation`**   
수행할 DynamoDB 작업입니다. `UpdateItem` DynamoDB 작업을 수행하려면 이 값을 `UpdateItem`으로 설정해야 합니다. 이 값은 필수입니다.

 **`key`**   
DynamoDB의 항목 키입니다. DynamoDB 항목은 테이블 구조에 따라 단일 해시 키 또는 해시 키와 정렬 키를 가질 수 있습니다. '입력된 값' 지정에 대한 자세한 내용은 [유형 시스템(요청 매핑)](aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-request.md)을 참조하세요. 이 값은 필수입니다.

 **`update`**   
`update` 섹션에서는 DynamoDB의 항목 업데이트 방법을 설명하는 업데이트 표현식을 지정합니다. 업데이트 표현식을 작성하는 방법에 대한 자세한 내용은 [DynamoDB UpdateExpressions 문서](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html)를 참조하십시오. 이 섹션은 필수입니다.  
`update` 섹션에는 다음 세 가지 구성 요소가 있습니다.    
** `expression` **  
업데이트 표현식. 이 값은 필수입니다.  
** `expressionNames` **  
표현식 속성 *name* 자리 표시자의 대체 항목으로, 키-값 페어의 형식으로 표시됩니다. 키는 `expression`에 사용된 name 자리 표시자에 해당하고 값은 DynamoDB에 있는 항목의 속성 이름에 해당하는 문자열이어야 합니다. 이 필드는 선택 사항으로, `expression`에 사용된 표현식 속성인 name 자리 표시자의 대체 항목으로만 채워져야 합니다.  
** `expressionValues` **  
표현식 속성 *value* 자리 표시자의 대체 항목으로, 키-값 페어의 형식으로 표시됩니다. 키는 `expression`에 사용되는 value 자리 표시자에 해당하고 값은 입력된 값이어야 합니다. '입력된 값'을 지정하는 방법에 대한 자세한 내용은 [유형 시스템(요청 매핑)](aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-request.md)을 참조하세요. 입력된 값은 지정되어 있어야 합니다. 이 필드는 선택 사항으로, `expression`에 사용된 표현식 속성인 value 자리 표시자의 대체 항목으로만 채워져야 합니다.

 **`condition`**   
DynamoDB에 이미 있는 객체의 상태를 기반으로 요청의 성공 여부를 결정하는 조건. 조건을 지정하지 않으면 `UpdateItem` 요청이 현재 상태와 상관 없이 기존 항목을 업데이트합니다. 조건에 대한 자세한 내용은 [조건 표현식](aws-appsync-resolver-mapping-template-reference-dynamodb-condition-expressions.md)을 참조하세요. 이 값은 선택 사항입니다.

 **`_version`**   
항목의 알려진 최신 버전을 나타내는 숫자 값입니다. 이 값은 선택 사항입니다. 이 필드는 *충돌 감지*에 사용되며 버전이 지정된 데이터 원본에만 지원됩니다.

**`customPartitionKey`**  
활성화되면 이 문자열 값은 버전 관리가 활성화되었을 때 델타 동기화 테이블에서 사용되는 `ds_sk` 및 `ds_pk` 레코드의 형식을 수정합니다(자세한 내용은 **AWS AppSync 개발자 안내서의 [충돌 감지 및 동기화](https://docs.aws.amazon.com/appsync/latest/devguide/conflict-detection-and-sync.html) 참조). 활성화되면 `populateIndexFields` 항목 처리도 활성화됩니다. 이 필드는 선택 사항입니다.

**`populateIndexFields`**  
**`customPartitionKey`와 함께** 활성화되면 델타 동기화 테이블, 특히 `gsi_ds_pk` 및 `gsi_ds_sk` 열의 각 레코드에 대해 새 항목을 생성하는 부울 값입니다. 자세한 내용은 **AWS AppSync 개발자 안내서의 [충돌 감지 및 동기화](https://docs.aws.amazon.com/appsync/latest/devguide/conflict-detection-and-sync.html)를 참조하세요. 이 필드는 선택 사항입니다.

DynamoDB에서 업데이트된 항목은 자동으로 GraphQL 및 JSON 기본 형식으로 변환되며 매핑 컨텍스트(`$context.result`)에서 사용할 수 있습니다.

DynamoDB 형식 변환에 대한 자세한 내용은 [형식 시스템(응답 매핑)](aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-responses.md)을 참조하세요.

응답 매핑 템플릿에 대한 자세한 내용은 [해석기 매핑 템플릿 개요](resolver-mapping-template-reference-overview.md#aws-appsync-resolver-mapping-template-reference-overview)를 참조하세요.

## 예제 1.
<a name="id3"></a>

다음 예제는 GraphQL 변형 `upvote(id: ID!)`의 매핑 템플릿입니다.

이 예에서 DynamoDB의 항목에는 1씩 증가하는 `upvotes` 및 `version` 필드가 있습니다.

```
{
    "version" : "2017-02-28",
    "operation" : "UpdateItem",
    "key" : {
        "id" : $util.dynamodb.toDynamoDBJson($ctx.args.id)
    },
    "update" : {
        "expression" : "ADD #votefield :plusOne, version :plusOne",
        "expressionNames" : {
            "#votefield" : "upvotes"
        },
        "expressionValues" : {
            ":plusOne" : { "N" : 1 }
        }
    }
}
```

## 예제 2.
<a name="id4"></a>

다음 예제는 GraphQL 변형 `updateItem(id: ID!, title: String, author: String, expectedVersion: Int!)`의 매핑 템플릿입니다.

다음은 인수를 조사해 클라이언트에서 제공한 인수만 포함하는 업데이트 표현식을 동적으로 생성하는 복잡한 예입니다. 예를 들어, `title` 및 `author`는 생략되면 업데이트되지 않습니다. 인수가 지정되어 있으나 그 값이 `null`이면 DynamoDB의 객체에서 해당 필드가 삭제됩니다. 마지막으로, 이 작업에는 DynamoDB에 현재 있는 항목에 `expectedVersion`으로 설정된 `version` 필드가 있는지 확인하는 조건이 있습니다.

```
{
    "version" : "2017-02-28",

    "operation" : "UpdateItem",

    "key" : {
        "id" : $util.dynamodb.toDynamoDBJson($ctx.args.id)
    },

    ## Set up some space to keep track of things we're updating **
    #set( $expNames  = {} )
    #set( $expValues = {} )
    #set( $expSet = {} )
    #set( $expAdd = {} )
    #set( $expRemove = [] )

    ## Increment "version" by 1 **
    $!{expAdd.put("version", ":newVersion")}
    $!{expValues.put(":newVersion", { "N" : 1 })}

    ## Iterate through each argument, skipping "id" and "expectedVersion" **
    #foreach( $entry in $context.arguments.entrySet() )
        #if( $entry.key != "id" && $entry.key != "expectedVersion" )
            #if( (!$entry.value) && ("$!{entry.value}" == "") )
                ## If the argument is set to "null", then remove that attribute from the item in DynamoDB **

                #set( $discard = ${expRemove.add("#${entry.key}")} )
                $!{expNames.put("#${entry.key}", "$entry.key")}
            #else
                ## Otherwise set (or update) the attribute on the item in DynamoDB **

                $!{expSet.put("#${entry.key}", ":${entry.key}")}
                $!{expNames.put("#${entry.key}", "$entry.key")}

                #if( $entry.key == "ups" || $entry.key == "downs" )
                    $!{expValues.put(":${entry.key}", { "N" : $entry.value })}
                #else
                    $!{expValues.put(":${entry.key}", { "S" : "${entry.value}" })}
                #end
            #end
        #end
    #end

    ## Start building the update expression, starting with attributes we're going to SET **
    #set( $expression = "" )
    #if( !${expSet.isEmpty()} )
        #set( $expression = "SET" )
        #foreach( $entry in $expSet.entrySet() )
            #set( $expression = "${expression} ${entry.key} = ${entry.value}" )
            #if ( $foreach.hasNext )
                #set( $expression = "${expression}," )
            #end
        #end
    #end

    ## Continue building the update expression, adding attributes we're going to ADD **
    #if( !${expAdd.isEmpty()} )
        #set( $expression = "${expression} ADD" )
        #foreach( $entry in $expAdd.entrySet() )
            #set( $expression = "${expression} ${entry.key} ${entry.value}" )
            #if ( $foreach.hasNext )
                #set( $expression = "${expression}," )
            #end
        #end
    #end

    ## Continue building the update expression, adding attributes we're going to REMOVE **
    #if( !${expRemove.isEmpty()} )
        #set( $expression = "${expression} REMOVE" )

        #foreach( $entry in $expRemove )
            #set( $expression = "${expression} ${entry}" )
            #if ( $foreach.hasNext )
                #set( $expression = "${expression}," )
            #end
        #end
    #end

    ## Finally, write the update expression into the document, along with any expressionNames and expressionValues **
    "update" : {
        "expression" : "${expression}"
        #if( !${expNames.isEmpty()} )
            ,"expressionNames" : $utils.toJson($expNames)
        #end
        #if( !${expValues.isEmpty()} )
            ,"expressionValues" : $utils.toJson($expValues)
        #end
    },

    "condition" : {
        "expression"       : "version = :expectedVersion",
        "expressionValues" : {
            ":expectedVersion" : $util.dynamodb.toDynamoDBJson($ctx.args.expectedVersion)
        }
    }
}
```

DynamoDB `UpdateItem` API에 대한 자세한 내용은 [DynamoDB API 문서](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateItem.html)를 참조하십시오.

# DeleteItem
<a name="aws-appsync-resolver-mapping-template-reference-dynamodb-deleteitem"></a>

`DeleteItem` 요청 매핑 문서를 사용하면 AWS AppSync DynamoDB 해석기에 DynamoDB에 `DeleteItem` 요청하도록 지시하고 다음을 지정할 수 있습니다.
+ DynamoDB의 항목 키
+ 성공할 작업의 조건

`DeleteItem` 매핑 문서의 구조는 다음과 같습니다.

```
{
    "version" : "2018-05-29",
    "operation" : "DeleteItem",
    "customPartitionKey" : "foo",
    "populateIndexFields" : boolean value,
    "key": {
        "foo" : ... typed value,
        "bar" : ... typed value
    },
    "condition" : {
        ...
    },
    "_version" : 1
}
```

필드는 다음과 같이 정의됩니다.

## DeleteItem 필드
<a name="deleteitem-list"></a>

### DeleteItem 필드 목록
<a name="deleteitem-list-col"></a>

** `version` **  
템플릿 정의 버전. `2017-02-28` 및 `2018-05-29`만 현재 지원됩니다. 이 값은 필수입니다.

** `operation` **  
수행할 DynamoDB 작업입니다. `DeleteItem` DynamoDB 작업을 수행하려면 이 값을 `DeleteItem`으로 설정해야 합니다. 이 값은 필수입니다.

** `key` **  
DynamoDB의 항목 키입니다. DynamoDB 항목은 테이블 구조에 따라 단일 해시 키 또는 해시 키와 정렬 키를 가질 수 있습니다. '입력된 값' 지정에 대한 자세한 내용은 [유형 시스템(요청 매핑)](aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-request.md)을 참조하세요. 이 값은 필수입니다.

** `condition` **  
DynamoDB에 이미 있는 객체의 상태를 기반으로 요청의 성공 여부를 결정하는 조건. 조건을 지정하지 않으면 `DeleteItem` 요청이 현재 상태와 상관 없이 항목을 삭제합니다. 조건에 대한 자세한 내용은 [조건 표현식](aws-appsync-resolver-mapping-template-reference-dynamodb-condition-expressions.md)을 참조하세요. 이 값은 선택 사항입니다.

** `_version` **  
항목의 알려진 최신 버전을 나타내는 숫자 값입니다. 이 값은 선택 사항입니다. 이 필드는 *충돌 감지*에 사용되며 버전이 지정된 데이터 원본에만 지원됩니다.

**`customPartitionKey`**  
활성화되면 이 문자열 값은 버전 관리가 활성화되었을 때 델타 동기화 테이블에서 사용되는 `ds_sk` 및 `ds_pk` 레코드의 형식을 수정합니다(자세한 내용은 **AWS AppSync 개발자 안내서의 [충돌 감지 및 동기화](https://docs.aws.amazon.com/appsync/latest/devguide/conflict-detection-and-sync.html) 참조). 활성화되면 `populateIndexFields` 항목 처리도 활성화됩니다. 이 필드는 선택 사항입니다.

**`populateIndexFields`**  
**`customPartitionKey`와 함께** 활성화되면 델타 동기화 테이블, 특히 `gsi_ds_pk` 및 `gsi_ds_sk` 열의 각 레코드에 대해 새 항목을 생성하는 부울 값입니다. 자세한 내용은 **AWS AppSync 개발자 안내서의 [충돌 감지 및 동기화](https://docs.aws.amazon.com/appsync/latest/devguide/conflict-detection-and-sync.html)를 참조하세요. 이 필드는 선택 사항입니다.

DynamoDB에서 삭제된 항목은 자동으로 GraphQL 및 JSON 기본 형식으로 변환되며 매핑 컨텍스트(`$context.result`)에서 사용할 수 있습니다.

DynamoDB 형식 변환에 대한 자세한 내용은 [형식 시스템(응답 매핑)](aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-responses.md)을 참조하세요.

응답 매핑 템플릿에 대한 자세한 내용은 [해석기 매핑 템플릿 개요](resolver-mapping-template-reference-overview.md#aws-appsync-resolver-mapping-template-reference-overview)를 참조하세요.

## 예제 1.
<a name="id6"></a>

다음 예제는 GraphQL 변형 `deleteItem(id: ID!)`의 매핑 템플릿입니다. 이 ID를 가진 항목이 있으면 해당 항목은 삭제됩니다.

```
{
    "version" : "2017-02-28",
    "operation" : "DeleteItem",
    "key" : {
        "id" : $util.dynamodb.toDynamoDBJson($ctx.args.id)
    }
}
```

## 예제 2.
<a name="id7"></a>

다음 예제는 GraphQL 변형 `deleteItem(id: ID!, expectedVersion: Int!)`의 매핑 템플릿입니다. 이 ID를 가진 항목이 있으면 해당 항목은 `version` 필드가 `expectedVersion`으로 설정된 경우에만 삭제됩니다.

```
{
    "version" : "2017-02-28",
    "operation" : "DeleteItem",
    "key" : {
        "id" : $util.dynamodb.toDynamoDBJson($ctx.args.id)
    },
    "condition" : {
        "expression"       : "attribute_not_exists(id) OR version = :expectedVersion",
        "expressionValues" : {
            ":expectedVersion" : $util.dynamodb.toDynamoDBJson($expectedVersion)
        }
    }
}
```

DynamoDB `DeleteItem` API에 대한 자세한 내용은 [DynamoDB API 문서](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_DeleteItem.html)를 참조하십시오.

# Query
<a name="aws-appsync-resolver-mapping-template-reference-dynamodb-query"></a>

`Query` 요청 매핑 문서를 사용하면 AWS AppSync DynamoDB 해석기에 DynamoDB에 `Query` 요청하도록 지시하고 다음을 지정할 수 있습니다.
+ 키 표현식
+ 사용할 인덱스
+ 모든 추가 필터
+ 반환할 항목 수
+ 일관된 읽기를 사용할지 여부
+ 쿼리 방향(앞으로 또는 뒤로)
+ 페이지 매김 토큰입니다

`Query` 매핑 문서의 구조는 다음과 같습니다.

```
{
    "version" : "2017-02-28",
    "operation" : "Query",
    "query" : {
        "expression" : "some expression",
        "expressionNames" : {
            "#foo" : "foo"
        },
        "expressionValues" : {
            ":bar" : ... typed value
        }
    },
    "index" : "fooIndex",
    "nextToken" : "a pagination token",
    "limit" : 10,
    "scanIndexForward" : true,
    "consistentRead" : false,
    "select" : "ALL_ATTRIBUTES" | "ALL_PROJECTED_ATTRIBUTES" | "SPECIFIC_ATTRIBUTES",
    "filter" : {
        ...
    },
    "projection" : {
        ...
    }
}
```

필드는 다음과 같이 정의됩니다.

## 쿼리 필드
<a name="query-list"></a>

### 쿼리 필드 목록
<a name="query-list-col"></a>

** `version` **  
템플릿 정의 버전. `2017-02-28` 및 `2018-05-29`만 현재 지원됩니다. 이 값은 필수입니다.

** `operation` **  
수행할 DynamoDB 작업입니다. `Query` DynamoDB 작업을 수행하려면 이 값을 `Query`으로 설정해야 합니다. 이 값은 필수입니다.

** `query` **  
`query` 섹션에서는 DynamoDB에서 가져올 항목을 설명하는 키 조건 표현식을 지정할 수 있습니다. 키 조건 표현식을 작성하는 방법에 대한 자세한 내용은 [DynamoDB KeyConditions 문서](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LegacyConditionalParameters.KeyConditions.html)를 참조하십시오. 이 섹션은 지정되어 있어야 합니다.    
** `expression` **  
쿼리 표현식. 이 필드는 지정되어 있어야 합니다.  
** `expressionNames` **  
표현식 속성 *name* 자리 표시자의 대체 항목으로, 키-값 페어의 형식으로 표시됩니다. 키는 `expression`에 사용된 name 자리 표시자에 해당하고 값은 DynamoDB에 있는 항목의 속성 이름에 해당하는 문자열이어야 합니다. 이 필드는 선택 사항으로, `expression`에 사용된 표현식 속성인 name 자리 표시자의 대체 항목으로만 채워져야 합니다.  
** `expressionValues` **  
표현식 속성 *value* 자리 표시자의 대체 항목으로, 키-값 페어의 형식으로 표시됩니다. 키는 `expression`에 사용되는 value 자리 표시자에 해당하고 값은 입력된 값이어야 합니다. '입력된 값'을 지정하는 방법에 대한 자세한 내용은 [유형 시스템(요청 매핑)](aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-request.md)을 참조하세요. 이 값은 필수입니다. 이 필드는 선택 사항으로, `expression`에 사용된 표현식 속성인 value 자리 표시자의 대체 항목으로만 채워져야 합니다.

** `filter` **  
반환되기 전 DynamoDB의 결과를 필터링하는 데 사용할 수 있는 추가 필터입니다. 필터에 대한 자세한 내용은 [필터](aws-appsync-resolver-mapping-template-reference-dynamodb-filter.md)를 참조하십시오. 이 필드는 선택 사항입니다.

** `index` **  
쿼리할 인덱스의 이름. DynamoDB 쿼리 작업을 사용하면 해시 키의 프라이머리 키 인덱스 이외에 로컬 보조 인덱스 및 글로벌 보조 인덱스를 검사할 수 있습니다. 지정하면 이 값은 DynamoDB에 지정한 인덱스를 쿼리하라고 지시합니다. 이 값을 생략하면 기본 키 인덱스가 쿼리됩니다.

** `nextToken` **  
이전 쿼리를 지속하는 페이지 매김 토큰. 이 토큰은 이전 쿼리에서 얻습니다. 이 필드는 선택 사항입니다.

** `limit` **  
평가할 최대 항목 수입니다(반드시 일치하는 항목 수는 아님). 이 필드는 선택 사항입니다.

** `scanIndexForward` **  
앞으로 또는 뒤로 쿼리할지 여부를 나타내는 부울. 이 필드는 선택 사항으로, 기본값은 `true`입니다.

** `consistentRead` **  
DynamoDB 쿼리 시 일관된 읽기를 사용할지 여부를 나타내는 부울. 이 필드는 선택 사항으로, 기본값은 `false`입니다.

** `select` **  
기본적으로 AWS AppSync DynamoDB 해석기는 인덱스로 프로젝션된 속성만 반환합니다. 추가 속성이 필요한 경우 이 필드를 설정할 수 있습니다. 이 필드는 선택 사항입니다. 지원되는 값은 다음과 같습니다.    
** `ALL_ATTRIBUTES` **  
지정한 테이블 또는 인덱스에서 항목 속성을 모두 반환합니다. 로컬 보조 인덱스를 쿼리하는 경우 DynamoDB는 인덱스의 일치하는 각 항목에 대해 상위 테이블의 전체 항목을 가져옵니다. 인덱스가 모든 항목 속성을 프로젝션하도록 구성된 경우, 모든 데이터를 로컬의 보조 인덱스에서 얻을 수 있기 때문에 가져올 필요가 없습니다.  
** `ALL_PROJECTED_ATTRIBUTES` **  
인덱스를 쿼리하는 경우에만 허용됩니다. 인덱스로 프로젝션된 모든 속성을 가져옵니다. 모든 속성을 프로젝션하도록 인덱스가 구성된 경우 이 반환 값은 `ALL_ATTRIBUTES`를 지정하는 것과 동일합니다.  
**`SPECIFIC_ATTRIBUTES`**  
`projection`의 `expression`에 나열된 속성만 반환합니다. 이 반환 값은 `Select`에 대한 값을 지정하지 않고 `projection`의 `expression`을 지정하는 것과 같습니다.

**`projection`**  
DynamoDB 작업에서 반환할 속성을 지정하는 데 사용되는 프로젝션입니다. 프로젝션에 대한 자세한 내용은 [프로젝션](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-dynamodb.html#aws-appsync-resolver-mapping-template-reference-dynamodb-projections)을 참조하세요. 이 필드는 선택 사항입니다.

DynamoDB의 결과는 자동으로 GraphQL 및 JSON 기본 형식으로 변환되며 매핑 컨텍스트(`$context.result`)에서 사용할 수 있습니다.

DynamoDB 형식 변환에 대한 자세한 내용은 [형식 시스템(응답 매핑)](aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-responses.md)을 참조하세요.

응답 매핑 템플릿에 대한 자세한 내용은 [해석기 매핑 템플릿 개요](resolver-mapping-template-reference-overview.md#aws-appsync-resolver-mapping-template-reference-overview)를 참조하세요.

결과의 구조는 다음과 같습니다.

```
{
    items = [ ... ],
    nextToken = "a pagination token",
    scannedCount = 10
}
```

필드는 다음과 같이 정의됩니다.

** `items` **  
DynamoDB 쿼리에서 반환하는 항목이 포함된 목록.

** `nextToken` **  
더 많은 결과가 있을 수 있는 경우 `nextToken`에는 다른 요청에 사용할 수 있는 페이지 매김 토큰이 포함됩니다. 참고로 AWS AppSync는 DynamoDB에서 반환된 페이지 매김 토큰을 암호화하고 난독화합니다. 따라서 테이블 데이터가 호출자에게 실수로 유출되는 일이 없습니다. 페이지 매김 토큰은 여러 해석기 간에 사용할 수 없습니다.

** `scannedCount` **  
필터 표현식(있는 경우)을 적용하기 전에 쿼리 조건 표현식과 일치했던 항목 수

## 예제
<a name="id9"></a>

다음 예제는 GraphQL 쿼리 `getPosts(owner: ID!)`의 매핑 템플릿입니다.

이 예에서는 테이블의 글로벌 보조 인덱스를 쿼리해 지정한 ID가 소유한 게시물을 모두 반환합니다.

```
{
    "version" : "2017-02-28",
    "operation" : "Query",
    "query" : {
        "expression" : "ownerId = :ownerId",
        "expressionValues" : {
            ":ownerId" : $util.dynamodb.toDynamoDBJson($context.arguments.owner)
        }
    },
    "index" : "owner-index"
}
```

DynamoDB `Query` API에 대한 자세한 내용은 [DynamoDB API 문서](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html)를 참조하십시오.

# 스캔
<a name="aws-appsync-resolver-mapping-template-reference-dynamodb-scan"></a>

`Scan` 요청 매핑 문서를 사용하면 AWS AppSync DynamoDB 해석기에 DynamoDB에 `Scan` 요청하도록 지시하고 다음을 지정할 수 있습니다.
+ 결과를 제외하는 필터
+ 사용할 인덱스
+ 반환할 항목 수
+ 일관된 읽기를 사용할지 여부
+ 페이지 매김 토큰입니다
+ 병렬 스캔

`Scan` 매핑 문서의 구조는 다음과 같습니다.

```
{
    "version" : "2017-02-28",
    "operation" : "Scan",
    "index" : "fooIndex",
    "limit" : 10,
    "consistentRead" : false,
    "nextToken" : "aPaginationToken",
    "totalSegments" : 10,
    "segment" : 1,
    "filter" : {
        ...
    },
    "projection" : {
        ...
    }
}
```

필드는 다음과 같이 정의됩니다.

## Scan 필드
<a name="scan-list"></a>

### Scan 필드 목록
<a name="scan-list-col"></a>

** `version` **  
템플릿 정의 버전. `2017-02-28` 및 `2018-05-29`만 현재 지원됩니다. 이 값은 필수입니다.

** `operation` **  
수행할 DynamoDB 작업입니다. `Scan` DynamoDB 작업을 수행하려면 이 값을 `Scan`으로 설정해야 합니다. 이 값은 필수입니다.

** `filter` **  
반환되기 전 DynamoDB의 결과를 필터링하는 데 사용할 수 있는 필터. 필터에 대한 자세한 내용은 [필터](aws-appsync-resolver-mapping-template-reference-dynamodb-filter.md)를 참조하십시오. 이 필드는 선택 사항입니다.

** `index` **  
쿼리할 인덱스의 이름. DynamoDB 쿼리 작업을 사용하면 해시 키의 프라이머리 키 인덱스 이외에 로컬 보조 인덱스 및 글로벌 보조 인덱스를 검사할 수 있습니다. 지정하면 이 값은 DynamoDB에 지정한 인덱스를 쿼리하라고 지시합니다. 이 값을 생략하면 기본 키 인덱스가 쿼리됩니다.

** `limit` **  
한 번에 평가올 수 있는 최대 항목 수입니다. 이 필드는 선택 사항입니다.

** `consistentRead` **  
DynamoDB 쿼리 시 일관된 읽기를 사용할지 여부를 나타내는 부울. 이 필드는 선택 사항으로, 기본값은 `false`입니다.

** `nextToken` **  
이전 쿼리를 지속하는 페이지 매김 토큰. 이 토큰은 이전 쿼리에서 얻습니다. 이 필드는 선택 사항입니다.

** `select` **  
기본적으로 AWS AppSync DynamoDB 해석기는 인덱스로 프로젝션되는 속성만 반환합니다. 추가 속성이 필요한 경우 이 필드를 설정할 수 있습니다. 이 필드는 선택 사항입니다. 지원되는 값은 다음과 같습니다.    
** `ALL_ATTRIBUTES` **  
지정한 테이블 또는 인덱스에서 항목 속성을 모두 반환합니다. 로컬 보조 인덱스를 쿼리하는 경우 DynamoDB는 인덱스의 일치하는 각 항목에 대해 상위 테이블의 전체 항목을 가져옵니다. 인덱스가 모든 항목 속성을 프로젝션하도록 구성된 경우, 모든 데이터를 로컬의 보조 인덱스에서 얻을 수 있기 때문에 가져올 필요가 없습니다.  
** `ALL_PROJECTED_ATTRIBUTES` **  
인덱스를 쿼리하는 경우에만 허용됩니다. 인덱스로 프로젝션된 모든 속성을 가져옵니다. 모든 속성을 프로젝션하도록 인덱스가 구성된 경우 이 반환 값은 `ALL_ATTRIBUTES`를 지정하는 것과 동일합니다.  
**`SPECIFIC_ATTRIBUTES`**  
`projection`의 `expression`에 나열된 속성만 반환합니다. 이 반환 값은 `Select`에 대한 값을 지정하지 않고 `projection`의 `expression`을 지정하는 것과 같습니다.

** `totalSegments` **  
병렬 스캔을 수행할 때 테이블을 분할할 기준이 될 세그먼트 수. 이 필드는 선택 사항이지만 `segment`가 지정된 경우에는 반드시 지정해야 합니다.

** `segment` **  
병렬 스캔을 수행할 때 작업의 테이블 세그먼트. 이 필드는 선택 사항이지만 `totalSegments`가 지정된 경우에는 반드시 지정해야 합니다.

**`projection`**  
DynamoDB 작업에서 반환할 속성을 지정하는 데 사용되는 프로젝션입니다. 프로젝션에 대한 자세한 내용은 [프로젝션](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-dynamodb.html#aws-appsync-resolver-mapping-template-reference-dynamodb-projections)을 참조하세요. 이 필드는 선택 사항입니다.

DynamoDB 스캔에서 반환하는 결과는 자동으로 GraphQL 및 JSON 기본 형식으로 변환되며 매핑 컨텍스트(`$context.result`)에서 사용할 수 있습니다.

DynamoDB 형식 변환에 대한 자세한 내용은 [형식 시스템(응답 매핑)](aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-responses.md)을 참조하세요.

응답 매핑 템플릿에 대한 자세한 내용은 [해석기 매핑 템플릿 개요](resolver-mapping-template-reference-overview.md#aws-appsync-resolver-mapping-template-reference-overview)를 참조하세요.

결과의 구조는 다음과 같습니다.

```
{
    items = [ ... ],
    nextToken = "a pagination token",
    scannedCount = 10
}
```

필드는 다음과 같이 정의됩니다.

** `items` **  
DynamoDB 스캔에서 반환하는 항목이 포함된 목록

** `nextToken` **  
결과가 더 있을 수 있는 경우 에는 다른 요청에 사용할 수 있는 페이지 매김 토큰이 `nextToken` 포함되어 있습니다. AWS AppSync는 DynamoDB에서 반환된 페이지 매김 토큰을 암호화하고 난독화합니다. 따라서 테이블 데이터가 호출자에게 실수로 유출되는 일이 없습니다. 또한 페이지 매김 토큰은 여러 해석기 간에 사용할 수 없습니다.

** `scannedCount` **  
필터 표현식(있는 경우)을 적용하기 전에 DynamoDB에서 검색한 항목 수.

## 예제 1.
<a name="id11"></a>

다음 예제는 GraphQL 쿼리 `allPosts`의 매핑 템플릿입니다.

이 예에서는 테이블의 항목을 모두 반환합니다.

```
{
    "version" : "2017-02-28",
    "operation" : "Scan"
}
```

## 예제 2.
<a name="id12"></a>

다음 예제는 GraphQL 쿼리 `postsMatching(title: String!)`의 매핑 템플릿입니다.

이 예에서는 제목이 `title` 인수로 시작하는 경우 테이블의 모든 항목이 반환됩니다.

```
{
    "version" : "2017-02-28",
    "operation" : "Scan",
    "filter" : {
        "expression" : "begins_with(title, :title)",
        "expressionValues" : {
            ":title" : $util.dynamodb.toDynamoDBJson($context.arguments.title)
        },
    }
}
```

DynamoDB `Scan` API에 대한 자세한 내용은 [DynamoDB API 문서](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Scan.html)를 참조하십시오.

# 동기화
<a name="aws-appsync-resolver-mapping-template-reference-dynamodb-sync"></a>

`Sync` 요청 매핑 문서를 사용하면 DynamoDB 테이블에서 모든 결과를 가져온 다음, 마지막 쿼리(델타 업데이트) 이후에 변경된 데이터만 수신할 수 있습니다. `Sync` 요청은 버전이 지정된 DynamoDB 데이터 소스에만 수행할 수 있습니다. 다음을 지정할 수 있습니다.
+ 결과를 제외하는 필터
+ 반환할 항목 수
+ 페이지 매김 토큰
+ 마지막 `Sync` 작업이 시작된 경우

`Sync` 매핑 문서의 구조는 다음과 같습니다.

```
{
    "version" : "2018-05-29",
    "operation" : "Sync",
    "basePartitionKey": "Base Tables PartitionKey",
    "deltaIndexName": "delta-index-name",
    "limit" : 10,
    "nextToken" : "aPaginationToken",
    "lastSync" :  1550000000000,
    "filter" : {
        ...
    }
}
```

필드는 다음과 같이 정의됩니다.

## Sync 필드
<a name="sync-list"></a>

### Sync 필드 목록
<a name="sync-list-col"></a>

** `version` **  
템플릿 정의 버전. 현재 `2018-05-29`만 지원됩니다. 이 값은 필수입니다.

** `operation` **  
수행할 DynamoDB 작업입니다. `Sync` 작업을 수행하려면 이 값을 `Sync`으로 설정해야 합니다. 이 값은 필수입니다.

** `filter` **  
반환되기 전 DynamoDB의 결과를 필터링하는 데 사용할 수 있는 필터. 필터에 대한 자세한 내용은 [필터](aws-appsync-resolver-mapping-template-reference-dynamodb-filter.md)를 참조하십시오. 이 필드는 선택 사항입니다.

** `limit` **  
한 번에 평가올 수 있는 최대 항목 수입니다. 이 필드는 선택 사항입니다. 생략된 경우, 기본 제한이 `100`개 항목으로 설정됩니다. 이 필드의 최대값은 `1000`개 항목입니다.

** `nextToken` **  
이전 쿼리를 지속하는 페이지 매김 토큰. 이 토큰은 이전 쿼리에서 얻습니다. 이 필드는 선택 사항입니다.

** `lastSync` **  
마지막으로 성공한 `Sync` 작업이 시작되었던 시간(epoch 밀리초)입니다. 지정된 경우, `lastSync` 이후에 변경된 항목만 반환됩니다. 이 필드는 선택 사항이며 초기 `Sync` 작업에서 모든 페이지를 가져온 이후에만 채워져야 합니다. 생략된 경우, *기본* 테이블의 결과가 반환되고, 그렇지 않으면 *델타* 테이블의 결과가 반환됩니다.

**`basePartitionKey`**  
`Sync` 작업을 수행할 때 사용되는 *기본* 테이블의 파티션 키입니다. 이 필드를 사용하면 테이블에서 사용자 지정 파티션 키를 활용할 때 `Sync` 작업을 수행할 수 있습니다. 이 필드는 선택 사항입니다.

**`deltaIndexName`**  
`Sync` 작업에 사용되는 인덱스. 이 인덱스는 테이블에서 사용자 지정 파티션 키를 사용할 때 전체 델타 저장소 테이블에서 `Sync` 작업을 활성화하는 데 필요합니다. `Sync` 작업은 GSI(`gsi_ds_pk` 및 `gsi_ds_sk`에서 생성)에서 수행됩니다. 이 필드는 선택 사항입니다.

DynamoDB 동기화에서 반환하는 결과는 자동으로 GraphQL 및 JSON 기본 형식으로 변환되며 매핑 컨텍스트(`$context.result`)에서 사용할 수 있습니다.

DynamoDB 형식 변환에 대한 자세한 내용은 [형식 시스템(응답 매핑)](aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-responses.md)을 참조하세요.

응답 매핑 템플릿에 대한 자세한 내용은 [해석기 매핑 템플릿 개요](resolver-mapping-template-reference-overview.md#aws-appsync-resolver-mapping-template-reference-overview)를 참조하세요.

결과의 구조는 다음과 같습니다.

```
{
    items = [ ... ],
    nextToken = "a pagination token",
    scannedCount = 10,
    startedAt = 1550000000000
}
```

필드는 다음과 같이 정의됩니다.

** `items` **  
동기화에서 반환하는 항목이 포함된 목록.

** `nextToken` **  
결과가 더 있을 수 있는 경우 에는 다른 요청에 사용할 수 있는 페이지 매김 토큰이 `nextToken` 포함되어 있습니다. AWS AppSync는 DynamoDB에서 반환된 페이지 매김 토큰을 암호화하고 난독화합니다. 따라서 테이블 데이터가 호출자에게 실수로 유출되는 일이 없습니다. 또한 페이지 매김 토큰은 여러 해석기 간에 사용할 수 없습니다.

** `scannedCount` **  
필터 표현식(있는 경우)을 적용하기 전에 DynamoDB에서 검색한 항목 수.

** `startedAt` **  
로컬로 저장하고 다른 요청에 `lastSync` 인수로 사용할 수 있는 동기화 작업이 시작된 시간(Epoch 밀리초)입니다. 페이지 매김 토큰이 요청에 포함된 경우, 이 값은 결과의 첫 페이지에 대한 요청에 의해 반환된 값과 동일합니다.

## 예제
<a name="id14"></a>

다음 예제는 GraphQL 쿼리 `syncPosts(nextToken: String, lastSync: AWSTimestamp)`의 매핑 템플릿입니다.

이 예에서 `lastSync`가 생략된 경우, 기본 테이블의 모든 항목이 반환됩니다. `lastSync`가 제공된 경우 `lastSync` 이후 변경된 델타 동기화 테이블의 항목만 반환됩니다.

```
{
    "version" : "2018-05-29",
    "operation" : "Sync",
    "limit": 100,
    "nextToken": $util.toJson($util.defaultIfNull($ctx.args.nextToken, null)),
    "lastSync": $util.toJson($util.defaultIfNull($ctx.args.lastSync, null))
}
```

# BatchGetItem
<a name="aws-appsync-resolver-mapping-template-reference-dynamodb-batch-get-item"></a>

`BatchGetItem` 요청 매핑 문서를 사용하면 AWS AppSync DynamoDB 해석기에 DynamoDB에 `BatchGetItem` 요청하여 잠재적으로 여러 테이블에서 여러 항목을 검색하도록 지시할 수 있습니다. 이 요청 템플릿에 대해 다음을 지정해야 합니다.
+ 항목을 가져올 테이블 이름
+ 각 테이블에서 가져올 항목의 키

DynamoDB `BatchGetItem` 한도가 적용되고 **표현식 없음**이 제공될 수 있습니다.

`BatchGetItem` 매핑 문서의 구조는 다음과 같습니다.

```
{
    "version" : "2018-05-29",
    "operation" : "BatchGetItem",
    "tables" : {
        "table1": {
           "keys": [
              ## Item to retrieve Key
              {
                   "foo" : ... typed value,
                   "bar" : ... typed value
              },
              ## Item2 to retrieve Key
              {
                   "foo" : ... typed value,
                   "bar" : ... typed value
              }
            ],
            "consistentRead": true|false,            
            "projection" : {
                 ...
            }
        },
        "table2": {
           "keys": [
              ## Item3 to retrieve Key
              {
                   "foo" : ... typed value,
                   "bar" : ... typed value
              },
              ## Item4 to retrieve Key
              {
                   "foo" : ... typed value,
                   "bar" : ... typed value
              }
            ],
            "consistentRead": true|false,
            "projection" : {
                 ...
            }
        }
    }
}
```

필드는 다음과 같이 정의됩니다.

## BatchGetItem 필드
<a name="BatchGetItem-list"></a>

### BatchGetItem 필드 목록
<a name="BatchGetItem-list-col"></a>

** `version` **  
템플릿 정의 버전. `2018-05-29`만 지원됩니다. 이 값은 필수입니다.

** `operation` **  
수행할 DynamoDB 작업입니다. `BatchGetItem` DynamoDB 작업을 수행하려면 이 값을 `BatchGetItem`으로 설정해야 합니다. 이 값은 필수입니다.

** `tables` **  
항목을 가져올 DynamoDB 테이블입니다. 이 값은 테이블 이름이 맵의 키로 지정되는 맵입니다. 테이블이 하나 이상 제공되어야 합니다. 이 `tables` 값은 필수입니다.    
** `keys` **  
검색할 항목의 프라이머리 키를 나타내는 DynamoDB 키 목록입니다. DynamoDB 항목은 테이블 구조에 따라 단일 해시 키 또는 해시 키와 정렬 키를 가질 수 있습니다. '입력된 값'을 지정하는 방법에 대한 자세한 내용은 [유형 시스템(요청 매핑)](aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-request.md)을 참조하세요.  
** `consistentRead` **  
*GetItem* 작업을 실행할 때 일관된 읽기를 사용할지 여부. 이 값은 선택 사항으로, 기본값은 *false*입니다.  
**`projection`**  
DynamoDB 작업에서 반환할 속성을 지정하는 데 사용되는 프로젝션입니다. 프로젝션에 대한 자세한 내용은 [프로젝션](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-dynamodb.html#aws-appsync-resolver-mapping-template-reference-dynamodb-projections)을 참조하세요. 이 필드는 선택 사항입니다.

기억해야 할 내용:
+ 테이블에서 항목을 가져오지 못하면 해당 테이블의 데이터 블록에 *null* 요소가 나타납니다.
+ 호출 결과는 요청 매핑 템플릿 내에 제공된 순서에 따라 테이블별로 정렬됩니다.
+ `BatchGetItem` 내부의 각 `Get` 명령은 원자성이지만 배치는 부분적으로 처리될 수 있습니다. 오류로 인해 배치가 부분적으로 처리된 경우 처리되지 않은 키는 *unprocessedKeys* 블록 내에 호출 결과의 일부로 반환됩니다.
+  `BatchGetItem`은 100개의 키로 제한됩니다.

다음과 같은 요청 매핑 템플릿 예제가 있습니다.

```
{
  "version": "2018-05-29",
  "operation": "BatchGetItem",
  "tables": {
    "authors": [
        {
          "author_id": {
            "S": "a1"
          }
        },
    ],
    "posts": [
        {
          "author_id": {
            "S": "a1"
          },
          "post_id": {
            "S": "p2"
          }
        }
    ],
  }
}
```

`$ctx.result`에서 사용할 수 있는 호출 결과는 다음과 같습니다.

```
{
   "data": {
     "authors": [null],
     "posts": [
        # Was retrieved
        {
          "author_id": "a1",
          "post_id": "p2",
          "post_title": "title",
          "post_description": "description",
        }
     ]
   },
   "unprocessedKeys": {
     "authors": [
        # This item was not processed due to an error
        {
          "author_id": "a1"
        }
      ],
     "posts": []
   }
}
```

`$ctx.error`에는 오류에 대한 세부 정보가 포함됩니다. 키 **data**, **unprocessedKeys** 및 요청 매핑 템플릿에서 제공된 각 테이블 키는 호출 결과에 표시됩니다. 삭제된 항목은 **데이터** 블록에 나타납니다. 처리되지 않은 항목은 데이터 블록 내에서 *null*로 표시되고 **unprocessedKeys** 블록 내에 배치됩니다.

보다 완벽한 예제를 찾아보려면 [자습서: DynamoDB 배치 해석기](tutorial-dynamodb-batch.md#aws-appsync-tutorial-dynamodb-batch)에서 AppSync 관련 DynamoDB 배치 자습서를 따라해 보세요.

# BatchDeleteItem
<a name="aws-appsync-resolver-mapping-template-reference-dynamodb-batch-delete-item"></a>

`BatchDeleteItem` 요청 매핑 문서를 사용하면 AWS AppSync DynamoDB 해석기에 DynamoDB에 `BatchWriteItem` 요청하여 잠재적으로 여러 테이블에서 여러 항목을 삭제하도록 지시할 수 있습니다. 이 요청 템플릿에 대해 다음을 지정해야 합니다.
+ 항목을 삭제할 테이블 이름
+ 각 테이블에서 삭제할 항목의 키

DynamoDB `BatchWriteItem` 한도가 적용되고 **표현식 없음**이 제공될 수 있습니다.

`BatchDeleteItem` 매핑 문서의 구조는 다음과 같습니다.

```
{
    "version" : "2018-05-29",
    "operation" : "BatchDeleteItem",
    "tables" : {
        "table1": [
        ## Item to delete Key
        {
             "foo" : ... typed value,
             "bar" : ... typed value
        },
        ## Item2 to delete Key
        {
             "foo" : ... typed value,
             "bar" : ... typed value
        }],
        "table2": [
        ## Item3 to delete Key
        {
             "foo" : ... typed value,
             "bar" : ... typed value
        },
        ## Item4 to delete Key
        {
             "foo" : ... typed value,
             "bar" : ... typed value
        }],
    }
}
```

필드는 다음과 같이 정의됩니다.

## BatchDeleteItem 필드
<a name="BatchDeleteItem-list"></a>

### BatchDeleteItem 필드 목록
<a name="BatchDeleteItem-list-col"></a>

** `version` **  
템플릿 정의 버전. `2018-05-29`만 지원됩니다. 이 값은 필수입니다.

** `operation` **  
수행할 DynamoDB 작업입니다. `BatchDeleteItem` DynamoDB 작업을 수행하려면 이 값을 `BatchDeleteItem`으로 설정해야 합니다. 이 값은 필수입니다.

** `tables` **  
항목을 삭제할 DynamoDB 테이블입니다. 각 테이블은 삭제할 항목의 프라이머리 키를 나타내는 DynamoDB 키 목록입니다. DynamoDB 항목은 테이블 구조에 따라 단일 해시 키 또는 해시 키와 정렬 키를 가질 수 있습니다. '입력된 값'을 지정하는 방법에 대한 자세한 내용은 [유형 시스템(요청 매핑)](aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-request.md)을 참조하세요. 테이블이 하나 이상 제공되어야 합니다. `tables` 값이 필요합니다.

기억해야 할 내용:
+ `DeleteItem` 작업과 달리 완전히 삭제된 항목은 응답에서 반환되지 않습니다. 전달된 키만 반환됩니다.
+ 테이블에서 항목을 삭제하지 못하면 해당 테이블의 데이터 블록에 *null* 요소가 나타납니다.
+ 호출 결과는 요청 매핑 템플릿 내에 제공된 순서에 따라 테이블별로 정렬됩니다.
+ `BatchDeleteItem` 내부의 각 `Delete` 명령은 원자성입니다. 그러나 배치는 부분적으로 처리될 수 있습니다. 오류로 인해 배치가 부분적으로 처리된 경우 처리되지 않은 키는 *unprocessedKeys* 블록 내에 호출 결과의 일부로 반환됩니다.
+  `BatchDeleteItem`은 25개의 키로 제한됩니다.
+ 충돌 감지와 함께 사용할 때 이 작업은 지원되지 **않습니다**. 두 가지를 동시에 사용하면 오류가 발생할 수 있습니다.

다음과 같은 요청 매핑 템플릿 예제가 있습니다.

```
{
  "version": "2018-05-29",
  "operation": "BatchDeleteItem",
  "tables": {
    "authors": [
        {
          "author_id": {
            "S": "a1"
          }
        },
    ],
    "posts": [
        {
          "author_id": {
            "S": "a1"
          },
          "post_id": {
            "S": "p2"
          }
        }
    ],
  }
}
```

`$ctx.result`에서 사용할 수 있는 호출 결과는 다음과 같습니다.

```
{
   "data": {
     "authors": [null],
     "posts": [
        # Was deleted
        {
          "author_id": "a1",
          "post_id": "p2"
        }
     ]
   },
   "unprocessedKeys": {
     "authors": [
        # This key was not processed due to an error
        {
          "author_id": "a1"
        }
      ],
     "posts": []
   }
}
```

`$ctx.error`에는 오류에 대한 세부 정보가 포함됩니다. 키 **data**, **unprocessedKeys** 및 요청 매핑 템플릿에서 제공된 각 테이블 키는 호출 결과에 표시됩니다. 삭제된 항목은 **데이터** 블록에 나타납니다. 처리되지 않은 항목은 데이터 블록 내에서 *null*로 표시되고 **unprocessedKeys** 블록 내에 배치됩니다.

보다 완벽한 예제를 찾아보려면 [자습서: DynamoDB 배치 해석기](tutorial-dynamodb-batch.md#aws-appsync-tutorial-dynamodb-batch)에서 AppSync 관련 DynamoDB 배치 자습서를 따라해 보세요.

# BatchPutItem
<a name="aws-appsync-resolver-mapping-template-reference-dynamodb-batch-put-item"></a>

`BatchPutItem` 요청 매핑 문서를 사용하면 AWS AppSync DynamoDB 해석기에 DynamoDB에 `BatchWriteItem` 요청하여 잠재적으로 여러 테이블에 여러 항목을 배치하도록 지시할 수 있습니다. 이 요청 템플릿에 대해 다음을 지정해야 합니다.
+ 항목을 저장할 테이블 이름
+ 각 테이블에 저장할 전체 항목

DynamoDB `BatchWriteItem` 한도가 적용되고 **표현식 없음**이 제공될 수 있습니다.

`BatchPutItem` 매핑 문서의 구조는 다음과 같습니다.

```
{
    "version" : "2018-05-29",
    "operation" : "BatchPutItem",
    "tables" : {
        "table1": [
        ## Item to put
        {
             "foo" : ... typed value,
             "bar" : ... typed value
        },
        ## Item2 to put
        {
             "foo" : ... typed value,
             "bar" : ... typed value
        }],
        "table2": [
        ## Item3 to put
        {
             "foo" : ... typed value,
             "bar" : ... typed value
        },
        ## Item4 to put
        {
             "foo" : ... typed value,
             "bar" : ... typed value
        }],
    }
}
```

필드는 다음과 같이 정의됩니다.

## BatchPutItem 필드
<a name="BatchPutItem-list"></a>

### BatchPutItem 필드 목록
<a name="BatchPutItem-list-col"></a>

** `version` **  
템플릿 정의 버전. `2018-05-29`만 지원됩니다. 이 값은 필수입니다.

** `operation` **  
수행할 DynamoDB 작업입니다. `BatchPutItem` DynamoDB 작업을 수행하려면 이 값을 `BatchPutItem`으로 설정해야 합니다. 이 값은 필수입니다.

** `tables` **  
항목을 넣을 DynamoDB 테이블입니다. 각 테이블 항목은 이 특정 테이블에 삽입할 DynamoDB 항목 목록을 나타냅니다. 테이블이 하나 이상 제공되어야 합니다. 이 값은 필수입니다.

기억해야 할 내용:
+ 성공하면, 완전히 삽입된 항목이 응답에서 반환됩니다.
+ 테이블에 항목이 삽입되지 못하면 해당 테이블의 데이터 블록에 *null* 요소가 표시됩니다.
+ 삽입된 항목은 요청 매핑 템플릿 내에 제공된 순서에 따라 테이블별로 정렬됩니다.
+ `BatchPutItem` 내부의 각 `Put` 명령은 원자성이지만 배치는 부분적으로 처리될 수 있습니다. 오류로 인해 배치가 부분적으로 처리된 경우 처리되지 않은 키는 *unprocessedKeys* 블록 내에 호출 결과의 일부로 반환됩니다.
+  `BatchPutItem`은 25개의 항목으로 제한됩니다.
+ 충돌 감지와 함께 사용할 때 이 작업은 지원되지 **않습니다**. 두 가지를 동시에 사용하면 오류가 발생할 수 있습니다.

다음과 같은 요청 매핑 템플릿 예제가 있습니다.

```
{
  "version": "2018-05-29",
  "operation": "BatchPutItem",
  "tables": {
    "authors": [
        {
          "author_id": {
            "S": "a1"
          },
          "author_name": {
            "S": "a1_name"
          }
        },
    ],
    "posts": [
        {
          "author_id": {
            "S": "a1"
          },
          "post_id": {
            "S": "p2"
          },
          "post_title": {
            "S": "title"
          }
        }
    ],
  }
}
```

`$ctx.result`에서 사용할 수 있는 호출 결과는 다음과 같습니다.

```
{
   "data": {
     "authors": [
         null
     ],
     "posts": [
        # Was inserted
        {
          "author_id": "a1",
          "post_id": "p2",
          "post_title": "title"
        }
     ]
   },
   "unprocessedItems": {
     "authors": [
        # This item was not processed due to an error
        {
          "author_id": "a1",
          "author_name": "a1_name"
        }
      ],
     "posts": []
   }
}
```

`$ctx.error`에는 오류에 대한 세부 정보가 포함됩니다. 키 **data**, **unprocessedItems** 및 요청 매핑 템플릿에서 제공된 각 테이블 키는 호출 결과에 표시됩니다. 삽입된 항목은 **데이터** 블록에 나타납니다. 처리되지 않은 항목은 데이터 블록 내에서 *null*로 표시되고 **unprocessedItems** 블록 내에 배치됩니다.

보다 완벽한 예제를 찾아보려면 [자습서: DynamoDB 배치 해석기](tutorial-dynamodb-batch.md#aws-appsync-tutorial-dynamodb-batch)에서 AppSync 관련 DynamoDB 배치 자습서를 따라해 보세요.

# TransactGetItems
<a name="aws-appsync-resolver-mapping-template-reference-dynamodb-transact-get-items"></a>

`TransactGetItems` 요청 매핑 문서를 사용하면 AWS AppSync DynamoDB 해석기에 DynamoDB에 `TransactGetItems` 요청하여 잠재적으로 여러 테이블에서 여러 항목을 검색하도록 지시할 수 있습니다. 이 요청 템플릿에 대해 다음을 지정해야 합니다.
+ 항목을 가져올 각 요청 항목의 테이블 이름
+ 각 테이블에서 가져올 각 요청 항목의 키

DynamoDB `TransactGetItems` 한도가 적용되고 **표현식 없음**이 제공될 수 있습니다.

`TransactGetItems` 매핑 문서의 구조는 다음과 같습니다.

```
{
    "version": "2018-05-29",
    "operation": "TransactGetItems",
    "transactItems": [
       ## First request item
       {
           "table": "table1",
           "key": {
               "foo": ... typed value,
               "bar": ... typed value
           },
           "projection" : {
                ...
           }
       },
       ## Second request item
       {
           "table": "table2",
           "key": {
               "foo": ... typed value,
               "bar": ... typed value
           },
           "projection" : {
                ...
           }
       }
    ]
}
```

필드는 다음과 같이 정의됩니다.

## TransactGetItems 필드
<a name="TransactGetItems-list"></a>

### TransactGetItems 필드 목록
<a name="TransactGetItems-list-col"></a>

** `version` **  
템플릿 정의 버전. `2018-05-29`만 지원됩니다. 이 값은 필수입니다.

** `operation` **  
수행할 DynamoDB 작업입니다. `TransactGetItems` DynamoDB 작업을 수행하려면 이 값을 `TransactGetItems`으로 설정해야 합니다. 이 값은 필수입니다.

** `transactItems` **  
포함할 요청 항목입니다. 이 값은 요청 항목의 배열입니다. 하나 이상의 요청 항목이 제공되어야 합니다. 이 `transactItems` 값은 필수입니다.    
** `table` **  
항목을 가져올 DynamoDB 테이블입니다. 이 값은 테이블 이름의 문자열입니다. 이 `table` 값은 필수입니다.  
** `key` **  
검색할 항목의 프라이머리 키를 나타내는 DynamoDB 키입니다. DynamoDB 항목은 테이블 구조에 따라 단일 해시 키 또는 해시 키와 정렬 키를 가질 수 있습니다. '입력된 값'을 지정하는 방법에 대한 자세한 내용은 [유형 시스템(요청 매핑)](aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-request.md)을 참조하세요.  
**`projection`**  
DynamoDB 작업에서 반환할 속성을 지정하는 데 사용되는 프로젝션입니다. 프로젝션에 대한 자세한 내용은 [프로젝션](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-dynamodb.html#aws-appsync-resolver-mapping-template-reference-dynamodb-projections)을 참조하세요. 이 필드는 선택 사항입니다.

기억해야 할 내용:
+ 트랜잭션이 성공하면 `items` 블록에서 가져오는 항목의 순서는 요청 항목의 순서와 동일합니다.
+ 트랜잭션은 전부 또는 전무 방식으로 수행됩니다. 요청 항목에 오류가 발생하면 전체 트랜잭션이 수행되지 않고 오류 세부 정보가 반환됩니다.
+ 가져올 수 없는 요청 항목은 오류가 아닙니다. 대신 해당 위치의 *항목* 블록에 *null* 요소가 나타납니다.
+ 트랜잭션의 오류가 *TransactionCanceledException*인 경우 `cancellationReasons` 블록이 채워집니다. `cancellationReasons` 블록 내의 취소 사유 순서는 요청 항목의 순서와 동일합니다.
+  `TransactGetItems`는 100개의 요청 항목으로 제한됩니다.

다음과 같은 요청 매핑 템플릿 예제가 있습니다.

```
{
    "version": "2018-05-29",
    "operation": "TransactGetItems",
    "transactItems": [
       ## First request item
       {
           "table": "posts",
           "key": {
               "post_id": {
                 "S": "p1"
               }
           }
       },
       ## Second request item
       {
           "table": "authors",
           "key": {
               "author_id": {
                 "S": a1
               }
           }
       }
    ]
}
```

트랜잭션이 성공하고 첫 번째 요청된 항목만 검색되는 경우 `$ctx.result`에서 사용할 수 있는 호출 결과는 다음과 같습니다.

```
{
    "items": [
       {
           // Attributes of the first requested item
           "post_id": "p1",
           "post_title": "title",
           "post_description": "description"
       },
       // Could not retrieve the second requested item
       null,
    ],
    "cancellationReasons": null
}
```

첫 번째 요청 항목으로 인한 *TransactionCanceledException* 때문에 트랜잭션이 실패할 경우 `$ctx.result`에서 사용할 수 있는 호출 결과는 다음과 같습니다.

```
{
    "items": null,
    "cancellationReasons": [
       {
           "type":"Sample error type",
           "message":"Sample error message"
       },
       {
           "type":"None",
           "message":"None"
       }
    ]
}
```

`$ctx.error`에는 오류에 대한 세부 정보가 포함됩니다. 키 **항목** 과 **cancellationReasons**는 `$ctx.result`에 있습니다.

보다 완벽한 예제를 찾아보려면 [자습서: DynamoDB 트랜잭션 해석기](tutorial-dynamodb-transact.md#aws-appsync-tutorial-dynamodb-transact)에서 AppSync 관련 DynamoDB 트랜잭션 자습서를 따라해 보세요.

# TransactWriteItems
<a name="aws-appsync-resolver-mapping-template-reference-dynamodb-transact-write-items"></a>

`TransactWriteItems` 요청 매핑 문서를 사용하면 AWS AppSync DynamoDB 해석기에 DynamoDB에 `TransactWriteItems` 요청하여 잠재적으로 여러 테이블에 여러 항목을 쓰도록 지시할 수 있습니다. 이 요청 템플릿에 대해 다음을 지정해야 합니다.
+ 각 요청 항목의 대상 테이블 이름
+ 수행할 각 요청 항목의 작업입니다. 지원되는 작업에는 *PutItem*, *UpdateItem*, *DeleteItem*, *ConditionCheck*의 네 가지 유형이 있습니다.
+ 작성할 각 요청 항목의 키

DynamoDB `TransactWriteItems` 제한이 적용됩니다.

`TransactWriteItems` 매핑 문서의 구조는 다음과 같습니다.

```
{
    "version": "2018-05-29",
    "operation": "TransactWriteItems",
    "transactItems": [
       {
           "table": "table1",
           "operation": "PutItem",
           "key": {
               "foo": ... typed value,
               "bar": ... typed value
           },
           "attributeValues": {
               "baz": ... typed value
           },
           "condition": {
               "expression": "someExpression",
               "expressionNames": {
                   "#foo": "foo"
               },
               "expressionValues": {
                   ":bar": ... typed value
               },
               "returnValuesOnConditionCheckFailure": true|false
           }
       },
       {
           "table":"table2",
           "operation": "UpdateItem",
           "key": {
               "foo": ... typed value,
               "bar": ... typed value
           },
           "update": {
               "expression": "someExpression",
               "expressionNames": {
                   "#foo": "foo"
               },
               "expressionValues": {
                   ":bar": ... typed value
               }
           },
           "condition": {
               "expression": "someExpression",
               "expressionNames": {
                   "#foo":"foo"
               },
               "expressionValues": {
                   ":bar": ... typed value
               },
               "returnValuesOnConditionCheckFailure": true|false
           }
       },
       {
           "table": "table3",
           "operation": "DeleteItem",
           "key":{
               "foo": ... typed value,
               "bar": ... typed value
           },
           "condition":{
               "expression": "someExpression",
               "expressionNames": {
                   "#foo": "foo"
               },
               "expressionValues": {
                   ":bar": ... typed value
               },
               "returnValuesOnConditionCheckFailure": true|false
           }
       },
       {
           "table": "table4",
           "operation": "ConditionCheck",
           "key":{
               "foo": ... typed value,
               "bar": ... typed value
           },
           "condition":{
               "expression": "someExpression",
               "expressionNames": {
                   "#foo": "foo"
               },
               "expressionValues": {
                   ":bar": ... typed value
               },
               "returnValuesOnConditionCheckFailure": true|false
           }
       }
    ]
}
```

## TransactWriteItems 필드
<a name="TransactWriteItems-list"></a>

### TransactWriteItems 필드 목록
<a name="TransactWriteItems-list-col"></a>

**필드는 다음과 같이 정의됩니다.**    
** `version` **  
템플릿 정의 버전. `2018-05-29`만 지원됩니다. 이 값은 필수입니다.  
** `operation` **  
수행할 DynamoDB 작업입니다. `TransactWriteItems` DynamoDB 작업을 수행하려면 이 값을 `TransactWriteItems`으로 설정해야 합니다. 이 값은 필수입니다.  
** `transactItems` **  
포함할 요청 항목입니다. 이 값은 요청 항목의 배열입니다. 하나 이상의 요청 항목이 제공되어야 합니다. 이 `transactItems` 값은 필수입니다.  
`PutItem`의 필드는 다음과 같이 정의됩니다.    
** `table` **  
대상 DynamoDB 테이블입니다. 이 값은 테이블 이름의 문자열입니다. 이 `table` 값은 필수입니다.  
** `operation` **  
수행할 DynamoDB 작업입니다. `PutItem` DynamoDB 작업을 수행하려면 이 값을 `PutItem`으로 설정해야 합니다. 이 값은 필수입니다.  
** `key` **  
입력할 항목의 프라이머리 키를 나타내는 DynamoDB 키입니다. DynamoDB 항목은 테이블 구조에 따라 단일 해시 키 또는 해시 키와 정렬 키를 가질 수 있습니다. '입력된 값'을 지정하는 방법에 대한 자세한 내용은 [유형 시스템(요청 매핑)](aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-request.md)을 참조하세요. 이 값은 필수입니다.  
** `attributeValues` **  
DynamoDB에 저장할 항목의 나머지 속성. '입력된 값'을 지정하는 방법에 대한 자세한 내용은 [유형 시스템(요청 매핑)](aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-request.md)을 참조하세요. 이 필드는 선택 사항입니다.  
** `condition` **  
DynamoDB에 이미 있는 객체의 상태를 기반으로 요청의 성공 여부를 결정하는 조건. 조건을 지정하지 않으면 `PutItem` 요청이 해당 항목에 대한 기존 입력을 덮어씁니다. 조건 검사에 실패할 경우 기존 항목을 다시 가져올지 여부를 지정할 수 있습니다. 트랜잭션 조건에 대한 자세한 내용은 [트랜잭션 조건 표현식](aws-appsync-resolver-mapping-template-reference-dynamodb-transaction-condition-expressions.md)을 참조하세요. 이 값은 선택 사항입니다.
`UpdateItem`의 필드는 다음과 같이 정의됩니다.    
** `table` **  
업데이트할 DynamoDB 테이블입니다. 이 값은 테이블 이름의 문자열입니다. 이 `table` 값은 필수입니다.  
** `operation` **  
수행할 DynamoDB 작업입니다. `UpdateItem` DynamoDB 작업을 수행하려면 이 값을 `UpdateItem`으로 설정해야 합니다. 이 값은 필수입니다.  
** `key` **  
업데이트할 항목의 프라이머리 키를 나타내는 DynamoDB 키입니다. DynamoDB 항목은 테이블 구조에 따라 단일 해시 키 또는 해시 키와 정렬 키를 가질 수 있습니다. '입력된 값'을 지정하는 방법에 대한 자세한 내용은 [유형 시스템(요청 매핑)](aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-request.md)을 참조하세요. 이 값은 필수입니다.  
** `update` **  
`update` 섹션에서는 DynamoDB의 항목 업데이트 방법을 설명하는 업데이트 표현식을 지정합니다. 업데이트 표현식을 작성하는 방법에 대한 자세한 내용은 [DynamoDB UpdateExpressions 문서](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html)를 참조하십시오. 이 섹션은 필수입니다.  
** `condition` **  
DynamoDB에 이미 있는 객체의 상태를 기반으로 요청의 성공 여부를 결정하는 조건. 조건을 지정하지 않으면 `UpdateItem` 요청이 현재 상태와 상관 없이 기존 항목을 업데이트합니다. 조건 검사에 실패할 경우 기존 항목을 다시 가져올지 여부를 지정할 수 있습니다. 트랜잭션 조건에 대한 자세한 내용은 [트랜잭션 조건 표현식](aws-appsync-resolver-mapping-template-reference-dynamodb-transaction-condition-expressions.md)을 참조하세요. 이 값은 선택 사항입니다.
`DeleteItem`의 필드는 다음과 같이 정의됩니다.    
** `table` **  
항목을 삭제할 DynamoDB 테이블입니다. 이 값은 테이블 이름의 문자열입니다. 이 `table` 값은 필수입니다.  
** `operation` **  
수행할 DynamoDB 작업입니다. `DeleteItem` DynamoDB 작업을 수행하려면 이 값을 `DeleteItem`으로 설정해야 합니다. 이 값은 필수입니다.  
** `key` **  
삭제할 항목의 프라이머리 키를 나타내는 DynamoDB 키입니다. DynamoDB 항목은 테이블 구조에 따라 단일 해시 키 또는 해시 키와 정렬 키를 가질 수 있습니다. '입력된 값'을 지정하는 방법에 대한 자세한 내용은 [유형 시스템(요청 매핑)](aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-request.md)을 참조하세요. 이 값은 필수입니다.  
** `condition` **  
DynamoDB에 이미 있는 객체의 상태를 기반으로 요청의 성공 여부를 결정하는 조건. 조건을 지정하지 않으면 `DeleteItem` 요청이 현재 상태와 상관 없이 항목을 삭제합니다. 조건 검사에 실패할 경우 기존 항목을 다시 가져올지 여부를 지정할 수 있습니다. 트랜잭션 조건에 대한 자세한 내용은 [트랜잭션 조건 표현식](aws-appsync-resolver-mapping-template-reference-dynamodb-transaction-condition-expressions.md)을 참조하세요. 이 값은 선택 사항입니다.
`ConditionCheck`의 필드는 다음과 같이 정의됩니다.    
** `table` **  
조건을 검사할 DynamoDB 테이블입니다. 이 값은 테이블 이름의 문자열입니다. 이 `table` 값은 필수입니다.  
** `operation` **  
수행할 DynamoDB 작업입니다. `ConditionCheck` DynamoDB 작업을 수행하려면 이 값을 `ConditionCheck`으로 설정해야 합니다. 이 값은 필수입니다.  
** `key` **  
조건을 확인할 항목의 프라이머리 키를 나타내는 DynamoDB 키입니다. DynamoDB 항목은 테이블 구조에 따라 단일 해시 키 또는 해시 키와 정렬 키를 가질 수 있습니다. '입력된 값'을 지정하는 방법에 대한 자세한 내용은 [유형 시스템(요청 매핑)](aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-request.md)을 참조하세요. 이 값은 필수입니다.  
** `condition` **  
DynamoDB에 이미 있는 객체의 상태를 기반으로 요청의 성공 여부를 결정하는 조건. 조건 검사에 실패할 경우 기존 항목을 다시 가져올지 여부를 지정할 수 있습니다. 트랜잭션 조건에 대한 자세한 내용은 [트랜잭션 조건 표현식](aws-appsync-resolver-mapping-template-reference-dynamodb-transaction-condition-expressions.md)을 참조하세요. 이 값은 필수입니다.

기억해야 할 내용:
+ 성공할 경우 요청 항목의 키만 응답에 반환됩니다. 키 순서는 요청 항목의 순서와 동일합니다.
+ 트랜잭션은 전부 또는 전무 방식으로 수행됩니다. 요청 항목에 오류가 발생하면 전체 트랜잭션이 수행되지 않고 오류 세부 정보가 반환됩니다.
+ 두 개의 요청 항목이 동일한 항목을 대상으로 할 수 없습니다. 그렇지 않으면 *TransactionCanceledException* 오류가 발생합니다.
+ 트랜잭션의 오류가 *TransactionCanceledException*인 경우 `cancellationReasons` 블록이 채워집니다. 요청 항목의 조건 검사에 실패한 **동시에** `returnValuesOnConditionCheckFailure`를 `false`로 지정하지 않은 경우, 테이블에 있는 항목이 검색되고 `item`에서 `cancellationReasons` 블록의 해당 위치에 저장됩니다.
+  `TransactWriteItems`는 100개의 요청 항목으로 제한됩니다.
+ 충돌 감지와 함께 사용할 때 이 작업은 지원되지 **않습니다**. 두 가지를 동시에 사용하면 오류가 발생할 수 있습니다.

다음과 같은 요청 매핑 템플릿 예제가 있습니다.

```
{
    "version": "2018-05-29",
    "operation": "TransactWriteItems",
    "transactItems": [
       {
           "table": "posts",
           "operation": "PutItem",
           "key": {
               "post_id": {
                   "S": "p1"
               }
           },
           "attributeValues": {
               "post_title": {
                   "S": "New title"
               },
               "post_description": {
                   "S": "New description"
               }
           },
           "condition": {
               "expression": "post_title = :post_title",
               "expressionValues": {
                   ":post_title": {
                       "S": "Expected old title"
                   }
               }
           }
       },
       {
           "table":"authors",
           "operation": "UpdateItem",
           "key": {
               "author_id": {
                   "S": "a1"
               },
           },
           "update": {
               "expression": "SET author_name = :author_name",
               "expressionValues": {
                   ":author_name": {
                       "S": "New name"
                   }
               }
           },
       }
    ]
}
```

트랜잭션이 성공하면 `$ctx.result`에서 사용할 수 있는 호출 결과는 다음과 같습니다.

```
{
    "keys": [
       // Key of the PutItem request
       {
           "post_id": "p1",
       },
       // Key of the UpdateItem request
       {
           "author_id": "a1"
       }
    ],
    "cancellationReasons": null
}
```

`PutItem` 요청의 조건 검사 실패로 인해 트랜잭션이 실패할 경우 `$ctx.result`에서 사용할 수 있는 간접 호출 결과는 다음과 같습니다.

```
{
    "keys": null,
    "cancellationReasons": [
       {
           "item": {
               "post_id": "p1",
               "post_title": "Actual old title",
               "post_description": "Old description"
           },
           "type": "ConditionCheckFailed",
           "message": "The condition check failed."
       },
       {
           "type": "None",
           "message": "None"
       }
    ]
}
```

`$ctx.error`에는 오류에 대한 세부 정보가 포함됩니다. **키** 및 **cancellationReasons** 키는 `$ctx.result`에 있습니다.

보다 완벽한 예제를 찾아보려면 [자습서: DynamoDB 트랜잭션 해석기](tutorial-dynamodb-transact.md#aws-appsync-tutorial-dynamodb-transact)에서 AppSync 관련 DynamoDB 트랜잭션 자습서를 따라해 보세요.

# 형식 시스템(요청 매핑)
<a name="aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-request"></a>

 AWS AppSync DynamoDB 해석기를 사용하여 DynamoDB 테이블을 호출하는 경우 AWS AppSync는 해당 호출에 사용할 각 값의 유형을 알아야 합니다. 이는 DynamoDB가 GraphQL 또는 JSON(예: 세트 및 바이너리 데이터)보다 더 많은 유형의 프리미티브를 지원하기 때문입니다. AWS AppSync는 GraphQL과 DynamoDB 간에 변환할 때 몇 가지 힌트가 필요하며, 그렇지 않으면 테이블에서 데이터가 구조화되는 방식을 일부 가정해야 합니다.

DynamoDB 데이터 유형에 대한 자세한 내용은 DynamoDB [데이터 유형 설명자](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Programming.LowLevelAPI.html#Programming.LowLevelAPI.DataTypeDescriptors) 및 [데이터 유형](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.NamingRulesDataTypes.html#HowItWorks.DataTypes) 설명서를 참조하세요.

DynamoDB 값은 단일 키-값 페어가 포함된 JSON 객체로 나타납니다. 여기서 키는 DynamoDB 형식을 지정하고 값은 값 자체를 지정합니다. 다음 예에서 키 `S`는 값이 문자열임을 나타내고 값 `identifier`는 문자열 값 자체를 나타냅니다.

```
{ "S" : "identifier" }
```

JSON 객체는 키-값 페어를 두 개 이상 포함할 수 없습니다. 키-값 페어를 두 개 이상 지정하면 요청 매핑 문서가 구문 분석되지 않습니다.

요청 매핑 문서에서 값을 지정해야 하는 모든 곳에 DynamoDB 값을 사용할 수 있습니다. 이렇게 해야 하는 위치로는 `key` 및 `attributeValue` 섹션과 표현식 섹션 중 `expressionValues` 섹션이 있습니다. 다음 예에서는 DynamoDB 문자열 값 `identifier`를 `key` 섹션(`GetItem` 요청 매핑 문서)의 `id` 필드에 할당합니다.

```
"key" : {
   "id" : { "S" : "identifier" }
}
```

 **지원되는 유형** 

AWS AppSync는 다음과 같은 DynamoDB 스칼라, 문서 및 세트 유형을 지원합니다.

**String 형식 `S` **  
단일 문자열 값. DynamoDB String 값은 다음과 같이 표시됩니다.  

```
{ "S" : "some string" }
```
사용 예제는 다음과 같습니다.  

```
"key" : {
   "id" : { "S" : "some string" }
}
```

**String set 형식 `SS` **  
문자열 값 집합. DynamoDB String Set 값은 다음과 같이 표시됩니다.  

```
{ "SS" : [ "first value", "second value", ... ] }
```
사용 예제는 다음과 같습니다.  

```
"attributeValues" : {
   "phoneNumbers" : { "SS" : [ "+1 555 123 4567", "+1 555 234 5678" ] }
}
```

**Number 형식 `N` **  
단일 숫자 값. DynamoDB Number 값은 다음과 같이 표시됩니다.  

```
{ "N" : 1234 }
```
사용 예제는 다음과 같습니다.  

```
"expressionValues" : {
   ":expectedVersion" : { "N" : 1 }
}
```

**Number set 형식 `NS` **  
숫자 값 집합. DynamoDB Number Set 값은 다음과 같이 표시됩니다.  

```
{ "NS" : [ 1, 2.3, 4 ... ] }
```
사용 예제는 다음과 같습니다.  

```
"attributeValues" : {
   "sensorReadings" : { "NS" : [ 67.8, 12.2, 70 ] }
}
```

**Binary 형식 `B` **  
이진 값. DynamoDB Binary 값은 다음과 같이 표시됩니다.  

```
{ "B" : "SGVsbG8sIFdvcmxkIQo=" }
```
값은 실제로 문자열입니다. 여기서 문자열은 이진 데이터의 base64 인코딩 표현입니다. AWS AppSync는이 문자열을 DynamoDB로 보내기 전에 이진 값으로 다시 디코딩합니다. AWS AppSync는 RFC 2045에 정의된 base64 디코딩 체계를 사용합니다. base64 알파벳에 없는 모든 문자는 무시됩니다.  
사용 예제는 다음과 같습니다.  

```
"attributeValues" : {
   "binaryMessage" : { "B" : "SGVsbG8sIFdvcmxkIQo=" }
}
```

**Binary set 형식 `BS` **  
이진 값 집합. DynamoDB Binary Set 값은 다음과 같이 표시됩니다.  

```
{ "BS" : [ "SGVsbG8sIFdvcmxkIQo=", "SG93IGFyZSB5b3U/Cg==" ... ] }
```
값은 실제로 문자열입니다. 여기서 문자열은 이진 데이터의 base64 인코딩 표현입니다. AWS AppSync는이 문자열을 DynamoDB로 보내기 전에 이진 값으로 다시 디코딩합니다. AWS AppSync는 RFC 2045에 정의된 base64 디코딩 체계를 사용합니다. base64 알파벳에 없는 모든 문자는 무시됩니다.  
사용 예제는 다음과 같습니다.  

```
"attributeValues" : {
   "binaryMessages" : { "BS" : [ "SGVsbG8sIFdvcmxkIQo=", "SG93IGFyZSB5b3U/Cg==" ] }
}
```

**Boolean 형식 `BOOL` **  
부울 값. DynamoDB Boolean 값은 다음과 같이 표시됩니다.  

```
{ "BOOL" : true }
```
`true` 및 `false`만 유효한 값입니다.  
사용 예제는 다음과 같습니다.  

```
"attributeValues" : {
   "orderComplete" : { "BOOL" : false }
}
```

**List 형식 `L` **  
기타 지원되는 DynamoDB 값 목록입니다. DynamoDB List 값은 다음과 같이 표시됩니다.  

```
{ "L" : [ ... ] }
```
값은 복합 값으로, 목록에는 지원되는 DynamoDB 값(다른 목록 포함)이 0개 이상 포함될 수 있습니다. 또한 목록에는 여러 형식이 혼합되어 포함될 수 있습니다.  
사용 예제는 다음과 같습니다.  

```
{ "L" : [
      { "S"  : "A string value" },
      { "N"  : 1 },
      { "SS" : [ "Another string value", "Even more string values!" ] }
   ]
}
```

**Map 형식 `M` **  
지원되는 다른 DynamoDB 값의 키-값 페어로 구성된 순서 없는 모음을 나타냅니다. DynamoDB Map 값은 다음과 같이 표시됩니다.  

```
{ "M" : { ... } }
```
맵에는 키-값 페어가 0개 이상 포함될 수 있습니다. 키는 문자열이어야 하며 값은 지원되는 모든 DynamoDB 값(다른 맵 포함)일 수 있습니다. 또한 맵에는 여러 형식이 혼합되어 포함될 수 있습니다.  
사용 예제는 다음과 같습니다.  

```
{ "M" : {
      "someString" : { "S"  : "A string value" },
      "someNumber" : { "N"  : 1 },
      "stringSet"  : { "SS" : [ "Another string value", "Even more string values!" ] }
   }
}
```

**Null 형식 `NULL` **  
null 값. DynamoDB Null 값은 다음과 같이 표시됩니다.  

```
{ "NULL" : null }
```
사용 예제는 다음과 같습니다.  

```
"attributeValues" : {
   "phoneNumbers" : { "NULL" : null }
}
```

각 형식에 대한 자세한 내용은 [DynamoDB 문서](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.NamingRulesDataTypes.html)를 참조하십시오.

# 형식 시스템(응답 매핑)
<a name="aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-responses"></a>

DynamoDB로부터 응답을 수신하면 AWS AppSync는 자동으로 응답을 GraphQL 및 JSON 기본 유형으로 변환합니다. DynamoDB의 각 속성은 디코딩되어 응답 매핑 컨텍스트에서 반환됩니다.

예를 들어 DynamoDB에서 다음을 반환한 경우:

```
{
    "id" : { "S" : "1234" },
    "name" : { "S" : "Nadia" },
    "age" : { "N" : 25 }
}
```

그런 다음 AWS AppSync DynamoDB 해석기는 이를 GraphQL 및 JSON 유형으로 다음과 같이 변환합니다.

```
{
    "id" : "1234",
    "name" : "Nadia",
    "age" : 25
}
```

이 섹션에서는 AWS AppSync가 다음 DynamoDB 스칼라, 문서 및 세트 유형을 변환하는 방법을 설명합니다.

**String 형식 `S` **  
단일 문자열 값. DynamoDB String 값은 문자열로 반환됩니다.  
예를 들어 DynamoDB에서 다음 DynamoDB String 값을 반환한 경우:  

```
{ "S" : "some string" }
```
AWS AppSync는 이를 문자열로 변환합니다.  

```
"some string"
```

**String set 형식 `SS` **  
문자열 값 집합. DynamoDB String Set 값은 문자열 목록으로 반환됩니다.  
예를 들어 DynamoDB에서 다음 DynamoDB String Set 값을 반환한 경우:  

```
{ "SS" : [ "first value", "second value", ... ] }
```
AWS AppSync는 이를 문자열 목록으로 변환합니다.  

```
[ "+1 555 123 4567", "+1 555 234 5678" ]
```

**Number 형식 `N` **  
단일 숫자 값. DynamoDB Number 값은 숫자로 반환됩니다.  
예를 들어 DynamoDB에서 다음 DynamoDB Number 값을 반환한 경우:  

```
{ "N" : 1234 }
```
AWS AppSync는 이를 숫자로 변환합니다.  

```
1234
```

**Number set 형식 `NS` **  
숫자 값 집합. DynamoDB Number Set 값은 숫자 목록으로 반환됩니다.  
예를 들어 DynamoDB에서 다음 DynamoDB Number Set 값을 반환한 경우:  

```
{ "NS" : [ 67.8, 12.2, 70 ] }
```
AWS AppSync는 이를 숫자 목록으로 변환합니다.  

```
[ 67.8, 12.2, 70 ]
```

**Binary 형식 `B` **  
이진 값. DynamoDB Binary 값은 base64로 표시된 값이 포함된 문자열로 반환됩니다.  
예를 들어 DynamoDB에서 다음 DynamoDB Binary 값을 반환한 경우:  

```
{ "B" : "SGVsbG8sIFdvcmxkIQo=" }
```
AWS AppSync는 값을 base64로 표현한 문자열로 변환합니다.  

```
"SGVsbG8sIFdvcmxkIQo="
```
이진 데이터는 [RFC 4648](https://tools.ietf.org/html/rfc4648) 및 [RFC 2045](https://tools.ietf.org/html/rfc2045)에 지정된 base64 인코딩 체계로 인코딩됩니다.

**Binary set 형식 `BS` **  
이진 값 집합. DynamoDB Binary Set 값은 base64로 표시된 값이 포함된 문자열 목록으로 반환됩니다.  
예를 들어 DynamoDB에서 다음 DynamoDB Binary Set 값을 반환한 경우:  

```
{ "BS" : [ "SGVsbG8sIFdvcmxkIQo=", "SG93IGFyZSB5b3U/Cg==" ... ] }
```
AWS AppSync는 값을 base64로 표현한 문자열 목록으로 변환합니다.  

```
[ "SGVsbG8sIFdvcmxkIQo=", "SG93IGFyZSB5b3U/Cg==" ... ]
```
이진 데이터는 [RFC 4648](https://tools.ietf.org/html/rfc4648) 및 [RFC 2045](https://tools.ietf.org/html/rfc2045)에 지정된 base64 인코딩 체계로 인코딩됩니다.

**Boolean 형식 `BOOL` **  
부울 값. DynamoDB Boolean 값은 부울로 반환됩니다.  
예를 들어 DynamoDB에서 다음 DynamoDB Boolean 값을 반환한 경우:  

```
{ "BOOL" : true }
```
AWS AppSync는 이를 부울로 변환합니다.  

```
true
```

**List 형식 `L` **  
기타 지원되는 DynamoDB 값 목록입니다. DynamoDB List 값은 값 목록으로 반환되며, 여기서 각 내부 값 역시 변환됩니다.  
예를 들어 DynamoDB에서 다음 DynamoDB List 값을 반환한 경우:  

```
{ "L" : [
      { "S"  : "A string value" },
      { "N"  : 1 },
      { "SS" : [ "Another string value", "Even more string values!" ] }
   ]
}
```
AWS AppSync는 변환된 값 목록으로 변환합니다.  

```
[ "A string value", 1, [ "Another string value", "Even more string values!" ] ]
```

**Map 형식 `M` **  
지원되는 기타 모든 DynamoDB 값의 키/값 모음입니다. DynamoDB Map 값은 JSON 객체로 반환되며, 여기서 각 키/값 역시 변환됩니다.  
예를 들어 DynamoDB에서 다음 DynamoDB Map 값을 반환한 경우:  

```
{ "M" : {
      "someString" : { "S"  : "A string value" },
      "someNumber" : { "N"  : 1 },
      "stringSet"  : { "SS" : [ "Another string value", "Even more string values!" ] }
   }
}
```
AWS AppSync는 이를 JSON 객체로 변환합니다.  

```
{
   "someString" : "A string value",
   "someNumber" : 1,
   "stringSet"  : [ "Another string value", "Even more string values!" ]
}
```

**Null 형식 `NULL` **  
null 값.  
예를 들어 DynamoDB에서 다음 DynamoDB Null 값을 반환한 경우:  

```
{ "NULL" : null }
```
AWS AppSync는 이를 null로 변환합니다.  

```
null
```

# 필터
<a name="aws-appsync-resolver-mapping-template-reference-dynamodb-filter"></a>

`Query` 및 `Scan` 작업을 사용하여 DynamoDB에서 객체를 쿼리하는 경우, 결과를 평가해 원하는 값만 반환하는 `filter`를 선택적으로 지정할 수 있습니다.

`Query` 또는 `Scan` 매핑 문서의 필터 매핑 섹션의 구조는 다음과 같습니다.

```
"filter" : {
    "expression" : "filter expression"
    "expressionNames" : {
        "#name" : "name",
    },
    "expressionValues" : {
        ":value" : ... typed value
    },
}
```

필드는 다음과 같이 정의됩니다.

** `expression` **  
쿼리 표현식. 필터 표현식을 작성하는 방법에 대한 자세한 내용은 [DynamoDB QueryFilter](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LegacyConditionalParameters.QueryFilter.html) 및 [DynamoDB ScanFilter](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LegacyConditionalParameters.ScanFilter.html) 문서를 참조하십시오. 이 필드는 지정되어 있어야 합니다.

** `expressionNames` **  
표현식 속성 *name* 자리 표시자의 대체 항목으로, 키-값 페어의 형식으로 표시됩니다. 키는 `expression`에 사용된 이름 자리 표시자에 해당합니다. 이 값은 DynamoDB에서 항목의 속성 이름에 해당하는 문자열이어야 합니다. 이 필드는 선택 사항으로, `expression`에 사용된 표현식 속성인 name 자리 표시자의 대체 항목으로만 채워져야 합니다.

** `expressionValues` **  
표현식 속성 *value* 자리 표시자의 대체 항목으로, 키-값 페어의 형식으로 표시됩니다. 키는 `expression`에 사용되는 value 자리 표시자에 해당하고 값은 입력된 값이어야 합니다. ‘입력된 값’을 지정하는 방법에 대한 자세한 내용은 [형식 시스템(요청 매핑)](aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-request.md)을 참조하십시오. 입력된 값은 지정되어 있어야 합니다. 이 필드는 선택 사항으로, `expression`에 사용된 표현식 속성인 value 자리 표시자의 대체 항목으로만 채워져야 합니다.

## 예제
<a name="id18"></a>

다음 예제는 매핑 템플릿의 필터 섹션으로, 여기서 DynamoDB에서 가져온 항목은 제목이 `title` 인수로 시작되는 경우에만 반환됩니다.

```
"filter" : {
    "expression" : "begins_with(#title, :title)",
    "expressionNames" : {
        "#title" : "title"
    },
    "expressionValues" : {
        ":title" : $util.dynamodb.toDynamoDBJson($context.arguments.title)
    }
}
```

# 조건 표현식
<a name="aws-appsync-resolver-mapping-template-reference-dynamodb-condition-expressions"></a>

DynamoDB에서 `PutItem`, `UpdateItem` 및 `DeleteItem` DynamoDB 작업을 사용하여 객체를 변경하는 경우, 작업을 수행하기 전에 DynamoDB에 이미 있는 객체의 상태를 기준으로 요청에 성공할지 여부를 제어하는 조건 표현식을 선택적으로 지정할 수 있습니다.

 AWS AppSync DynamoDB 해석기를 사용하면 `PutItem`, `UpdateItem`및 `DeleteItem` 요청 매핑 문서에 조건 표현식을 지정할 수 있으며, 조건이 실패하고 객체가 업데이트되지 않은 경우 따라야 할 전략도 지정할 수 있습니다.

## 예제 1.
<a name="id19"></a>

다음 `PutItem` 매핑 문서에는 조건식은 포함되어 있지 않습니다. 따라서 키가 같은 항목이 이미 존재하더라도 DynamoDB에 항목을 저장하기 때문에 기존 항목을 덮어 씁니다.

```
{
   "version" : "2017-02-28",
   "operation" : "PutItem",
   "key" : {
      "id" : { "S" : "1" }
   }
}
```

## 예제 2.
<a name="id20"></a>

다음 `PutItem` 매핑 문서에는 동일한 키를 가진 항목이 DynamoDB에 *없는* 경우에만 작업을 성공시킬 수 있는 조건 표현식이 있습니다.

```
{
   "version" : "2017-02-28",
   "operation" : "PutItem",
   "key" : {
      "id" : { "S" : "1" }
   },
   "condition" : {
      "expression" : "attribute_not_exists(id)"
   }
}
```

기본적으로 조건 확인에 실패하면 AWS AppSync DynamoDB 해석기는 변형에 대한 오류를 반환합니다. 그러나 AWS AppSync DynamoDB 해석기는 개발자가 몇 가지 일반적인 엣지 사례를 처리하는 데 도움이 되는 몇 가지 추가 기능을 제공합니다.
+  AWS AppSync DynamoDB 해석기가 DynamoDB의 현재 값이 원하는 결과와 일치하는지 확인할 수 있는 경우 작업을 성공한 것처럼 취급합니다.
+ 오류를 반환하는 대신 사용자 지정 Lambda 함수를 호출하도록 해석기를 구성하여 AWS AppSync DynamoDB 해석기가 오류를 처리하는 방법을 결정할 수 있습니다.

이러한 내용은 [조건 확인 실패 처리](#aws-appsync-resolver-mapping-template-reference-dynamodb-condition-handling) 단원에 자세히 설명되어 있습니다.

DynamoDB 조건 표현식에 대한 자세한 내용은 [DynamoDB ConditionExpressions 문서](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ConditionExpressions.html)를 참조하세요.

## 조건 지정
<a name="aws-appsync-resolver-mapping-template-reference-dynamodb-condition-specification"></a>

`PutItem`, `UpdateItem` 및 `DeleteItem` 요청 매핑 문서 모두에서 선택적 `condition` 섹션을 지정할 수 있습니다. 이 섹션을 지정하지 않으면 조건 검사가 수행되지 않습니다. 지정한 경우, 해당 조건을 충족해야 작업이 성공합니다.

`condition` 섹션의 구조는 다음과 같습니다.

```
"condition" : {
    "expression" : "someExpression"
    "expressionNames" : {
        "#foo" : "foo"
    },
    "expressionValues" : {
        ":bar" : ... typed value
    },
    "equalsIgnore" : [ "version" ],
    "consistentRead" : true,
    "conditionalCheckFailedHandler" : {
        "strategy" : "Custom",
        "lambdaArn" : "arn:..."
    }
}
```

조건을 지정하는 필드는 다음과 같습니다.

** `expression` **  
업데이트 표현식 자체. 조건 표현식을 작성하는 방법에 대한 자세한 내용은 [DynamoDB ConditionExpressions 문서](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ConditionExpressions.html)를 참조하십시오. 이 필드는 지정되어 있어야 합니다.

** `expressionNames` **  
표현식 속성 name 자리 표시자의 대체 항목으로, 키-값 페어의 형식으로 표시됩니다. 키는 *expression*에 사용된 name 자리 표시자에 해당하고 값은 DynamoDB에 있는 항목의 속성 이름에 해당하는 문자열이어야 합니다. 이 필드는 선택 사항으로, *expression*에 사용된 표현식 속성인 name 자리 표시자의 대체 항목으로만 채워져야 합니다.

** `expressionValues` **  
표현식 속성 value 자리 표시자의 대체 항목으로, 키-값 페어의 형식으로 표시됩니다. 키는 expression에 사용되는 value 자리 표시자에 해당하고 값은 입력된 값이어야 합니다. ‘입력된 값’을 지정하는 방법에 대한 자세한 내용은 [형식 시스템(요청 매핑)](aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-request.md)을 참조하십시오. 입력된 값은 지정되어 있어야 합니다. 이 필드는 선택 사항으로, expression에 사용된 표현식 속성인 value 자리 표시자의 대체 항목으로만 채워져야 합니다.

나머지 필드는 AWS AppSync DynamoDB 해석기에 조건 확인 실패를 처리하는 방법을 알려줍니다.

** `equalsIgnore` **  
`PutItem` 작업을 사용할 때 조건 확인이 실패하면 AWS AppSync DynamoDB 해석기는 현재 DynamoDB에 있는 항목을 쓰려고 시도한 항목과 비교합니다. 이러한 두 항목이 동일하면 해석기에서는 해당 작업을 마치 성공한 것처럼 간주합니다. `equalsIgnore` 필드를 사용하여 해당 비교를 수행할 때 AWS AppSync가 무시해야 하는 속성 목록을 지정할 수 있습니다. 예를 들어, `version` 속성만 차이가 나는 경우에는 해당 작업을 성공한 작업으로 취급합니다. 이 필드는 선택 사항입니다.

** `consistentRead` **  
조건 확인에 실패하면 AWS AppSync는 강력히 일관된 읽기를 사용하여 DynamoDB에서 항목의 현재 값을 가져옵니다. 이 필드를 사용하여 AWS AppSync DynamoDB 해석기에 최종적으로 일관된 읽기를 대신 사용하도록 지시할 수 있습니다. 이 필드는 선택 사항으로, 기본값은 `true`입니다.

** `conditionalCheckFailedHandler` **  
이 섹션에서는 AWS AppSync DynamoDB 해석기가 DynamoDB의 현재 값을 예상 결과와 비교한 후 조건 확인 실패를 처리하는 방법을 지정할 수 있습니다. 이 섹션은 선택 사항입니다. 방법을 지정하지 않으면 `Reject` 전략이 기본값으로 지정됩니다.    
** `strategy` **  
 AWS AppSync DynamoDB 해석기가 DynamoDB의 현재 값을 예상 결과와 비교한 후 수행하는 전략입니다. 이 필드는 필수 필드로, 다음과 같은 두 가지 값을 가질 수 있습니다.    
** `Reject` **  
변형이 실패하고 GraphQL 응답에 오류가 추가됩니다.  
** `Custom` **  
 AWS AppSync DynamoDB 해석기는 사용자 지정 Lambda 함수를 호출하여 조건 확인 실패를 처리하는 방법을 결정합니다. `strategy`를 `Custom`으로 설정하면 `lambdaArn` 필드에 호출할 Lambda 함수의 ARN이 포함되어 있어야 합니다.  
** `lambdaArn` **  
 AWS AppSync DynamoDB 해석기가 조건 확인 실패를 처리하는 방법을 결정하는 호출할 Lambda 함수의 ARN입니다. 이 필드는 `strategy`를 `Custom`으로 설정한 경우에만 지정해야 합니다. 이 기능을 사용하는 방법에 대한 자세한 내용은 [조건 검사 실패 처리](#aws-appsync-resolver-mapping-template-reference-dynamodb-condition-handling)를 참조하십시오.

## 조건 검사 실패 처리
<a name="aws-appsync-resolver-mapping-template-reference-dynamodb-condition-handling"></a>

기본적으로 조건 확인이 실패하면 AWS AppSync DynamoDB 해석기는 변형에 대한 오류와 DynamoDB에 있는 객체의 현재 값을 반환합니다. 그러나 AWS AppSync DynamoDB 해석기는 개발자가 몇 가지 일반적인 엣지 사례를 처리하는 데 도움이 되는 몇 가지 추가 기능을 제공합니다.
+  AWS AppSync DynamoDB 해석기가 DynamoDB의 현재 값이 원하는 결과와 일치하는지 확인할 수 있는 경우 작업을 성공한 것처럼 취급합니다.
+ 오류를 반환하는 대신 사용자 지정 Lambda 함수를 호출하도록 해석기를 구성하여 AWS AppSync DynamoDB 해석기가 오류를 처리하는 방법을 결정할 수 있습니다.

이 프로세스의 흐름 차트입니다.

![\[Flowchart showing process for transforming requests with mutation attempts and value checks.\]](http://docs.aws.amazon.com/ko_kr/appsync/latest/devguide/images/DynamoDB-condition-check-failure-handling.png)


### 원하는 결과 확인
<a name="checking-for-the-desired-result"></a>

조건 확인에 실패하면 AWS AppSync DynamoDB 해석기는 `GetItem` DynamoDB 요청을 수행하여 DynamoDB에서 항목의 현재 값을 가져옵니다. 기본적으로 이 해석기는 강력히 일관된 읽기를 사용하지만, `condition` 블록의 `consistentRead` 필드를 사용하여 예상 결과와 비교하도록 구성할 수 있습니다.
+ `PutItem` 작업의 경우 AWS AppSync DynamoDB 해석기는 비교`equalsIgnore`에서에 나열된 속성을 제외하고 현재 값을 쓰려고 시도한 값과 비교합니다. 항목이 동일한 경우 해당 작업을 성공한 작업으로 간주하고 DynamoDB에서 가져온 항목을 반환합니다. 그렇지 않으면 구성된 전략을 따릅니다.

  예를 들어, `PutItem` 요청 매핑 문서가 다음과 같은 경우:

  ```
  {
     "version" : "2017-02-28",
     "operation" : "PutItem",
     "key" : {
        "id" : { "S" : "1" }
     },
     "attributeValues" : {
        "name" : { "S" : "Steve" },
        "version" : { "N" : 2 }
     },
     "condition" : {
        "expression" : "version = :expectedVersion",
        "expressionValues" : {
            ":expectedVersion" : { "N" : 1 }
        },
        "equalsIgnore": [ "version" ]
     }
  }
  ```

  그리고 DynamoDB에 현재 있는 항목이 다음과 같은 경우:

  ```
  {
     "id" : { "S" : "1" },
     "name" : { "S" : "Steve" },
     "version" : { "N" : 8 }
  }
  ```

   AWS AppSync DynamoDB 해석기는 쓰려고 시도한 항목을 현재 값과 비교하고 유일한 차이점은 `version` 필드였지만 필드를 무시하도록 구성되어 있으므로 작업을 성공으로 `version` 처리하고 DynamoDB에서 검색된 항목을 반환합니다.
+ `DeleteItem` 작업의 경우 AWS AppSync DynamoDB 해석기는 항목을 DynamoDB에서 반환했는지 확인합니다. 반환되는 항목이 없는 경우 해당 작업을 성공으로 간주합니다. 그렇지 않으면 구성된 전략을 따릅니다.
+ `UpdateItem` 작업의 경우 AWS AppSync DynamoDB 해석기에 현재 DynamoDB에 있는 항목이 예상 결과와 일치하는지 확인하기에 충분한 정보가 없으므로 구성된 전략을 따릅니다.

DynamoDB에서 객체의 현재 상태가 예상 결과와 다른 경우 AWS AppSync DynamoDB 해석기는 구성된 전략을 따라 변형을 거부하거나 Lambda 함수를 호출하여 다음에 수행할 작업을 결정합니다.

### 'Reject' 전략 따르기
<a name="following-the-reject-strategy"></a>

`Reject` 전략을 따르면 AWS AppSync DynamoDB 해석기가 변형에 대한 오류를 반환합니다.

예를 들어 다음과 같은 변형 요청이 있습니다.

```
mutation {
    updatePerson(id: 1, name: "Steve", expectedVersion: 1) {
        Name
        theVersion
    }
}
```

DynamoDB에서 반환된 항목이 다음과 같은 경우:

```
{
   "id" : { "S" : "1" },
   "name" : { "S" : "Steve" },
   "version" : { "N" : 8 }
}
```

그리고 응답 매핑 템플릿이 다음과 같은 경우:

```
{
   "id" : $util.toJson($context.result.id),
   "Name" : $util.toJson($context.result.name),
   "theVersion" : $util.toJson($context.result.version)
}
```

GraphQL 응답은 다음과 같습니다.

```
{
  "data": null,
  "errors": [
    {
      "message": "The conditional request failed (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ConditionalCheckFailedException; Request ID: ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ)"
      "errorType": "DynamoDB:ConditionalCheckFailedException",
      ...
    }
  ]
}
```

반환된 객체의 필드를 다른 해석기가 채우고 변형에 성공했는데 이 객체가 `error` 섹션에서 반환되면 반환된 객체의 필드가 확인되지 않습니다.

### 'Custom' 전략 따르기
<a name="following-the-custom-strategy"></a>

`Custom` 전략을 따르면 AWS AppSync DynamoDB 해석기가 Lambda 함수를 호출하여 다음에 수행할 작업을 결정합니다. Lambda 함수는 다음 옵션 중 하나를 선택합니다.
+  변형 `reject`. 이렇게 하면 AWS AppSync DynamoDB 해석기가 구성된 전략이 인 것처럼 동작하여 이전 섹션에서 설명한 대로 DynamoDB에 있는 객체의 현재 값과 변형에 대한 오류를 `Reject`반환하도록 지시합니다.
+  변형 `discard`. 이렇게 하면 AWS AppSync DynamoDB 해석기에 조건 확인 실패를 자동으로 무시하고 DynamoDB에서 값을 반환하도록 지시합니다.
+  변형 `retry`. 이렇게 하면 AWS AppSync DynamoDB 해석기에 새 요청 매핑 문서로 변형을 다시 시도하도록 지시합니다.

 **Lambda 호출 요청** 

 AWS AppSync DynamoDB 해석기는에 지정된 Lambda 함수를 호출합니다`lambdaArn`. 데이터 원본에 대해 구성된 동일한 `service-role-arn`을 사용합니다. 호출의 페이로드 구조는 다음과 같습니다.

```
{
    "arguments": { ... },
    "requestMapping": {... },
    "currentValue": { ... },
    "resolver": { ... },
    "identity": { ... }
}
```

필드는 다음과 같이 정의됩니다.

** `arguments` **  
GraphQL 변형의 인수. `$context.arguments`에서 요청 매핑 문서에 사용할 수 있는 인수와 동일합니다.

** `requestMapping` **  
작업에 대한 요청 매핑 문서

** `currentValue` **  
DynamoDB에 있는 객체의 현재 값

** `resolver` **  
 AWS AppSync 해석기에 대한 정보입니다.

** `identity` **  
호출자에 대한 정보. `$context.identity`에서 요청 매핑 문서에 사용할 수 있는 자격 증명 정보와 동일합니다.

페이로드 전체를 보여주는 예:

```
{
    "arguments": {
        "id": "1",
        "name": "Steve",
        "expectedVersion": 1
    },
    "requestMapping": {
        "version" : "2017-02-28",
        "operation" : "PutItem",
        "key" : {
           "id" : { "S" : "1" }
        },
        "attributeValues" : {
           "name" : { "S" : "Steve" },
           "version" : { "N" : 2 }
        },
        "condition" : {
           "expression" : "version = :expectedVersion",
           "expressionValues" : {
               ":expectedVersion" : { "N" : 1 }
           },
           "equalsIgnore": [ "version" ]
        }
    },
    "currentValue": {
        "id" : { "S" : "1" },
        "name" : { "S" : "Steve" },
        "version" : { "N" : 8 }
    },
    "resolver": {
        "tableName": "People",
        "awsRegion": "us-west-2",
        "parentType": "Mutation",
        "field": "updatePerson",
        "outputType": "Person"
    },
    "identity": {
        "accountId": "123456789012",
        "sourceIp": "x.x.x.x",
        "user": "AIDAAAAAAAAAAAAAAAAAA",
        "userArn": "arn:aws:iam::123456789012:user/appsync"
    }
}
```

 **Lambda 호출 응답** 

Lambda 함수는 호출 페이로드를 검사해 AWS AppSync DynamoDB 해석기에서 실패를 처리해야 하는 방법을 결정하는 비즈니스 로직을 어떠한 것이든 적용할 수 있습니다. 조건 검사 실패를 처리하기 위한 옵션에는 다음 3가지가 있습니다.
+  변형 `reject`. 이 옵션에 대한 응답 페이로드의 구조는 다음과 같아야 합니다.

  ```
  {
      "action": "reject"
  }
  ```

  이렇게 하면 위의 섹션에 설명된 대로 AWS AppSync DynamoDB 해석기에 구성된 전략이 인 것처럼 동작하여 DynamoDB에 있는 객체의 현재 값과 변형에 대한 오류를 `Reject`반환하도록 지시합니다.
+  변형 `discard`. 이 옵션에 대한 응답 페이로드의 구조는 다음과 같아야 합니다.

  ```
  {
      "action": "discard"
  }
  ```

  이렇게 하면 AWS AppSync DynamoDB 해석기에 조건 확인 실패를 자동으로 무시하고 DynamoDB에서 값을 반환하도록 지시합니다.
+  변형 `retry`. 이 옵션에 대한 응답 페이로드의 구조는 다음과 같아야 합니다.

  ```
  {
      "action": "retry",
      "retryMapping": { ... }
  }
  ```

  그러면 AWS AppSync DynamoDB 해석기에 새 요청 매핑 문서로 변형을 다시 시도하도록 지시합니다. `retryMapping` 섹션의 구조는 DynamoDB 작업에 따라 달라지며 해당 작업에 대한 전체 요청 매핑 문서의 하위 집합입니다.

  `PutItem`의 경우 `retryMapping` 섹션의 구조는 다음과 같습니다. `attributeValues` 필드에 대한 설명은 [PutItem](aws-appsync-resolver-mapping-template-reference-dynamodb-putitem.md)을 참조하십시오.

  ```
  {
      "attributeValues": { ... },
      "condition": {
          "equalsIgnore" = [ ... ],
          "consistentRead" = true
      }
  }
  ```

  `UpdateItem`의 경우 `retryMapping` 섹션의 구조는 다음과 같습니다. `update` 섹션에 대한 설명은 [UpdateItem](aws-appsync-resolver-mapping-template-reference-dynamodb-updateitem.md)을 참조하십시오.

  ```
  {
      "update" : {
          "expression" : "someExpression"
          "expressionNames" : {
              "#foo" : "foo"
          },
          "expressionValues" : {
              ":bar" : ... typed value
          }
      },
      "condition": {
          "consistentRead" = true
      }
  }
  ```

  `DeleteItem`의 경우 `retryMapping` 섹션의 구조는 다음과 같습니다.

  ```
  {
      "condition": {
          "consistentRead" = true
      }
  }
  ```

  작동할 수 있는 다른 작업 또는 키를 지정할 수 있는 방법은 없습니다. AWS AppSync DynamoDB 해석기는 동일한 객체에서 동일한 작업의 재시도만 허용합니다. `condition` 섹션에서는 `conditionalCheckFailedHandler`를 지정할 수 없습니다. 재시도가 실패하면 AWS AppSync DynamoDB 해석기는 `Reject` 전략을 따릅니다.

다음은 실패한 `PutItem` 요청을 처리하는 Lambda 함수의 예입니다. 이 비즈니스 로직은 호출한 사람이 누구인지 확인합니다. `jeffTheAdmin`이 호출한 경우 요청을 재시도해 현재 DynamoDB에 있는 항목에서 `version` 및 `expectedVersion`을 업데이트합니다. 그렇지 않으면 변형을 거부합니다.

```
exports.handler = (event, context, callback) => {
    console.log("Event: "+ JSON.stringify(event));

    // Business logic goes here.

    var response;
    if ( event.identity.user == "jeffTheAdmin" ) {
        response = {
            "action" : "retry",
            "retryMapping" : {
                "attributeValues" : event.requestMapping.attributeValues,
                "condition" : {
                    "expression" : event.requestMapping.condition.expression,
                    "expressionValues" : event.requestMapping.condition.expressionValues
                }
            }
        }
        response.retryMapping.attributeValues.version = { "N" : event.currentValue.version.N + 1 }
        response.retryMapping.condition.expressionValues[':expectedVersion'] = event.currentValue.version

    } else {
        response = { "action" : "reject" }
    }

    console.log("Response: "+ JSON.stringify(response))
    callback(null, response)
};
```

# 트랜잭션 조건 표현식
<a name="aws-appsync-resolver-mapping-template-reference-dynamodb-transaction-condition-expressions"></a>

트랜잭션 조건식은 `TransactWriteItems`에서 네 가지 작업 유형 모두(`PutItem`, `DeleteItem`, `UpdateItem`, `ConditionCheck`)의 요청 매핑 템플릿에 사용할 수 있습니다.

`PutItem`, `DeleteItem`, `UpdateItem`의 경우 트랜잭션 조건 표현식은 선택 사항입니다. `ConditionCheck`의 경우 트랜잭션 조건 표현식이 필수입니다.

## 예제 1.
<a name="id22"></a>

다음 트랜잭션 `DeleteItem` 매핑 문서에는 조건식이 없습니다. 따라서 DynamoDB에서 항목을 삭제합니다.

```
{
   "version": "2018-05-29",
   "operation": "TransactWriteItems",
   "transactItems": [
      {
         "table": "posts",
         "operation": "DeleteItem",
         "key": {
            "id": { "S" : "1" }
         }
      }
   ]
}
```

## 예제 2.
<a name="id23"></a>

다음 트랜잭션 `DeleteItem` 매핑 문서에는 해당 게시물의 작성자가 특정 이름과 같은 경우에만 작업이 성공할 수 있는 트랜잭션 조건식이 있습니다.

```
{
   "version": "2018-05-29",
   "operation": "TransactWriteItems",
   "transactItems": [
      {
         "table": "posts",
         "operation": "DeleteItem",
         "key": {
            "id": { "S" : "1" }
         }
         "condition": {
            "expression": "author = :author",
            "expressionValues": {
               ":author": { "S" : "Chunyan" }
            }
         }
      }
   ]
}
```

조건 검사에 실패하면 `TransactionCanceledException`이 발생하고, `$ctx.result.cancellationReasons`에 오류 세부 정보가 반환됩니다. 기본적으로, 조건 검사가 실패하게 된 원인인 DynamoDB의 이전 항목이 `$ctx.result.cancellationReasons`에 반환됩니다.

## 조건 지정
<a name="id24"></a>

`PutItem`, `UpdateItem` 및 `DeleteItem` 요청 매핑 문서 모두에서 선택적 `condition` 섹션을 지정할 수 있습니다. 이 섹션을 지정하지 않으면 조건 검사가 수행되지 않습니다. 지정한 경우, 해당 조건을 충족해야 작업이 성공합니다. `ConditionCheck`에는 지정할 `condition` 섹션이 있어야 합니다. 전체 트랜잭션이 성공하려면 조건이 true여야 합니다.

`condition` 섹션의 구조는 다음과 같습니다.

```
"condition": {
    "expression": "someExpression",
    "expressionNames": {
        "#foo": "foo"
    },
    "expressionValues": {
        ":bar": ... typed value
    },
    "returnValuesOnConditionCheckFailure": false
}
```

조건을 지정하는 필드는 다음과 같습니다.

** `expression` **  
업데이트 표현식 자체. 조건 표현식을 작성하는 방법에 대한 자세한 내용은 [DynamoDB ConditionExpressions 문서](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ConditionExpressions.html)를 참조하십시오. 이 필드는 지정되어 있어야 합니다.

** `expressionNames` **  
표현식 속성 name 자리 표시자의 대체 항목으로, 키-값 페어의 형식으로 표시됩니다. 키는 *expression*에 사용된 name 자리 표시자에 해당하고 값은 DynamoDB에 있는 항목의 속성 이름에 해당하는 문자열이어야 합니다. 이 필드는 선택 사항으로, *expression*에 사용된 표현식 속성인 name 자리 표시자의 대체 항목으로만 채워져야 합니다.

** `expressionValues` **  
표현식 속성 value 자리 표시자의 대체 항목으로, 키-값 페어의 형식으로 표시됩니다. 키는 expression에 사용되는 value 자리 표시자에 해당하고 값은 입력된 값이어야 합니다. ‘입력된 값’을 지정하는 방법에 대한 자세한 내용은 형식 시스템(요청 매핑)을 참조하십시오. 입력된 값은 지정되어 있어야 합니다. 이 필드는 선택 사항으로, expression에 사용된 표현식 속성인 value 자리 표시자의 대체 항목으로만 채워져야 합니다.

** `returnValuesOnConditionCheckFailure` **  
조건 검사에 실패할 경우 DynamoDB의 항목을 다시 가져올지 여부를 지정합니다. 가져온 항목은 `$ctx.result.cancellationReasons[$index].item`에 있습니다. 여기서 `$index`는 조건 검사에 실패한 요청 항목의 인덱스입니다. 기본값은 true입니다.

# 프로젝션
<a name="aws-appsync-resolver-mapping-template-reference-dynamodb-projections"></a>

`GetItem`, `Scan`, `Query`, `BatchGetItem` 및 `TransactGetItems` 작업을 사용하여 DynamoDB에서 객체를 읽을 때 원하는 속성을 식별하는 프로젝션을 선택적으로 지정할 수 있습니다. 프로젝션의 구조는 필터와 비슷하며 다음과 같습니다.

```
"projection" : {
    "expression" : "projection expression"
    "expressionNames" : {
        "#name" : "name",
    }
}
```

필드는 다음과 같이 정의됩니다.

**`expression`**   
프로젝션 표현식은 문자열입니다. 단일 속성을 가져오려면 속성의 이름을 지정합니다. 여러 속성의 경우 이름은 쉼표로 구분된 값이어야 합니다. 프로젝션 표현식 작성에 대한 자세한 내용은 [DynamoDB 프로젝션 표현식](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ProjectionExpressions.html) 설명서를 참조하세요. 이 필드는 필수 항목입니다.

 **`expressionNames`**   
표현식 속성 *name* 자리 표시자의 대체 항목으로, 키-값 페어의 형식으로 표시됩니다. 키는 `expression`에 사용된 이름 자리 표시자에 해당합니다. 이 값은 DynamoDB에서 항목의 속성 이름에 해당하는 문자열이어야 합니다. 이 필드는 선택 사항으로, `expression`에 사용된 표현식 속성인 name 자리 표시자의 대체 항목으로만 채워져야 합니다. `expressionNames`에 대한 자세한 내용은 [DynamoDB 설명서](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ExpressionAttributeNames.html)를 참조하세요.

## 예제 1.
<a name="id25"></a>

다음 예는 DynamoDB에서 `author` 및 `id` 속성만 반환되는 VTL 매핑 템플릿의 프로젝션 섹션입니다.

```
"projection" : {
    "expression" : "#author, id",
    "expressionNames" : {
        "#author" : "author"
    }
}
```

**작은 정보**  
[\$1context.info.SelectionSetList](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference.html#aws-appsync-resolver-context-reference-info)를 사용하여 GraphQL 요청 설정에 액세스할 수 있습니다. 이 필드를 사용하면 요구 사항에 따라 프로젝션 표현식을 동적으로 프레이밍할 수 있습니다.

**참고**  
`Query` 및 `Scan` 작업과 함께 프로젝션 표현식을 사용하는 경우 `select`의 값은 반드시 `SPECIFIC_ATTRIBUTES`이어야 합니다. 자세한 내용은 [DynamoDB 설명서](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html#DDB-Query-request-Select)를 참조하세요.

# RDS용 AWS AppSync 해석기 매핑 템플릿 참조
<a name="resolver-mapping-template-reference-rds"></a>

 AWS AppSync RDS 해석기 매핑 템플릿을 사용하면 개발자가 Amazon Aurora Serverless용 데이터 API로 SQL 쿼리를 전송하고 이러한 쿼리의 결과를 다시 가져올 수 있습니다.

## 요청 매핑 템플릿
<a name="request-mapping-template"></a>

RDS 요청 매핑 템플릿은 꽤 간단합니다.

```
{
    "version": "2018-05-29",
    "statements": [],
    "variableMap": {},
    "variableTypeHintMap": {}
}
```

다음은 해석되고 난 RDS 요청 매핑 템플릿의 JSON 스키마 표현입니다.

```
{
    "definitions": {},
    "$schema": "https://json-schema.org/draft-07/schema#",
    "$id": "https://example.com/root.json",
    "type": "object",
    "title": "The Root Schema",
    "required": [
        "version",
        "statements",
        "variableMap"
    ],
    "properties": {
        "version": {
            "$id": "#/properties/version",
            "type": "string",
            "title": "The Version Schema",
            "default": "",
            "examples": [
                "2018-05-29"
            ],
            "enum": [
                "2018-05-29"
            ],
            "pattern": "^(.*)$"
        },
        "statements": {
            "$id": "#/properties/statements",
            "type": "array",
            "title": "The Statements Schema",
            "items": {
                "$id": "#/properties/statements/items",
                "type": "string",
                "title": "The Items Schema",
                "default": "",
                "examples": [
                    "SELECT * from BOOKS"
                ],
                "pattern": "^(.*)$"
            }
        },
        "variableMap": {
            "$id": "#/properties/variableMap",
            "type": "object",
            "title": "The Variablemap Schema"
        },
        "variableTypeHintMap": {
            "$id": "#/properties/variableTypeHintMap",
            "type": "object",
            "title": "The variableTypeHintMap Schema"
        }
    }
}
```

다음은 정적 쿼리를 사용하는 요청 매핑 템플릿의 예입니다.

```
{
    "version": "2018-05-29",
    "statements": [
        "select title, isbn13 from BOOKS where author = 'Mark Twain'"
    ]
}
```

## 버전
<a name="version"></a>

모든 요청 매핑 템플릿에 공통적으로 적용되는 버전 필드는 템플릿이 사용하는 버전을 정의합니다. 버전 필드는 필수입니다. 값 '2018-05-29'는 Amazon RDS 매핑 템플릿에 지원되는 유일한 버전입니다.

```
"version": "2018-05-29"
```

## 명령문 및 VariableMap
<a name="statements-variablemap"></a>

명령문 배열은 개발자 제공 쿼리를 위한 자리 표시자입니다. 현재, 요청 매핑 템플릿당 쿼리를 최대 2개까지 지원합니다. `variableMap`은 SQL 문을 더 간단하고 쉽게 읽을 수 있도록 만드는 데 사용할 수 있는 별칭을 포함하고 있는 선택적 필드입니다. 예를 들어, 가능한 예제는 다음과 같습니다.

```
{
"version": "2018-05-29",
    "statements": [
        "insert into BOOKS VALUES (:AUTHOR, :TITLE, :ISBN13)",
        "select * from BOOKS WHERE isbn13 = :ISBN13"
    ],
    "variableMap": {
        ":AUTHOR": $util.toJson($ctx.args.newBook.author),
        ":TITLE": $util.toJson($ctx.args.newBook.title),
        ":ISBN13": $util.toJson($ctx.args.newBook.isbn13)
    }
}
```

AWS AppSync 는 변수 맵 값을 사용하여 Amazon Aurora Serverless Data API로 전송할 **[SqlParameterized](https://docs.aws.amazon.com/rdsdataservice/latest/APIReference/API_SqlParameter.html)** 쿼리를 구성합니다. SQL 명령문은 변수 맵에 제공된 파라미터를 사용하여 실행되므로 SQL 삽입 위험이 없습니다.

## VariableTypeHintMap
<a name="variabletypehintmap"></a>

`variableTypeHintMap`은 [SQL 파라미터](https://docs.aws.amazon.com/rdsdataservice/latest/APIReference/API_SqlParameter.html) 유형 힌트를 보내는 데 사용할 수 있는 별칭 유형을 포함하는 선택적 필드입니다. 이러한 유형 힌트는 SQL 명령문에서의 명시적 캐스팅을 방지하므로 길이가 짧아집니다. 예를 들어, 가능한 예제는 다음과 같습니다.

```
{
    "version": "2018-05-29",
    "statements": [
        "insert into LOGINDATA VALUES (:ID, :TIME)",
        "select * from LOGINDATA WHERE id = :ID"
     ],
     "variableMap": {
        ":ID": $util.toJson($ctx.args.id),
        ":TIME": $util.toJson($ctx.args.time)
     },
     "variableTypeHintMap": {
        ":id": "UUID",
        ":time": "TIME"
     }
}
```

AWS AppSync 는 변수 맵 값을 사용하여 Amazon Aurora Serverless Data API로 전송되는 쿼리를 구성합니다. 또한 `variableTypeHintMap` 데이터를 사용하고 유형 정보를 RDS로 보냅니다. RDS가 지원되는 `typeHints`는 [여기](https://docs.aws.amazon.com/rdsdataservice/latest/APIReference/API_SqlParameter.html)에서 확인할 수 있습니다.

# OpenSearch용 AWS AppSync 해석기 매핑 템플릿 참조
<a name="resolver-mapping-template-reference-elasticsearch"></a>

**참고**  
이제 우리는 주로 APPSYNC\$1JS 런타임과 해당 문서를 지원합니다. [여기](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)에서 APPSYNC\$1JS 런타임과 해당 안내서를 사용해 보세요.

Amazon OpenSearch Service용 AWS AppSync 해석기를 사용하면 GraphQL을 사용하여 계정의 기존 OpenSearch Service 도메인에 데이터를 저장하고 검색할 수 있습니다. 이 해석기는 수신되는 GraphQL 요청을 OpenSearch Service 요청으로 매핑한 다음 OpenSearch Service 응답을 다시 GraphQL로 매핑하도록 하여 작동합니다. 이 섹션에서는 지원되는 OpenSearch Service 작업에 대한 매핑 템플릿에 대해 설명합니다.

## 요청 매핑 템플릿
<a name="request-mapping-template"></a>

대부분의 OpenSearch Service 요청 매핑 템플릿에는 몇 부분만 변경되는 공통 구조가 있습니다. 다음 예제에서는 OpenSearch Service 도메인을 대상으로 검색을 실행합니다. 이 도메인에서는 `post`라는 인덱스로 문서가 구성되어 있습니다. 검색 파라미터는 `body` 섹션에 정의되어 있고, 공통 쿼리 절은 대부분 `query` 필드에서 정의합니다. 이 예에서는 문서의 `"Nadia"` 필드에서 `"Bailey"`, `author` 또는 둘 다가 포함된 문서를 검색합니다.

```
{
    "version":"2017-02-28",
    "operation":"GET",
    "path":"/post/_search",
    "params":{
        "headers":{},
        "queryString":{},
        "body":{
            "from":0,
            "size":50,
            "query" : {
                "bool" : {
                    "should" : [
                        {"match" : { "author" : "Nadia" }},
                        {"match" : { "author" : "Bailey" }}
                    ]
                }
            }
        }
    }
}
```

## 응답 매핑 템플릿
<a name="response-mapping-template"></a>

다른 데이터 소스와 마찬가지로 OpenSearch Service는 GraphQL로 변환해야 하는 응답을 AWS AppSync에 전송합니다.

대부분의 GraphQL 쿼리는 OpenSearch Service 응답에서 `_source` 필드를 검색합니다. 개별 문서 또는 문서 목록을 반환하도록 검색을 수행할 수 있기 때문에 OpenSearch Service에서는 두 가지 공통 응답 매핑 템플릿이 사용됩니다.

 **결과 목록** 

```
[
    #foreach($entry in $context.result.hits.hits)
      #if( $velocityCount > 1 ) , #end
        $utils.toJson($entry.get("_source"))
    #end
]
```

 **개별 항목** 

```
$utils.toJson($context.result.get("_source"))
```

## `operation` field
<a name="operation-field"></a>

**참고**  
이는 요청 매핑 템플릿에만 적용됩니다.

 AWS AppSync가 OpenSearch Service 도메인으로 보내는 HTTP 메서드 또는 동사(GET, POST, PUT, HEAD 또는 DELETE)입니다. 키와 값은 둘 다 문자열이어야 합니다.

```
"operation" : "PUT"
```

## `path` field
<a name="path-field"></a>

**참고**  
이는 요청 매핑 템플릿에만 적용됩니다.

 AWS AppSync의 OpenSearch Service 요청에 대한 검색 경로입니다. 이 경로는 작업의 HTTP 동사에 대한 URL을 구성합니다. 키와 값은 둘 다 문자열이어야 합니다.

```
"path" : "/<indexname>/_doc/<_id>"
"path" : "/<indexname>/_doc"
"path" : "/<indexname>/_search"
"path" : "/<indexname>/_update/<_id>
```

매핑 템플릿이 평가되면 이 경로는 OpenSearch Service 도메인을 포함해 HTTP 요청의 일부로 전송됩니다. 예를 들어, 이전 예제는 다음과 같이 변환될 수 있습니다.

```
GET https://opensearch-domain-name.REGION.es.amazonaws.com/indexname/type/_search
```

## `params` field
<a name="params-field"></a>

**참고**  
이는 요청 매핑 템플릿에만 적용됩니다.

검색에서 수행할 작업을 지정하는 데 사용되며, 가장 일반적으로 **본문** 내에 **쿼리** 값을 설정하여 지정합니다. 그러나 응답 형식 지정 등과 같이 구성할 수 있는 기타 여러 가지 기능이 있습니다.
+  **headers** 

  키-값 페어로 표시되는 헤더 정보. 키와 값은 둘 다 문자열이어야 합니다. 예제:

  ```
  "headers" : {
      "Content-Type" : "application/json"
  }
  ```
**참고**  
AWS AppSync는 현재 JSON만 로 지원합니다`Content-Type`.
+  **queryString** 

  JSON 응답에 대한 코드 형식 지정 등과 같이 공통 옵션을 지정하는 키-값 페어. 키와 값은 둘 다 문자열이어야 합니다. 예를 들어, 형식이 잘 지정된 JSON을 가져오려면 다음을 사용합니다.

  ```
  "queryString" : {
      "pretty" : "true"
  }
  ```
+  **body** 

  이는 요청의 주요 부분으로, AWS AppSync가 OpenSearch Service 도메인에 대한 올바른 형식의 검색 요청을 생성할 수 있도록 허용합니다. 키는 객체로 구성된 문자열이어야 합니다. 아래에 몇 가지 경우가 나와 있습니다.

 **예제 1**.

‘시애틀’과 일치하는 도시가 포함된 모든 문서를 반환합니다.

```
"body":{
    "from":0,
    "size":50,
    "query" : {
        "match" : {
            "city" : "seattle"
        }
    }
}
```

 **예제 2**.

도시 또는 주가 ‘워싱턴’과 일치하는 모든 문서를 반환합니다.

```
"body":{
    "from":0,
    "size":50,
    "query" : {
        "multi_match" : {
            "query" : "washington",
            "fields" : ["city", "state"]
        }
    }
}
```

## 변수 전달
<a name="passing-variables"></a>

**참고**  
이는 요청 매핑 템플릿에만 적용됩니다.

또한 VTL 문에서 평가의 일부로 변수를 전달할 수도 있습니다. 예를 들어, 다음과 같은 GraphQL 쿼리가 있다고 가정해 보겠습니다.

```
query {
    searchForState(state: "washington"){
        ...
    }
}
```

이 매핑 템플릿은 인수로 주를 받을 수 있습니다.

```
"body":{
    "from":0,
    "size":50,
    "query" : {
        "multi_match" : {
            "query" : "$context.arguments.state",
            "fields" : ["city", "state"]
        }
    }
}
```

VTL에 포함할 수 있는 유틸리티 목록은 [요청 헤더에 액세스](resolver-context-reference.md#aws-appsync-resolver-context-reference-util)를 참조하십시오.

# Lambda에 대한 AWS AppSync 해석기 매핑 템플릿 참조
<a name="resolver-mapping-template-reference-lambda"></a>

**참고**  
이제 우리는 주로 APPSYNC\$1JS 런타임과 해당 문서를 지원합니다. [여기](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)에서 APPSYNC\$1JS 런타임과 해당 안내서를 사용해 보세요.

 AWS AppSync 함수 및 해석기를 사용하여 계정에 있는 Lambda 함수를 호출할 수 있습니다. 클라이언트에 반환하기 전에 요청 페이로드와 Lambda 함수의 응답을 구성할 수 있습니다. 매핑 템플릿을 사용하여 AWS AppSync에 호출할 작업의 성격에 대한 힌트를 제공할 수도 있습니다. 이 단원에서는 지원되는 Lambda 작업에 대한 다양한 매핑 템플릿에 대해 설명합니다.

## 요청 매핑 템플릿
<a name="request-mapping-template"></a>

Lambda 요청 매핑 템플릿은 Lambda 함수와 관련된 필드를 처리합니다.

```
{
  "version": string,
  "operation": Invoke|BatchInvoke,
  "payload": any type,
  "invocationType": RequestResponse|Event
}
```

이는 해석된 후 Lambda 요청 매핑 템플릿의 JSON 스키마 표현입니다.

```
{
  "definitions": {},
  "$schema": "https://json-schema.org/draft-06/schema#",
  "$id": "https://aws.amazon.com/appsync/request-mapping-template.json",
  "type": "object",
  "properties": {
    "version": {
      "$id": "/properties/version",
      "type": "string",
      "enum": [
        "2018-05-29"
      ],
      "title": "The Mapping template version.",
      "default": "2018-05-29"
    },
    "operation": {
      "$id": "/properties/operation",
      "type": "string",
      "enum": [
        "Invoke",
        "BatchInvoke"
      ],
      "title": "The Mapping template operation.",
      "description": "What operation to execute.",
      "default": "Invoke"
    },
    "payload": {},
    "invocationType": {
      "$id": "/properties/invocationType",
      "type": "string",
      "enum": [
        "RequestResponse",
        "Event"
      ],
      "title": "The Mapping template invocation type.",
      "description": "What invocation type to execute.",
      "default": "RequestResponse"
    }
  },
  "required": [
    "version",
    "operation"
  ],
  "additionalProperties": false
}
```

다음은 페이로드 데이터가 컨텍스트의 인수와 함께 GraphQL 스키마의 `getPost` 필드인 `invoke` 작업을 사용하는 예제입니다.

```
{
  "version": "2018-05-29",
  "operation": "Invoke",
  "payload": {
    "field": "getPost",
    "arguments": $util.toJson($context.arguments)
  }
}
```

전체 매핑 문서는 Lambda 함수에 입력으로 전달되므로 앞의 예제는 다음과 같습니다.

```
{
  "version": "2018-05-29",
  "operation": "Invoke",
  "payload": {
    "field": "getPost",
    "arguments": {
      "id": "postId1"
    }
  }
}
```

### 버전
<a name="version"></a>

모든 요청 매핑 템플릿에 공통적으로 `version`에 따라 템플릿이 사용하는 버전이 정의됩니다. `version`은 필수이며 정적 값입니다.

```
"version": "2018-05-29"
```

### 연산
<a name="operation"></a>

Lambda 데이터 소스를 사용하면 `operation` 필드에서 `Invoke` 및 `BatchInvoke`의 두 가지 작업을 정의할 수 있습니다. `Invoke` 작업을 통해 AWS AppSync는 모든 GraphQL 필드 해석기에 대해 Lambda 함수를 호출하도록 알 수 있습니다.는 현재 GraphQL 필드에 대한 요청을 일괄 처리하도록 AWS AppSync에 `BatchInvoke` 지시합니다. `operation` 필드는 필수 사항입니다.

`Invoke`의 경우 해석된 요청 매핑 템플릿은 Lambda 함수의 입력 페이로드와 일치합니다. 위의 예를 수정해 보겠습니다.

```
{
  "version": "2018-05-29",
  "operation": "Invoke",
    "payload": {
      "arguments": $util.toJson($context.arguments)
    }
}
```

해결 후 Lambda 함수로 전달되며 다음과 같을 수 있습니다.

```
{
  "version": "2018-05-29",
  "operation": "Invoke",
    "payload": {
      "arguments": {
        "id": "postId1"
      }
    }
}
```

`BatchInvoke`의 경우 배치의 모든 필드 해석기에 매핑 템플릿이 적용됩니다. 간결성을 위해 AWS AppSync는 확인된 모든 매핑 템플릿 `payload` 값을 매핑 템플릿과 일치하는 단일 객체 아래의 목록으로 병합합니다. 다음 예제 템플릿을 이러한 병합을 보여줍니다.

```
{
  "version": "2018-05-29",
  "operation": "BatchInvoke",
  "payload": $util.toJson($context)
}
```

이 템플릿은 다음 매핑 문서로 해석됩니다.

```
{
  "version": "2018-05-29",
  "operation": "BatchInvoke",
  "payload": [
    {...}, // context for batch item 1
    {...}, // context for batch item 2
    {...}  // context for batch item 3
  ]
}
```

`payload` 목록의 각 요소는 단일 배치 항목에 해당합니다. Lambda 함수는 요청에 전송된 항목 순서에 맞게 목록 형태의 응답을 반환해야 합니다.

```
[
  { "data": {...}, "errorMessage": null, "errorType": null }, // result for batch item 1
  { "data": {...}, "errorMessage": null, "errorType": null }, // result for batch item 2
  { "data": {...}, "errorMessage": null, "errorType": null }  // result for batch item 3
]
```

### Payload
<a name="payload"></a>

`payload` 필드는 올바른 형식의 JSON을 Lambda 함수로 전달하는 데 사용되는 컨테이너입니다. `operation` 필드가 로 설정된 경우 `BatchInvoke` AWS AppSync는 기존 `payload` 값을 목록으로 래핑합니다. `payload` 필드는 선택 사항입니다.

### 간접 호출 유형
<a name="async-invocation-type"></a>

Lambda 데이터 소스를 사용하면 `RequestResponse` 및 `Event`의 두 가지 간접 호출 유형을 정의할 수 있습니다. 간접 호출 유형은 [Lambda API](https://docs.aws.amazon.com//lambda/latest/api/API_Invoke.html)에 정의된 호출 유형과 동의어입니다. `RequestResponse` 호출 유형은 AWS AppSync가 Lambda 함수를 동기적으로 호출하여 응답을 기다리도록 합니다. `Event` 간접 호출을 사용하면 Lambda 함수를 비동기적으로 간접 호출할 수 있습니다. Lambda가 `Event` 간접 호출 유형 요청을 처리하는 방법에 대한 자세한 내용은 [비동기식 간접 호출](https://docs.aws.amazon.com/lambda/latest/dg/invocation-async.html)을 참조하세요. `invocationType` 필드는 선택 사항입니다. 이 필드가 요청에 포함되지 않은 경우 AWS AppSync는 기본적으로 `RequestResponse` 호출 유형으로 설정됩니다.

`invocationType` 필드의 경우 해석된 요청은 Lambda 함수의 입력 페이로드와 일치합니다. 위의 예를 수정해 보겠습니다.

```
{
  "version": "2018-05-29",
  "operation": "Invoke",
  "invocationType": "Event"
  "payload": {
    "arguments": $util.toJson($context.arguments)
  }
}
```

해결 후 Lambda 함수로 전달되며 다음과 같을 수 있습니다.

```
{
  "version": "2018-05-29",
  "operation": "Invoke",
  "invocationType": "Event",
  "payload": {
    "arguments": {
      "id": "postId1"
    }
  }
}
```

`Event` 호출 유형 필드와 함께 `BatchInvoke` 작업을 사용하는 경우 AWS AppSync는 위에서 언급한 것과 동일한 방식으로 필드 해석기를 병합하고 요청은 값 목록이 `payload`인 비동기 이벤트로 Lambda 함수에 전달됩니다. 캐시 적중이 발생하면 Lambda로 전송되지 않으므로 `Event` 간접 호출 유형 해석기에 대한 해석기 캐싱을 비활성화하는 것이 좋습니다.

## 응답 매핑 템플릿
<a name="response-mapping-template"></a>

다른 데이터 소스와 마찬가지로 Lambda 함수는 GraphQL 유형으로 변환해야 하는 응답을 AWS AppSync에 전송합니다.

Lambda 함수의 결과가 Velocity Template Language(VTL) `context` 속성을 통해 사용할 수 있는 `$context.result` 객체에 설정됩니다.

Lambda 함수 응답의 모양이 GraphQL 유형의 모양과 정확히 일치하는 경우 다음 응답 매핑 템플릿을 사용하여 응답을 전달할 수 있습니다.

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

응답 매핑 템플릿에 적용되는 필수 필드 또는 모양 제한이 없습니다. 하지만 GraphQL은 강력한 형식이므로 해석된 매핑 템플릿이 필요한 GraphQL 유형과 일치해야 합니다.

## Lambda 함수 일괄 처리 응답
<a name="aws-appsync-resolver-mapping-template-reference-lambda-batched-response"></a>

`operation` 필드가 로 설정된 경우`BatchInvoke` AWS AppSync는 Lambda 함수에서 항목 목록을 다시 예상합니다. AWS AppSync가 각 결과를 원래 요청 항목에 다시 매핑하려면 응답 목록의 크기와 순서가 일치해야 합니다. 응답 목록에 `null` 항목이 있어도 유효합니다. `$ctx.result`가 적절히 *null*로 설정됩니다.

## Direct Lambda 해석기
<a name="direct-lambda-resolvers"></a>

매핑 템플릿 사용을 완전히 피하려는 경우 AWS AppSync는 Lambda 함수에 대한 기본 페이로드와 GraphQL 유형에 대한 기본 Lambda 함수 응답을 제공할 수 있습니다. 요청 템플릿, 응답 템플릿 또는 둘 다 제공하지 않도록 선택할 수 있으며 AWS AppSync는 이에 따라 이를 처리합니다.

### Direct Lambda 요청 매핑 템플릿
<a name="lambda-mapping-template-bypass-request"></a>

요청 매핑 템플릿이 제공되지 않으면 AWS AppSync는 `Context` 객체를 Lambda 함수에 `Invoke` 작업으로 직접 전송합니다. `Context` 객체의 구조에 대한 자세한 내용은 [AWS AppSync 해석기 매핑 템플릿 컨텍스트 참조](resolver-context-reference.md) 단원을 참조하세요.

### Direct Lambda 응답 매핑 템플릿
<a name="lambda-mapping-template-bypass-response"></a>

응답 매핑 템플릿이 제공되지 않은 경우 AWS AppSync는 Lambda 함수의 응답을 수신할 때 두 가지 중 하나를 수행합니다. 요청 매핑 템플릿을 제공하지 않았거나 버전 `2018-05-29`의 요청 매핑 템플릿을 제공한 경우, 응답은 다음 응답 매핑 템플릿과 동일하게 작동합니다.

```
#if($ctx.error)
     $util.error($ctx.error.message, $ctx.error.type, $ctx.result)
 #end
 $util.toJson($ctx.result)
```

버전 `2017-02-28`의 템플릿을 제공한 경우 응답 로직은 다음 응답 매핑 템플릿과 동일하게 작동합니다.

```
$util.toJson($ctx.result)
```

표면적으로 보면 매핑 템플릿 우회는 이전 예와 같이 특정 매핑 템플릿을 사용하는 것과 비슷하게 작동합니다. 그러나 내부에서는 매핑 템플릿에 대한 평가가 완전히 우회됩니다. 템플릿 평가 단계가 우회되기 때문에 평가해야 하는 응답 매핑 템플릿이 있는 Lambda 함수와 비교할 때 일부 시나리오에서는 애플리케이션이 응답 중에 더 적은 오버헤드와 지연 시간을 경험할 수 있습니다.

### Direct Lambda 해석기 응답에서의 사용자 지정 오류 처리
<a name="lambda-mapping-template-bypass-errors"></a>

사용자 지정 예외를 발생시켜 Direct Lambda 해석기가 호출하는 Lambda 함수의 오류 응답을 사용자 지정할 수 있습니다. 다음 예제는 JavaScript를 사용하여 사용자 지정 예외를 생성하는 방법을 설명합니다.

```
class CustomException extends Error {
  constructor(message) {
    super(message);
    this.name = "CustomException";
  }
}
 
throw new CustomException("Custom message");
```

예외가 발생하는 경우 `errorType` 및 `errorMessage`는 각각 발생한 사용자 지정 오류의 `name` 및 `message`입니다.

`errorType`가 인 경우`UnauthorizedException` AWS AppSync는 사용자 지정 메시지 대신 기본 메시지(`"You are not authorized to make this call."`)를 반환합니다.

다음의 코드 조각은 사용자 지정 `errorType`을 설명하는 GraphQL 응답의 예입니다.

```
{
  "data": {
    "query": null
  },
  "errors": [
    {
      "path": [
        "query"
      ],
      "data": null,
      "errorType": "CustomException",
      "errorInfo": null,
      "locations": [
        {
          "line": 5,
          "column": 10,
          "sourceName": null
        }
      ],
      "message": "Custom Message"
    }
  ]
}
```

### Direct Lambda 해석기: 일괄 처리 활성화
<a name="lambda-resolvers-batching"></a>

해석기에 `maxBatchSize`를 구성하여 Direct Lambda 해석기에 대한 일괄 처리를 활성화할 수 있습니다. Direct Lambda 해석기에 대해 `maxBatchSize`가 `0`보다 큰 값으로 설정된 경우, AWS AppSync는 최대 `maxBatchSize` 크기의 요청을 Lambda 함수에 일괄적으로 보냅니다.

Direct Lambda 해석기에서 `maxBatchSize`를 `0`으로 설정하면 일괄 처리가 해제됩니다.

Lambda 해석기를 사용한 일괄 처리 작동 방식에 대한 자세한 내용은 [고급 사용 사례: 일괄 처리](tutorial-lambda-resolvers.md#advanced-use-case-batching) 단원을 참조하세요.

#### 요청 매핑 템플릿
<a name="lambda-resolvers-batching-request-template"></a>

일괄 처리가 활성화되고 요청 매핑 템플릿이 제공되지 않으면 AWS AppSync는 `Context` 객체 목록을 `BatchInvoke` 작업으로 Lambda 함수에 직접 보냅니다.

#### 응답 매핑 템플릿
<a name="lambda-resolvers-batching-response-template"></a>

일괄 처리가 활성화되고 응답 매핑 템플릿이 제공되지 않은 경우, 응답 로직은 다음 응답 매핑 템플릿과 동일합니다.

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

Lambda 함수는 전송된 `Context` 객체 목록과 동일한 순서로 결과 목록을 반환해야 합니다. 특정 결과에 대해 `errorMessage` 및 `errorType`을 제공하여 개별 오류를 반환할 수 있습니다. 목록에서 각 결과는 다음 형식이어야 합니다.

```
{
   "data" : { ... }, // your data
   "errorMessage" : { ... }, // optional, if included an error entry is added to the "errors" object in the AppSync response 
   "errorType" : { ... } // optional, the error type
}
```

**참고**  
결과 객체의 다른 필드는 현재 무시됩니다.

#### Lambda의 오류 처리
<a name="lambda-resolvers-batching-error-handling"></a>

Lambda 함수에서 예외 또는 오류를 발생시켜 모든 결과에 대해 오류를 반환할 수 있습니다. 배치 요청의 페이로드 요청 또는 응답 크기가 너무 크면 Lambda는 오류를 반환합니다. 이 경우 `maxBatchSize`를 줄이거나 응답 페이로드의 크기를 줄이는 것을 고려해야 합니다.

개별 오류 처리에 대한 자세한 내용은 [개별 오류 반환](tutorial-lambda-resolvers.md#returning-individual-errors)을 참조하세요.

#### 샘플 Lambda 함수
<a name="sample-lambda-function"></a>

아래 스키마를 사용하여 `Post.relatedPosts` 필드 해석기에 대한 Direct Lambda 해석기를 생성하고 `maxBatchSize`를 `0`보다 큰 값으로 설정하여 일괄 처리를 활성화할 수 있습니다.

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

다음 쿼리에서는 `relatedPosts` 해결 요청을 일괄 처리하여 Lambda 함수를 호출합니다.

```
query getAllPosts {
  allPosts {
    id
    relatedPosts {
      id
    }
  }
}
```

Lambda 함수의 간단한 구현은 다음과 같습니다.

```
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: [],
}
exports.handler = async (event) => {
  console.log('event ->', event)
  // retrieve the ID of each post
  const ids = event.map((context) => context.source.id)
  // fetch the related posts for each post id
  const related = ids.map((id) => relatedPosts[id])

  // return the related posts; or an error if none were found
  return related.map((r) => {
    if (r.length > 0) {
      return { data: r }
    } else {
      return { data: null, errorMessage: 'Not found', errorType: 'ERROR' }
    }
  })
}
```

# EventBridge에 대한AWS AppSync 해석기 매핑 템플릿 참조
<a name="resolver-mapping-template-reference-eventbridge"></a>

**참고**  
이제 우리는 주로 APPSYNC\$1JS 런타임과 해당 문서를 지원합니다. [여기](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)에서 APPSYNC\$1JS 런타임과 해당 안내서를 사용해 보세요.

EventBridge 데이터 소스와 함께 사용되는 AWS AppSync 해석기 매핑 템플릿을 사용하면 사용자 지정 이벤트를 Amazon EventBridge 버스로 전송할 수 있습니다.

## 요청 매핑 템플릿
<a name="request-mapping-template"></a>

`PutEvents` 요청 매핑 템플릿을 사용하면 여러 사용자 지정 이벤트를 EventBridge 이벤트 버스로 보낼 수 있습니다. 매핑 문서의 구조는 다음과 같습니다.

```
{
    "version" : "2018-05-29", 
    "operation" : "PutEvents",
    "events" : [{}]
}
```

다음은 EventBridge용 요청 매핑 템플릿의 예입니다.

```
{
    "version": "2018-05-29",
    "operation": "PutEvents",
    "events": [{
        "source": "com.mycompany.myapp",
        "detail": {
            "key1" : "value1",
            "key2" : "value2"
        },
        "detailType": "myDetailType1"
    },
    {
        "source": "com.mycompany.myapp",
        "detail": {
            "key3" : "value3",
            "key4" : "value4"
        },
        "detailType": "myDetailType2",
        "resources" : ["Resource1", "Resource2"],
        "time" : "2023-01-01T00:30:00.000Z"
    }
    
    ]
}
```

## 응답 매핑 템플릿
<a name="response-mapping-template"></a>

`PutEvents` 작업이 성공하면 EventBridge의 응답이 `$ctx.result`에 포함됩니다.

```
#if($ctx.error)
  $util.error($ctx.error.message, $ctx.error.type, $ctx.result)
#end
  $util.toJson($ctx.result)
```

`InternalExceptions` 또는 `Timeouts`와 같은 `PutEvents` 작업을 수행하는 동안 발생하는 오류는 `$ctx.error`에 표시됩니다. EventBridge의 일반적인 오류 목록은 [EventBridge 일반 오류 참조](https://docs.aws.amazon.com/eventbridge/latest/APIReference/CommonErrors.html)를 참조하세요.

`result`는 다음 형식을 따릅니다.

```
{
    "Entries" [
        {
            "ErrorCode" : String,
            "ErrorMessage" : String,
            "EventId" : String
        }
    ],
    "FailedEntryCount" : number
}
```
+ **항목**

  수집된 이벤트 결과(성공 및 실패 모두) 수집이 성공하면 항목에 `EventID`가 포함됩니다. 그렇지 않으면 `ErrorCode` 및 `ErrorMessage`를 사용하여 항목의 문제를 식별할 수 있습니다.

  각 레코드의 응답 요소의 인덱스는 요청 배열의 인덱스와 동일합니다.
+ **FailedEntryCount**

  실패한 항목 수입니다. 이 값은 정수로 표시됩니다.

`PutEvents`의 응답에 대한 자세한 내용은 [PutEvents](https://docs.aws.amazon.com/eventbridge/latest/APIReference/API_PutEvents.html#API_PutEvents_ResponseElements)를 참조하세요.

**예제 샘플 응답 1**

다음 예는 두 개의 성공적인 이벤트가 있는 `PutEvents` 작업입니다.

```
{
    "Entries" : [ 
        {
            "EventId": "11710aed-b79e-4468-a20b-bb3c0c3b4860"
        }, 
        {
            "EventId": "d804d26a-88db-4b66-9eaf-9a11c708ae82"
        }
    ],
    "FailedEntryCount" : 0
}
```

**예제 샘플 응답 2**

다음 예는 3개의 이벤트(성공 2개, 실패 1개)가 있는 `PutEvents` 작업입니다.

```
{
    "Entries" : [ 
        {
            "EventId": "11710aed-b79e-4468-a20b-bb3c0c3b4860"
        }, 
        {
            "EventId": "d804d26a-88db-4b66-9eaf-9a11c708ae82"
        },
        {
            "ErrorCode" : "SampleErrorCode",
            "ErrorMessage" : "Sample Error Message"
        }
    ],
    "FailedEntryCount" : 1
}
```

## `PutEvents` 필드
<a name="putevents-field"></a>

`PutEvents`에는 다음 매핑 템플릿 필드가 포함되어 있습니다.
+ **버전**

  모든 요청 매핑 템플릿에 공통적으로 적용되는 `version` 필드는 템플릿이 사용하는 버전을 정의합니다. 이 필드는 필수 항목입니다. 값 `2018-05-29`는 EventBridge 매핑 템플릿에 지원되는 유일한 버전입니다.
+ **작업**

  지원되는 유일한 작업은 `PutEvents`입니다. 이 작업을 통해 이벤트 버스에 사용자 지정 이벤트를 추가할 수 있습니다.
+ **이벤트**

  이벤트 버스에 추가될 이벤트 배열입니다. 이 배열에는 1\$110개의 항목이 할당되어야 합니다.

  `Event` 객체는 다음 필드를 포함하는 유효한 JSON 객체입니다.
  + `"source"`: 이벤트 소스를 정의하는 문자열입니다.
  + `"detail"`: 이벤트에 대한 정보를 첨부하는 데 사용할 수 있는 JSON 객체입니다. 이 필드는 빈 맵(`{ }`)일 수 있습니다.
  + `"detailType`: 스토리지의 유형을 식별하는 문자열입니다.
  + `"resources"`: 이벤트와 관련된 리소스를 식별하는 문자열의 JSON 배열입니다. 이 필드는 빈 배열일 수 있습니다.
  + `"time"`: 이벤트 타임스탬프는 문자열로 제공됩니다. 이는 [RFC3339](https://www.rfc-editor.org/rfc/rfc3339.txt) 타임스탬프 형식을 따라야 합니다.

다음은 유효한 `Event` 객체의 몇 가지 예시입니다.

**예제 1**.

```
{
    "source" : "source1",
    "detail" : {
        "key1" : [1,2,3,4],
        "key2" : "strval"
    },
    "detailType" : "sampleDetailType",
    "resources" : ["Resouce1", "Resource2"],
    "time" : "2022-01-10T05:00:10Z"
}
```

**예제 2**.

```
{
    "source" : "source1",
    "detail" : {},
    "detailType" : "sampleDetailType"
}
```

**예 3**

```
{
    "source" : "source1",
    "detail" : {
        "key1" : 1200
    },
    "detailType" : "sampleDetailType",
    "resources" : []
}
```

# `None` 데이터 소스에 대한 AWS AppSync 해석기 매핑 템플릿 참조
<a name="resolver-mapping-template-reference-none"></a>

**참고**  
이제 우리는 주로 APPSYNC\$1JS 런타임과 해당 문서를 지원합니다. [여기](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)에서 APPSYNC\$1JS 런타임과 해당 안내서를 사용해 보세요.

*None* 유형의 데이터 소스와 함께 사용되는 AWS AppSync 해석기 매핑 템플릿을 사용하면 AWS AppSync 로컬 작업에 대한 요청을 구성할 수 있습니다.

## 요청 매핑 템플릿
<a name="request-mapping-template"></a>

매핑 템플릿은 단순하며 `payload` 필드를 통해 가능한 많은 컨텍스트 정보를 전달할 수 있습니다.

```
{
   "version": string,
   "payload": any type
}
```

다음은 해석되고 난 요청 매핑 템플릿의 JSON 스키마 표현입니다.

```
{
    "definitions": {},
    "$schema": "https://json-schema.org/draft-06/schema#",
    "$id": "https://aws.amazon.com/appsync/request-mapping-template.json",
    "type": "object",
    "properties": {
        "version": {
            "$id": "/properties/version",
            "type": "string",
            "enum": [
                "2018-05-29"
            ],
            "title": "The Mapping template version.",
            "default": "2018-05-29"
        },
        "payload": {}
    },
    "required": [
        "version"
    ],
    "additionalProperties": false
}
```

다음은 VTL 컨텍스트 속성 `$context.arguments`를 통한 필드 인수 전달의 예입니다.

```
{
    "version": "2018-05-29",
    "payload": $util.toJson($context.arguments)
}
```

`payload` 필드의 값이 응답 매핑 템플릿으로 전달되어 VTL 컨텍스트 속성(`$context.result`)에서 사용할 수 있습니다.

다음은 `payload` 필드의 보간 값을 나타내는 예제입니다.

```
{
    "id": "postId1"
}
```

## 버전
<a name="version"></a>

모든 요청 매핑 템플릿에 공통된 `version` 필드는 템플릿에 사용되는 버전을 정의합니다.

 `version` 필드는 필수 사항입니다.

예제:

```
"version": "2018-05-29"
```

## Payload
<a name="payload"></a>

`payload` 필드는 올바른 형식의 JSON을 응답 매핑 템플릿으로 전달하는 데 사용할 수 있는 컨테이너입니다.

 `payload` 필드는 선택 사항입니다.

## 응답 매핑 템플릿
<a name="response-mapping-template"></a>

데이터 원본이 없으므로 `payload` 필드의 값이 응답 매핑 템플릿으로 전달되고 VTL `context` 속성을 통해 제공되는 `$context.result` 객체에서 설정됩니다.

`payload` 필드 값의 모양이 GraphQL 유형의 모양과 정확히 일치하는 경우 다음 응답 매핑 템플릿을 사용하여 응답을 전달할 수 있습니다.

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

응답 매핑 템플릿에 적용되는 필수 필드 또는 모양 제한이 없습니다. 하지만 GraphQL은 강력한 형식이므로 해석된 매핑 템플릿이 필요한 GraphQL 유형과 일치해야 합니다.

# HTTP용 AWS AppSync 해석기 매핑 템플릿 참조
<a name="resolver-mapping-template-reference-http"></a>

**참고**  
이제 우리는 주로 APPSYNC\$1JS 런타임과 해당 문서를 지원합니다. [여기](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)에서 APPSYNC\$1JS 런타임과 해당 안내서를 사용해 보세요.

 AWS AppSync HTTP 해석기 매핑 템플릿을 사용하면 AWS AppSync에서 모든 HTTP 엔드포인트로 요청을 보내고 HTTP 엔드포인트의 응답을 AWS AppSync로 다시 보낼 수 있습니다. 매핑 템플릿을 사용하면 호출할 작업의 특성에 대한 힌트를 AWS AppSync에 제공할 수 있습니다. 이 단원에서는 지원되는 HTTP 해석기에 대한 다양한 매핑 템플릿에 대해 설명합니다.

## 요청 매핑 템플릿
<a name="request-mapping-template"></a>

```
{
    "version": "2018-05-29",
    "method": "PUT|POST|GET|DELETE|PATCH",
    "params": {
        "query": Map,
        "headers": Map,
        "body": any
    },
    "resourcePath": string
}
```

HTTP 요청 매핑 템플릿을 해석한 후 요청 매핑 템플릿의 JSON 스키마 표현은 아래와 같습니다.

```
{
    "$id": "https://aws.amazon.com/appsync/request-mapping-template.json",
    "type": "object",
    "properties": {
        "version": {
        "$id": "/properties/version",
        "type": "string",
        "title": "The Version Schema ",
        "default": "",
        "examples": [
            "2018-05-29"
        ],
        "enum": [
            "2018-05-29"
        ]
        },
        "method": {
        "$id": "/properties/method",
        "type": "string",
        "title": "The Method Schema ",
        "default": "",
        "examples": [
            "PUT|POST|GET|DELETE|PATCH"
        ],
        "enum": [
            "PUT",
            "PATCH",
            "POST",
            "DELETE",
            "GET"
        ]
        },
        "params": {
        "$id": "/properties/params",
        "type": "object",
        "properties": {
            "query": {
            "$id": "/properties/params/properties/query",
            "type": "object"
            },
            "headers": {
            "$id": "/properties/params/properties/headers",
            "type": "object"
            },
            "body": {
            "$id": "/properties/params/properties/body",
            "type": "string",
            "title": "The Body Schema ",
            "default": "",
            "examples": [
                ""
            ]
            }
        }
        },
        "resourcePath": {
        "$id": "/properties/resourcePath",
        "type": "string",
        "title": "The Resourcepath Schema ",
        "default": "",
        "examples": [
            ""
        ]
        }
    },
    "required": [
        "version",
        "method",
        "resourcePath"
    ]
}
```

다음은 `text/plain` 본문을 포함한 HTTP POST 요청의 예입니다.

```
{
    "version": "2018-05-29",
    "method": "POST",
    "params": {
        "headers":{
        "Content-Type":"text/plain"
        },
        "body":"this is an example of text body"
    },
    "resourcePath": "/"
}
```

## 버전
<a name="version"></a>

**참고**  
이는 요청 매핑 템플릿에만 적용됩니다.

템플릿에 사용되는 버전을 정의합니다. `version`은 모든 요청 매핑 템플릿에 공통되며 필수입니다.

```
"version": "2018-05-29"
```

## 방법
<a name="method"></a>

**참고**  
이는 요청 매핑 템플릿에만 적용됩니다.

 AWS AppSync가 HTTP 엔드포인트로 전송하는 HTTP 메서드 또는 동사(GET, POST, PUT, PATCH 또는 DELETE).

```
"method": "PUT"
```

## ResourcePath
<a name="resourcepath"></a>

**참고**  
이는 요청 매핑 템플릿에만 적용됩니다.

액세스하고자 하는 리소스 경로입니다. 리소스 경로는 HTTP 데이터 소스의 엔드포인트와 함께 AWS AppSync 서비스가 요청하는 URL을 형성합니다.

```
"resourcePath": "/v1/users"
```

매핑 템플릿이 평가되면 이 경로는 HTTP 엔드포인트를 포함해 HTTP 요청의 일부로 전송됩니다. 예를 들어, 이전 예제는 다음과 같이 변환될 수 있습니다.

```
PUT <endpoint>/v1/users
```

## 파라미터 필드
<a name="params-field"></a>

**참고**  
이는 요청 매핑 템플릿에만 적용됩니다.

검색에서 수행할 작업을 지정하는 데 사용되며, 가장 일반적으로 **본문** 내에 **쿼리** 값을 설정하여 지정합니다. 그러나 응답 형식 지정 등과 같이 구성할 수 있는 기타 여러 가지 기능이 있습니다.

** **headers** **  
키-값 페어로 표시되는 헤더 정보. 키와 값은 둘 다 문자열이어야 합니다.  
예제:  

```
"headers" : {
    "Content-Type" : "application/json"
}
```
현재 지원되는 `Content-Type` 헤더는 다음과 같습니다.  

```
text/*
application/xml
application/json
application/soap+xml
application/x-amz-json-1.0
application/x-amz-json-1.1
application/vnd.api+json
application/x-ndjson
```
 **참고**: 다음 HTTP 헤더를 설정할 수 없습니다.  

```
HOST
CONNECTION
USER-AGENT
EXPECTATION
TRANSFER_ENCODING
CONTENT_LENGTH
```

** **query** **  
JSON 응답에 대한 코드 형식 지정 등과 같이 공통 옵션을 지정하는 키-값 페어. 키와 값은 둘 다 문자열이어야 합니다. 다음 예제는 쿼리 문자열을 `?type=json`으로 보낼 방법을 보여줍니다.  

```
"query" : {
    "type" : "json"
}
```

** **body** **  
본문에는 설정을 선택하는 HTTP 요청 본문이 포함됩니다. 콘텐츠 유형이 charset을 지정하지 않는 한 요청 본문은 항상 UTF-8 인코딩된 문자열입니다.  

```
"body":"body string"
```

## 응답
<a name="response"></a>

[여기](https://docs.aws.amazon.com/appsync/latest/devguide/tutorial-http-resolvers.html)에서 예시를 확인하세요.

# HTTPS 엔드포인트에 대해 AWS AppSync가 인정하는 인증 기관(CA)
<a name="http-cert-authorities"></a>

**참고**  
Let's Encrypt는 *identrust* 및 *isrgrootx1* 인증서를 통해 승인됩니다. Let's Encrypt를 사용하는 경우 별도의 조치가 필요하지 않습니다.

현재 HTTPS를 사용하는 경우 HTTP 해석기는 자체 서명된 인증서를 지원하지 않습니다. AWS AppSync는 HTTPS용 SSL/TLS 인증서를 해석할 때 다음과 같은 인증 기관을 인식합니다.


**AWS AppSync의 알려진 루트 인증서**  

|  이름 | 날짜 | SHA1 지문 | 
| --- | --- | --- | 
| digicertassuredidrootca |  2018년 4월 21일 | 05:63:B8:63:0D:62:D7:5A:BB:C8:AB:1E:4B:DF:B5:A8:99:B2:4D:43 | 
| trustcenterclass2caii |  2018년 4월 21일 | AE:50:83:ED:7C:F4:5C:BC:8F:61:C6:21:FE:68:5D:79:42:21:15:6E | 
| thawtepremiumserverca |  2018년 4월 21일 | E0:AB:05:94:20:72:54:93:05:60:62:02:36:70:F7:CD:2E:FC:66:66 | 
| cia-crt-g3-02-ca |  2016년 11월 23일 | 96:4A:BB:A7:BD:DA:FC:97:34:C0:0A:2D:F0:05:98:F7:E6:C6:6F:09 | 
| swisssignplatinumg2ca |  2018년 4월 21일 | 56:E0:FA:C0:3B:8F:18:23:55:18:E5:D3:11:CA:E8:C2:43:31:AB:66 | 
| swisssignsilverg2ca |  2018년 4월 21일 | 9B:AA:E5:9F:56:EE:21:CB:43:5A:BE:25:93:DF:A7:F0:40:D1:1D:CB | 
| thawteserverca |  2018년 4월 21일 | 9F:AD:91:A6:CE:6A:C6:C5:00:47:C4:4E:C9:D4:A5:0D:92:D8:49:79 | 
| equifaxsecureebusinessca1 |  2018년 4월 21일 | AE:E6:3D:70:E3:76:FB:C7:3A:EB:B0:A1:C1:D4:C4:7A:A7:40:B3:F4 | 
| securetrustca |  2018년 4월 21일 | 87:82:C6:C3:04:35:3B:CF:D2:96:92:D2:59:3E:7D:44:D9:34:FF:11 | 
| utnuserfirstclientauthemailca |  2018년 4월 21일 | B1:72:B1:A5:6D:95:F9:1F:E5:02:87:E1:4D:37:EA:6A:44:63:76:8A | 
| thawtepersonalfreemailca |  2018년 4월 21일 | E6:18:83:AE:84:CA:C1:C1:CD:52:AD:E8:E9:25:2B:45:A6:4F:B7:E2 | 
| affirmtrustnetworkingca |  2018년 4월 21일 | 29:36:21:02:8B:20:ED:02:F5:66:C5:32:D1:D6:ED:90:9F:45:00:2F | 
| entrustevca |  2018년 4월 21일 | B3:1E:B1:B7:40:E3:6C:84:02:DA:DC:37:D4:4D:F5:D4:67:49:52:F9 | 
| utnuserfirsthardwareca |  2018년 4월 21일 | 04:83:ED:33:99:AC:36:08:05:87:22:ED:BC:5E:46:00:E3:BE:F9:D7 | 
| certumca |  2018년 4월 21일 | 62:52:DC:40:F7:11:43:A2:2F:DE:9E:F7:34:8E:06:42:51:B1:81:18 | 
| addtrustclass1ca |  2018년 4월 21일 | CC:AB:0E:A0:4C:23:01:D6:69:7B:DD:37:9F:CD:12:EB:24:E3:94:9D | 
| entrustrootcag2 |  2018년 4월 21일 | 8C:F4:27:FD:79:0C:3A:D1:66:06:8D:E8:1E:57:EF:BB:93:22:72:D4 | 
| equifaxsecureca |  2018년 4월 21일 | D2:32:09:AD:23:D3:14:23:21:74:E4:0D:7F:9D:62:13:97:86:63:3A | 
| quovadisrootca3 |  2018년 4월 21일 | 1F:49:14:F7:D8:74:95:1D:DD:AE:02:C0:BE:FD:3A:2D:82:75:51:85 | 
| quovadisrootca2 |  2018년 4월 21일 | CA:3A:FB:CF:12:40:36:4B:44:B2:16:20:88:80:48:39:19:93:7C:F7 | 
| digicertglobalrootg2 |  2018년 4월 21일 | DF:3C:24:F9:BF:D6:66:76:1B:26:80:73:FE:06:D1:CC:8D:4F:82:A4 | 
| digicerthighassuranceevrootca |  2018년 4월 21일 | 5F:B7:EE:06:33:E2:59:DB:AD:0C:4C:9A:E6:D3:8F:1A:61:C7:DC:25 | 
| secomvalicertclass1ca |  2018년 4월 21일 | E5:DF:74:3C:B6:01:C4:9B:98:43:DC:AB:8C:E8:6A:81:10:9F:E4:8E | 
| equifaxsecureglobalebusinessca1 |  2018년 4월 21일 | 3A:74:CB:7A:47:DB:70:DE:89:1F:24:35:98:64:B8:2D:82:BD:1A:36 | 
| geotrustuniversalca |  2018년 4월 21일 | E6:21:F3:35:43:79:05:9A:4B:68:30:9D:8A:2F:74:22:15:87:EC:79 | 
| deprecateditsecca |  2012년 1월 27일 | 12:12:0B:03:0E:15:14:54:F4:DD:B3:F5:DE:13:6E:83:5A:29:72:9D | 
| verisignclass3ca |  2018년 4월 21일 | A1:DB:63:93:91:6F:17:E4:18:55:09:40:04:15:C7:02:40:B0:AE:6B | 
| thawteprimaryrootcag3 |  2018년 4월 21일 | F1:8B:53:8D:1B:E9:03:B6:A6:F0:56:43:5B:17:15:89:CA:F3:6B:F2 | 
| thawteprimaryrootcag2 |  2018년 4월 21일 | AA:DB:BC:22:23:8F:C4:01:A1:27:BB:38:DD:F4:1D:DB:08:9E:F0:12 | 
| deutschetelekomrootca2 |  2018년 4월 21일 | 85:A4:08:C0:9C:19:3E:5D:51:58:7D:CD:D6:13:30:FD:8C:DE:37:BF | 
| buypassclass3ca |  2018년 4월 21일 | DA:FA:F7:FA:66:84:EC:06:8F:14:50:BD:C7:C2:81:A5:BC:A9:64:57 | 
| utnuserfirstobjectca |  2018년 4월 21일 | E1:2D:FB:4B:41:D7:D9:C3:2B:30:51:4B:AC:1D:81:D8:38:5E:2D:46 | 
| geotrustprimaryca |  2018년 4월 21일 | 32:3C:11:8E:1B:F7:B8:B6:52:54:E2:E2:10:0D:D6:02:90:37:F0:96 | 
| buypassclass2ca |  2018년 4월 21일 | 49:0A:75:74:DE:87:0A:47:FE:58:EE:F6:C7:6B:EB:C6:0B:12:40:99 | 
| baltimorecodesigningca |  2018년 4월 21일 | 30:46:D8:C8:88:FF:69:30:C3:4A:FC:CD:49:27:08:7C:60:56:7B:0D | 
| verisignclass1ca |  2018년 4월 21일 | CE:6A:64:A3:09:E4:2F:BB:D9:85:1C:45:3E:64:09:EA:E8:7D:60:F1 | 
| baltimorecybertrustca |  2018년 4월 21일 | D4:DE:20:D0:5E:66:FC:53:FE:1A:50:88:2C:78:DB:28:52:CA:E4:74 | 
| starfieldclass2ca |  2018년 4월 21일 | AD:7E:1C:28:B0:64:EF:8F:60:03:40:20:14:C3:D0:E3:37:0E:B5:8A | 
| camerfirmachamberscommerceca |  2018년 4월 21일 | 6E:3A:55:A4:19:0C:19:5C:93:84:3C:C0:DB:72:2E:31:30:61:F0:B1 | 
| ttelesecglobalrootclass3ca |  2018년 4월 21일 | 55:A6:72:3E:CB:F2:EC:CD:C3:23:74:70:19:9D:2A:BE:11:E3:81:D1 | 
| verisignclass3g5ca |  2018년 4월 21일 | 4E:B6:D5:78:49:9B:1C:CF:5F:58:1E:AD:56:BE:3D:9B:67:44:A5:E5 | 
| ttelesecglobalrootclass2ca |  2018년 4월 21일 | 59:0D:2D:7D:88:4F:40:2E:61:7E:A5:62:32:17:65:CF:17:D8:94:E9 | 
| trustcenteruniversalcai |  2018년 4월 21일 | 6B:2F:34:AD:89:58:BE:62:FD:B0:6B:5C:CE:BB:9D:D9:4F:4E:39:F3 | 
| verisignclass3g4ca |  2018년 4월 21일 | 22:D5:D8:DF:8F:02:31:D1:8D:F7:9D:B7:CF:8A:2D:64:C9:3F:6C:3A | 
| verisignclass3g3ca |  2018년 4월 21일 | 13:2D:0D:45:53:4B:69:97:CD:B2:D5:C3:39:E2:55:76:60:9B:5C:C6 | 
| xrampglobalca |  2018년 4월 21일 | B8:01:86:D1:EB:9C:86:A5:41:04:CF:30:54:F3:4C:52:B7:E5:58:C6 | 
| amzninternalrootca |  2008년 12월 12일 | A7:B7:F6:15:8A:FF:1E:C8:85:13:38:BC:93:EB:A2:AB:A4:09:EF:06 | 
| certplusclass3pprimaryca |  2018년 4월 21일 | 21:6B:2A:29:E6:2A:00:CE:82:01:46:D8:24:41:41:B9:25:11:B2:79 | 
| certumtrustednetworkca |  2018년 4월 21일 | 07:E0:32:E0:20:B7:2C:3F:19:2F:06:28:A2:59:3A:19:A7:0F:06:9E | 
| verisignclass3g2ca |  2018년 4월 21일 | 85:37:1C:A6:E5:50:14:3D:CE:28:03:47:1B:DE:3A:09:E8:F8:77:0F | 
| globalsignr3ca |  2018년 4월 21일 | D6:9B:56:11:48:F0:1C:77:C5:45:78:C1:09:26:DF:5B:85:69:76:AD | 
| utndatacorpsgcca |  2018년 4월 21일 | 58:11:9F:0E:12:82:87:EA:50:FD:D9:87:45:6F:4F:78:DC:FA:D6:D4 | 
| secomscrootca2 |  2018년 4월 21일 | 5F:3B:8C:F2:F8:10:B3:7D:78:B4:CE:EC:19:19:C3:73:34:B9:C7:74 | 
| gtecybertrustglobalca |  2018년 4월 21일 | 97:81:79:50:D8:1C:96:70:CC:34:D8:09:CF:79:44:31:36:7E:F4:74 | 
| secomscrootca1 |  2018년 4월 21일 | 36:B1:2B:49:F9:81:9E:D7:4C:9E:BC:38:0F:C6:56:8F:5D:AC:B2:F7 | 
| affirmtrustcommercialca |  2018년 4월 21일 | F9:B5:B6:32:45:5F:9C:BE:EC:57:5F:80:DC:E9:6E:2C:C7:B2:78:B7 | 
| trustcenterclass4caii |  2018년 4월 21일 | A6:9A:91:FD:05:7F:13:6A:42:63:0B:B1:76:0D:2D:51:12:0C:16:50 | 
| verisignuniversalrootca |  2018년 4월 21일 | 36:79:CA:35:66:87:72:30:4D:30:A5:FB:87:3B:0F:A7:7B:B7:0D:54 | 
| globalsignr2ca |  2018년 4월 21일 | 75:E0:AB:B6:13:85:12:27:1C:04:F8:5F:DD:DE:38:E4:B7:24:2E:FE | 
| certplusclass2primaryca |  2018년 4월 21일 | 74:20:74:41:72:9C:DD:92:EC:79:31:D8:23:10:8D:C2:81:92:E2:BB | 
| digicertglobalrootca |  2018년 4월 21일 | A8:98:5D:3A:65:E5:E5:C4:B2:D7:D6:6D:40:C6:DD:2F:B1:9C:54:36 | 
| globalsignca |  2018년 4월 21일 | B1:BC:96:8B:D4:F4:9D:62:2A:A8:9A:81:F2:15:01:52:A4:1D:82:9C | 
| thawteprimaryrootca |  2018년 4월 21일 | 91:C6:D6:EE:3E:8A:C8:63:84:E5:48:C2:99:29:5C:75:6C:81:7B:81 | 
| starfieldrootg2ca |  2018년 4월 21일 | B5:1C:06:7C:EE:2B:0C:3D:F8:55:AB:2D:92:F4:FE:39:D4:E7:0F:0E | 
| geotrustglobalca |  2018년 4월 21일 | DE:28:F4:A4:FF:E5:B9:2F:A3:C5:03:D1:A3:49:A7:F9:96:2A:82:12 | 
| soneraclass2ca |  2018년 4월 21일 | 37:F7:6D:E6:07:7C:90:C5:B1:3E:93:1A:B7:41:10:B4:F2:E4:9A:27 | 
| verisigntsaca |  2018년 4월 21일 | 20:CE:B1:F0:F5:1C:0E:19:A9:F3:8D:B1:AA:8E:03:8C:AA:7A:C7:01 | 
| soneraclass1ca |  2018년 4월 21일 | 07:47:22:01:99:CE:74:B9:7C:B0:3D:79:B2:64:A2:C8:55:E9:33:FF | 
| quovadisrootca |  2018년 4월 21일 | DE:3F:40:BD:50:93:D3:9B:6C:60:F6:DA:BC:07:62:01:00:89:76:C9 | 
| affirmtrustpremiumeccca |  2018년 4월 21일 | B8:23:6B:00:2F:1D:16:86:53:01:55:6C:11:A4:37:CA:EB:FF:C3:BB | 
| starfieldservicesrootg2ca |  2018년 4월 21일 | 92:5A:8F:8D:2C:6D:04:E0:66:5F:59:6A:FF:22:D8:63:E8:25:6F:3F | 
| valicertclass2ca |  2018년 4월 21일 | 31:7A:2A:D0:7F:2B:33:5E:F5:A1:C3:4E:4B:57:E8:B7:D8:F1:FC:A6 | 
| comodoaaaca |  2018년 4월 21일 | D1:EB:23:A4:6D:17:D6:8F:D9:25:64:C2:F1:F1:60:17:64:D8:E3:49 | 
| aolrootca2 |  2018년 4월 21일 | 85:B5:FF:67:9B:0C:79:96:1F:C8:6E:44:22:00:46:13:DB:17:92:84 | 
| keynectisrootca |  2018년 4월 21일 | 9C:61:5C:4D:4D:85:10:3A:53:26:C2:4D:BA:EA:E4:A2:D2:D5:CC:97 | 
| addtrustqualifiedca |  2018년 4월 21일 | 4D:23:78:EC:91:95:39:B5:00:7F:75:8F:03:3B:21:1E:C5:4D:8B:CF | 
| aolrootca1 |  2018년 4월 21일 | 39:21:C1:15:C1:5D:0E:CA:5C:CB:5B:C4:F0:7D:21:D8:05:0B:56:6A | 
| verisignclass2g3ca |  2018년 4월 21일 | 61:EF:43:D7:7F:CA:D4:61:51:BC:98:E0:C3:59:12:AF:9F:EB:63:11 | 
| addtrustexternalca |  2018년 4월 21일 | 02:FA:F3:E2:91:43:54:68:60:78:57:69:4D:F5:E4:5B:68:85:18:68 | 
| verisignclass2g2ca |  2018년 4월 21일 | B3:EA:C4:47:76:C9:C8:1C:EA:F2:9D:95:B6:CC:A0:08:1B:67:EC:9D | 
| geotrustprimarycag3 |  2018년 4월 21일 | 03:9E:ED:B8:0B:E7:A0:3C:69:53:89:3B:20:D2:D9:32:3A:4C:2A:FD | 
| geotrustprimarycag2 |  2018년 4월 21일 | 8D:17:84:D5:37:F3:03:7D:EC:70:FE:57:8B:51:9A:99:E6:10:D7:B0 | 
| swisssigngoldg2ca |  2018년 4월 21일 | D8:C5:38:8A:B7:30:1B:1B:6E:D4:7A:E6:45:25:3A:6F:9F:1A:27:61 | 
| entrust2048ca |  2018년 4월 21일 | 50:30:06:09:1D:97:D4:F5:AE:39:F7:CB:E7:92:7D:7D:65:2D:34:31 | 
| chunghwaepkirootca |  2018년 4월 21일 | 67:65:0D:F1:7E:8E:7E:5B:82:40:A4:F4:56:4B:CF:E2:3D:69:C6:F0 | 
| camerfirmachambersignca |  2018년 4월 21일 | 4A:BD:EE:EC:95:0D:35:9C:89:AE:C7:52:A1:2C:5B:29:F6:D6:AA:0C | 
| camerfirmachambersca |  2018년 4월 21일 | 78:6A:74:AC:76:AB:14:7F:9C:6A:30:50:BA:9E:A8:7E:FE:9A:CE:3C | 
| godaddyclass2ca |  2018년 4월 21일 | 27:96:BA:E6:3F:18:01:E2:77:26:1B:A0:D7:77:70:02:8F:20:EE:E4 | 
| affirmtrustpremiumca |  2018년 4월 21일 | D8:A6:33:2C:E0:03:6F:B1:85:F6:63:4F:7D:6A:06:65:26:32:28:27 | 
| verisignclass1g3ca |  2018년 4월 21일 | 20:42:85:DC:F7:EB:76:41:95:57:8E:13:6B:D4:B7:D1:E9:8E:46:A5 | 
| secomevrootca1 |  2018년 4월 21일 | FE:B8:C4:32:DC:F9:76:9A:CE:AE:3D:D8:90:8F:FD:28:86:65:64:7D | 
| verisignclass1g2ca |  2018년 4월 21일 | 27:3E:E1:24:57:FD:C4:F9:0C:55:E8:2B:56:16:7F:62:F5:32:E5:47 | 
| amzninternalinfoseccag3 |  2015년 2월 27일 | B9:B1:CA:38:F7:BF:9C:D2:D4:95:E7:B6:5E:75:32:9B:A8:78:2E:F6 | 
| cia-crt-g3-01-ca |  2016년 11월 23일 | 2B:EE:2C:BA:A3:1D:B5:FE:60:40:41:95:08:ED:46:82:39:4D:ED:E2 | 
| godaddyrootg2ca |  2018년 4월 21일 | 47:BE:AB:C9:22:EA:E8:0E:78:78:34:62:A7:9F:45:C2:54:FD:E6:8B | 
| digicertassuredidrootca |  2018년 4월 21일 | 05:63:B8:63:0D:62:D7:5A:BB:C8:AB:1E:4B:DF:B5:A8:99:B2:4D:43 | 
| microseceszignorootca2009 |  2018년 4월 21일 | 89:DF:74:FE:5C:F4:0F:4A:80:F9:E3:37:7D:54:DA:91:E1:01:31:8E | 
| affirmtrustcommercial |  2018년 4월 21일 | F9:B5:B6:32:45:5F:9C:BE:EC:57:5F:80:DC:E9:6E:2C:C7:B2:78:B7 | 
| comodoecccertificationauthority |  2018년 4월 21일 | 9F:74:4E:9F:2B:4D:BA:EC:0F:31:2C:50:B6:56:3B:8E:2D:93:C3:11 | 
| cadisigrootr2 |  2018년 4월 21일 | B5:61:EB:EA:A4:DE:E4:25:4B:69:1A:98:A5:57:47:C2:34:C7:D9:71 | 
| swisssignsilvercag2 |  2018년 4월 21일 | 9B:AA:E5:9F:56:EE:21:CB:43:5A:BE:25:93:DF:A7:F0:40:D1:1D:CB | 
| securetrustca |  2018년 4월 21일 | 87:82:C6:C3:04:35:3B:CF:D2:96:92:D2:59:3E:7D:44:D9:34:FF:11 | 
| cadisigrootr1 |  2018년 4월 21일 | 8E:1C:74:F8:A6:20:B9:E5:8A:F4:61:FA:EC:2B:47:56:51:1A:52:C6 | 
| accvraiz1 |  2018년 4월 21일 | 93:05:7A:88:15:C6:4F:CE:88:2F:FA:91:16:52:28:78:BC:53:64:17 | 
| entrustrootcertificationauthority |  2018년 4월 21일 | B3:1E:B1:B7:40:E3:6C:84:02:DA:DC:37:D4:4D:F5:D4:67:49:52:F9 | 
| camerfirmaglobalchambersignroot |  2018년 4월 21일 | 33:9B:6B:14:50:24:9B:55:7A:01:87:72:84:D9:E0:2F:C3:D2:D8:E9 | 
| dstacescax6 |  2018년 4월 21일 | 40:54:DA:6F:1C:3F:40:74:AC:ED:0F:EC:CD:DB:79:D1:53:FB:90:1D | 
| identrustpublicsectorrootca1 |  2018년 4월 21일 | BA:29:41:60:77:98:3F:F4:F3:EF:F2:31:05:3B:2E:EA:6D:4D:45:FD | 
| starfieldrootcertificateauthorityg2 |  2018년 4월 21일 | B5:1C:06:7C:EE:2B:0C:3D:F8:55:AB:2D:92:F4:FE:39:D4:E7:0F:0E | 
| secureglobalca |  2018년 4월 21일 | 3A:44:73:5A:E5:81:90:1F:24:86:61:46:1E:3B:9C:C4:5F:F5:3A:1B | 
| eecertificationcentrerootca |  2018년 4월 21일 | C9:A8:B9:E7:55:80:5E:58:E3:53:77:A7:25:EB:AF:C3:7B:27:CC:D7 | 
| opentrustrootcag3 |  2018년 4월 21일 | 6E:26:64:F3:56:BF:34:55:BF:D1:93:3F:7C:01:DE:D8:13:DA:8A:A6 | 
| teliasonerarootcav1 |  2018년 4월 21일 | 43:13:BB:96:F1:D5:86:9B:C1:4E:6A:92:F6:CF:F6:34:69:87:82:37 | 
| autoridaddecertificacionfirmaprofesionalcifa62634068 |  2018년 4월 21일 | AE:C5:FB:3F:C8:E1:BF:C4:E5:4F:03:07:5A:9A:E8:00:B7:F7:B6:FA | 
| opentrustrootcag2 |  2018년 4월 21일 | 79:5F:88:60:C5:AB:7C:3D:92:E6:CB:F4:8D:E1:45:CD:11:EF:60:0B | 
| opentrustrootcag1 |  2018년 4월 21일 | 79:91:E8:34:F7:E2:EE:DD:08:95:01:52:E9:55:2D:14:E9:58:D5:7E | 
| globalsigneccrootcar5 |  2018년 4월 21일 | 1F:24:C6:30:CD:A4:18:EF:20:69:FF:AD:4F:DD:5F:46:3A:1B:69:AA | 
| globalsigneccrootcar4 |  2018년 4월 21일 | 69:69:56:2E:40:80:F4:24:A1:E7:19:9F:14:BA:F3:EE:58:AB:6A:BB | 
| izenpecom |  2018년 4월 21일 | 2F:78:3D:25:52:18:A7:4A:65:39:71:B5:2C:A2:9C:45:15:6F:E9:19 | 
| turktrustelektroniksertifikahizmetsaglayicisih5 |  2018년 4월 21일 | C4:18:F6:4D:46:D1:DF:00:3D:27:30:13:72:43:A9:12:11:C6:75:FB | 
| gdcatrustauthr5root |  2018년 4월 21일 | 0F:36:38:5B:81:1A:25:C3:9B:31:4E:83:CA:E9:34:66:70:CC:74:B4 | 
| dtrustrootclass3ca22009 |  2018년 4월 21일 | 58:E8:AB:B0:36:15:33:FB:80:F7:9B:1B:6D:29:D3:FF:8D:5F:00:F0 | 
| quovadisrootca3 |  2018년 4월 21일 | 1F:49:14:F7:D8:74:95:1D:DD:AE:02:C0:BE:FD:3A:2D:82:75:51:85 | 
| quovadisrootca2 |  2018년 4월 21일 | CA:3A:FB:CF:12:40:36:4B:44:B2:16:20:88:80:48:39:19:93:7C:F7 | 
| geotrustprimarycertificationauthorityg3 |  2018년 4월 21일 | 03:9E:ED:B8:0B:E7:A0:3C:69:53:89:3B:20:D2:D9:32:3A:4C:2A:FD | 
| geotrustprimarycertificationauthorityg2 |  2018년 4월 21일 | 8D:17:84:D5:37:F3:03:7D:EC:70:FE:57:8B:51:9A:99:E6:10:D7:B0 | 
| oistewisekeyglobalrootgbca |  2018년 4월 21일 | 0F:F9:40:76:18:D3:D7:6A:4B:98:F0:A8:35:9E:0C:FD:27:AC:CC:ED | 
| addtrustexternalroot |  2018년 4월 21일 | 02:FA:F3:E2:91:43:54:68:60:78:57:69:4D:F5:E4:5B:68:85:18:68 | 
| chambersofcommerceroot2008 |  2018년 4월 21일 | 78:6A:74:AC:76:AB:14:7F:9C:6A:30:50:BA:9E:A8:7E:FE:9A:CE:3C | 
| digicertglobalrootg3 |  2018년 4월 21일 | 7E:04:DE:89:6A:3E:66:6D:00:E6:87:D3:3F:FA:D9:3B:E8:3D:34:9E | 
| comodoaaaservicesroot |  2018년 4월 21일 | D1:EB:23:A4:6D:17:D6:8F:D9:25:64:C2:F1:F1:60:17:64:D8:E3:49 | 
| digicertglobalrootg2 |  2018년 4월 21일 | DF:3C:24:F9:BF:D6:66:76:1B:26:80:73:FE:06:D1:CC:8D:4F:82:A4 | 
| certinomisrootca |  2018년 4월 21일 | 9D:70:BB:01:A5:A4:A0:18:11:2E:F7:1C:01:B9:32:C5:34:E7:88:A8 | 
| oistewisekeyglobalrootgaca |  2018년 4월 21일 | 59:22:A1:E1:5A:EA:16:35:21:F8:98:39:6A:46:46:B0:44:1B:0F:A9 | 
| dstrootcax3 |  2018년 4월 21일 | DA:C9:02:4F:54:D8:F6:DF:94:93:5F:B1:73:26:38:CA:6A:D7:7C:13 | 
| certigna |  2018년 4월 21일 | B1:2E:13:63:45:86:A4:6F:1A:B2:60:68:37:58:2D:C4:AC:FD:94:97 | 
| digicerthighassuranceevrootca |  2018년 4월 21일 | 5F:B7:EE:06:33:E2:59:DB:AD:0C:4C:9A:E6:D3:8F:1A:61:C7:DC:25 | 
| soneraclass2rootca |  2018년 4월 21일 | 37:F7:6D:E6:07:7C:90:C5:B1:3E:93:1A:B7:41:10:B4:F2:E4:9A:27 | 
| trustcorrootcertca2 |  2018년 4월 21일 | B8:BE:6D:CB:56:F1:55:B9:63:D4:12:CA:4E:06:34:C7:94:B2:1C:C0 | 
| usertrustrsacertificationauthority |  2018년 4월 21일 | 2B:8F:1B:57:33:0D:BB:A2:D0:7A:6C:51:F7:0E:E9:0D:DA:B9:AD:8E | 
| trustcorrootcertca1 |  2018년 4월 21일 | FF:BD:CD:E7:82:C8:43:5E:3C:6F:26:86:5C:CA:A8:3A:45:5B:C3:0A | 
| geotrustuniversalca |  2018년 4월 21일 | E6:21:F3:35:43:79:05:9A:4B:68:30:9D:8A:2F:74:22:15:87:EC:79 | 
| certsignrootca |  2018년 4월 21일 | FA:B7:EE:36:97:26:62:FB:2D:B0:2A:F6:BF:03:FD:E8:7C:4B:2F:9B | 
| amazonrootca4 |  2018년 4월 21일 | F6:10:84:07:D6:F8:BB:67:98:0C:C2:E2:44:C2:EB:AE:1C:EF:63:BE | 
| amazonrootca3 |  2018년 4월 21일 | 0D:44:DD:8C:3C:8C:1A:1A:58:75:64:81:E9:0F:2E:2A:FF:B3:D2:6E | 
| amazonrootca2 |  2018년 4월 21일 | 5A:8C:EF:45:D7:A6:98:59:76:7A:8C:8B:44:96:B5:78:CF:47:4B:1A | 
| verisignuniversalrootcertificationauthority |  2018년 4월 21일 | 36:79:CA:35:66:87:72:30:4D:30:A5:FB:87:3B:0F:A7:7B:B7:0D:54 | 
| amazonrootca1 |  2018년 4월 21일 | 8D:A7:F9:65:EC:5E:FC:37:91:0F:1C:6E:59:FD:C1:CC:6A:6E:DE:16 | 
| networksolutionscertificateauthority |  2018년 4월 21일 | 74:F8:A3:C3:EF:E7:B3:90:06:4B:83:90:3C:21:64:60:20:E5:DF:CE | 
| thawteprimaryrootcag3 |  2018년 4월 21일 | F1:8B:53:8D:1B:E9:03:B6:A6:F0:56:43:5B:17:15:89:CA:F3:6B:F2 | 
| affirmtrustnetworking |  2018년 4월 21일 | 29:36:21:02:8B:20:ED:02:F5:66:C5:32:D1:D6:ED:90:9F:45:00:2F | 
| thawteprimaryrootcag2 |  2018년 4월 21일 | AA:DB:BC:22:23:8F:C4:01:A1:27:BB:38:DD:F4:1D:DB:08:9E:F0:12 | 
| trustcoreca1 |  2018년 4월 21일 | 58:D1:DF:95:95:67:6B:63:C0:F0:5B:1C:17:4D:8B:84:0B:C8:78:BD | 
| deutschetelekomrootca2 |  2018년 4월 21일 | 85:A4:08:C0:9C:19:3E:5D:51:58:7D:CD:D6:13:30:FD:8C:DE:37:BF | 
| godaddyrootcertificateauthorityg2 |  2018년 4월 21일 | 47:BE:AB:C9:22:EA:E8:0E:78:78:34:62:A7:9F:45:C2:54:FD:E6:8B | 
| entrustrootcertificationauthorityec1 |  2018년 4월 21일 | 20:D8:06:40:DF:9B:25:F5:12:25:3A:11:EA:F7:59:8A:EB:14:B5:47 | 
| szafirrootca2 |  2018년 4월 21일 | E2:52:FA:95:3F:ED:DB:24:60:BD:6E:28:F3:9C:CC:CF:5E:B3:3F:DE | 
| tubitakkamusmsslkoksertifikasisurum1 |  2018년 4월 21일 | 31:43:64:9B:EC:CE:27:EC:ED:3A:3F:0B:8F:0D:E4:E8:91:DD:EE:CA | 
| buypassclass3rootca |  2018년 4월 21일 | DA:FA:F7:FA:66:84:EC:06:8F:14:50:BD:C7:C2:81:A5:BC:A9:64:57 | 
| comodorsacertificationauthority |  2018년 4월 21일 | AF:E5:D2:44:A8:D1:19:42:30:FF:47:9F:E2:F8:97:BB:CD:7A:8C:B4 | 
| netlockaranyclassgoldfotanusitvany |  2018년 4월 21일 | 06:08:3F:59:3F:15:A1:04:A0:69:A4:6B:A9:03:D0:06:B7:97:09:91 | 
| securitycommunicationrootca2 |  2018년 4월 21일 | 5F:3B:8C:F2:F8:10:B3:7D:78:B4:CE:EC:19:19:C3:73:34:B9:C7:74 | 
| dtrustrootclass3ca2ev2009 |  2018년 4월 21일 | 96:C9:1B:0B:95:B4:10:98:42:FA:D0:D8:22:79:FE:60:FA:B9:16:83 | 
| starfieldclass2ca |  2018년 4월 21일 | AD:7E:1C:28:B0:64:EF:8F:60:03:40:20:14:C3:D0:E3:37:0E:B5:8A | 
| pscprocert |  2018년 4월 21일 | 70:C1:8D:74:B4:28:81:0A:E4:FD:A5:75:D7:01:9F:99:B0:3D:50:74 | 
| actalisauthenticationrootca |  2018년 4월 21일 | F3:73:B3:87:06:5A:28:84:8A:F2:F3:4A:CE:19:2B:DD:C7:8E:9C:AC | 
| staatdernederlandenrootcag3 |  2018년 4월 21일 | D8:EB:6B:41:51:92:59:E0:F3:E7:85:00:C0:3D:B6:88:97:C9:EE:FC | 
| cfcaevroot |  2018년 4월 21일 | E2:B8:29:4B:55:84:AB:6B:58:C2:90:46:6C:AC:3F:B8:39:8F:84:83 | 
| digicerttrustedrootg4 |  2018년 4월 21일 | DD:FB:16:CD:49:31:C9:73:A2:03:7D:3F:C8:3A:4D:7D:77:5D:05:E4 | 
| staatdernederlandenrootcag2 |  2018년 4월 21일 | 59:AF:82:79:91:86:C7:B4:75:07:CB:CF:03:57:46:EB:04:DD:B7:16 | 
| securitycommunicationevrootca1 |  2018년 4월 21일 | FE:B8:C4:32:DC:F9:76:9A:CE:AE:3D:D8:90:8F:FD:28:86:65:64:7D | 
| globalsignrootcar3 |  2018년 4월 21일 | D6:9B:56:11:48:F0:1C:77:C5:45:78:C1:09:26:DF:5B:85:69:76:AD | 
| globalsignrootcar2 |  2018년 4월 21일 | 75:E0:AB:B6:13:85:12:27:1C:04:F8:5F:DD:DE:38:E4:B7:24:2E:FE | 
| certumtrustednetworkca2 |  2018년 4월 21일 | D3:DD:48:3E:2B:BF:4C:05:E8:AF:10:F5:FA:76:26:CF:D3:DC:30:92 | 
| acraizfnmtrcm |  2018년 4월 21일 | EC:50:35:07:B2:15:C4:95:62:19:E2:A8:9A:5B:42:99:2C:4C:2C:20 | 
| hellenicacademicandresearchinstitutionseccrootca2015 |  2018년 4월 21일 | 9F:F1:71:8D:92:D5:9A:F3:7D:74:97:B4:BC:6F:84:68:0B:BA:B6:66 | 
| certplusrootcag2 |  2018년 4월 21일 | 4F:65:8E:1F:E9:06:D8:28:02:E9:54:47:41:C9:54:25:5D:69:CC:1A | 
| twcarootcertificationauthority |  2018년 4월 21일 | CF:9E:87:6D:D3:EB:FC:42:26:97:A3:B5:A3:7A:A0:76:A9:06:23:48 | 
| twcaglobalrootca |  2018년 4월 21일 | 9C:BB:48:53:F6:A4:F6:D3:52:A4:E8:32:52:55:60:13:F5:AD:AF:65 | 
| certplusrootcag1 |  2018년 4월 21일 | 22:FD:D0:B7:FD:A2:4E:0D:AC:49:2C:A0:AC:A6:7B:6A:1F:E3:F7:66 | 
| geotrustuniversalca2 |  2018년 4월 21일 | 37:9A:19:7B:41:85:45:35:0C:A6:03:69:F3:3C:2E:AF:47:4F:20:79 | 
| baltimorecybertrustroot |  2018년 4월 21일 | D4:DE:20:D0:5E:66:FC:53:FE:1A:50:88:2C:78:DB:28:52:CA:E4:74 | 
| buypassclass2rootca |  2018년 4월 21일 | 49:0A:75:74:DE:87:0A:47:FE:58:EE:F6:C7:6B:EB:C6:0B:12:40:99 | 
| certumtrustednetworkca |  2018년 4월 21일 | 07:E0:32:E0:20:B7:2C:3F:19:2F:06:28:A2:59:3A:19:A7:0F:06:9E | 
| digicertassuredidrootg3 |  2018년 4월 21일 | F5:17:A2:4F:9A:48:C6:C9:F8:A2:00:26:9F:DC:0F:48:2C:AB:30:89 | 
| digicertassuredidrootg2 |  2018년 4월 21일 | A1:4B:48:D9:43:EE:0A:0E:40:90:4F:3C:E0:A4:C0:91:93:51:5D:3F | 
| isrgrootx1 |  2018년 4월 21일 | CA:BD:2A:79:A1:07:6A:31:F2:1D:25:36:35:CB:03:9D:43:29:A5:E8 | 
| entrustnetpremium2048secureserverca |  2018년 4월 21일 | 50:30:06:09:1D:97:D4:F5:AE:39:F7:CB:E7:92:7D:7D:65:2D:34:31 | 
| certplusclass2primaryca |  2018년 4월 21일 | 74:20:74:41:72:9C:DD:92:EC:79:31:D8:23:10:8D:C2:81:92:E2:BB | 
| digicertglobalrootca |  2018년 4월 21일 | A8:98:5D:3A:65:E5:E5:C4:B2:D7:D6:6D:40:C6:DD:2F:B1:9C:54:36 | 
| entrustrootcertificationauthorityg2 |  2018년 4월 21일 | 8C:F4:27:FD:79:0C:3A:D1:66:06:8D:E8:1E:57:EF:BB:93:22:72:D4 | 
| starfieldservicesrootcertificateauthorityg2 |  2018년 4월 21일 | 92:5A:8F:8D:2C:6D:04:E0:66:5F:59:6A:FF:22:D8:63:E8:25:6F:3F | 
| thawteprimaryrootca |  2018년 4월 21일 | 91:C6:D6:EE:3E:8A:C8:63:84:E5:48:C2:99:29:5C:75:6C:81:7B:81 | 
| atostrustedroot2011 |  2018년 4월 21일 | 2B:B1:F5:3E:55:0C:1D:C5:F1:D4:E6:B7:6A:46:4B:55:06:02:AC:21 | 
| geotrustglobalca |  2018년 4월 21일 | DE:28:F4:A4:FF:E5:B9:2F:A3:C5:03:D1:A3:49:A7:F9:96:2A:82:12 | 
| luxtrustglobalroot2 |  2018년 4월 21일 | 1E:0E:56:19:0A:D1:8B:25:98:B2:04:44:FF:66:8A:04:17:99:5F:3F | 
| etugracertificationauthority |  2018년 4월 21일 | 51:C6:E7:08:49:06:6E:F3:92:D4:5C:A0:0D:6D:A3:62:8F:C3:52:39 | 
| visaecommerceroot |  2018년 4월 21일 | 70:17:9B:86:8C:00:A4:FA:60:91:52:22:3F:9F:3E:32:BD:E0:05:62 | 
| quovadisrootca |  2018년 4월 21일 | DE:3F:40:BD:50:93:D3:9B:6C:60:F6:DA:BC:07:62:01:00:89:76:C9 | 
| identrustcommercialrootca1 |  2018년 4월 21일 | DF:71:7E:AA:4A:D9:4E:C9:55:84:99:60:2D:48:DE:5F:BC:F0:3A:25 | 
| staatdernederlandenevrootca |  2018년 4월 21일 | 76:E2:7E:C1:4F:DB:82:C1:C0:A6:75:B5:05:BE:3D:29:B4:ED:DB:BB | 
| ttelesecglobalrootclass3 |  2018년 4월 21일 | 55:A6:72:3E:CB:F2:EC:CD:C3:23:74:70:19:9D:2A:BE:11:E3:81:D1 | 
| ttelesecglobalrootclass2 |  2018년 4월 21일 | 59:0D:2D:7D:88:4F:40:2E:61:7E:A5:62:32:17:65:CF:17:D8:94:E9 | 
| comodocertificationauthority |  2018년 4월 21일 | 66:31:BF:9E:F7:4F:9E:B6:C9:D5:A6:0C:BA:6A:BE:D1:F7:BD:EF:7B | 
| securitycommunicationrootca |  2018년 4월 21일 | 36:B1:2B:49:F9:81:9E:D7:4C:9E:BC:38:0F:C6:56:8F:5D:AC:B2:F7 | 
| quovadisrootca3g3 |  2018년 4월 21일 | 48:12:BD:92:3C:A8:C4:39:06:E7:30:6D:27:96:E6:A4:CF:22:2E:7D | 
| xrampglobalcaroot |  2018년 4월 21일 | B8:01:86:D1:EB:9C:86:A5:41:04:CF:30:54:F3:4C:52:B7:E5:58:C6 | 
| securesignrootca11 |  2018년 4월 21일 | 3B:C4:9F:48:F8:F3:73:A0:9C:1E:BD:F8:5B:B1:C3:65:C7:D8:11:B3 | 
| affirmtrustpremium |  2018년 4월 21일 | D8:A6:33:2C:E0:03:6F:B1:85:F6:63:4F:7D:6A:06:65:26:32:28:27 | 
| globalsignrootca |  2018년 4월 21일 | B1:BC:96:8B:D4:F4:9D:62:2A:A8:9A:81:F2:15:01:52:A4:1D:82:9C | 
| swisssigngoldcag2 |  2018년 4월 21일 | D8:C5:38:8A:B7:30:1B:1B:6E:D4:7A:E6:45:25:3A:6F:9F:1A:27:61 | 
| quovadisrootca2g3 |  2018년 4월 21일 | 09:3C:61:F3:8B:8B:DC:7D:55:DF:75:38:02:05:00:E1:25:F5:C8:36 | 
| affirmtrustpremiumecc |  2018년 4월 21일 | B8:23:6B:00:2F:1D:16:86:53:01:55:6C:11:A4:37:CA:EB:FF:C3:BB | 
| geotrustprimarycertificationauthority |  2018년 4월 21일 | 32:3C:11:8E:1B:F7:B8:B6:52:54:E2:E2:10:0D:D6:02:90:37:F0:96 | 
| quovadisrootca1g3 |  2018년 4월 21일 | 1B:8E:EA:57:96:29:1A:C9:39:EA:B8:0A:81:1A:73:73:C0:93:79:67 | 
| hongkongpostrootca1 |  2018년 4월 21일 | D6:DA:A8:20:8D:09:D2:15:4D:24:B5:2F:CB:34:6E:B2:58:B2:8A:58 | 
| usertrustecccertificationauthority |  2018년 4월 21일 | D1:CB:CA:5D:B2:D5:2A:7F:69:3B:67:4D:E5:F0:5A:1D:0C:95:7D:F0 | 
| cybertrustglobalroot |  2018년 4월 21일 | 5F:43:E5:B1:BF:F8:78:8C:AC:1C:C7:CA:4A:9A:C6:22:2B:CC:34:C6 | 
| godaddyclass2ca |  2018년 4월 21일 | 27:96:BA:E6:3F:18:01:E2:77:26:1B:A0:D7:77:70:02:8F:20:EE:E4 | 
| hellenicacademicandresearchinstitutionsrootca2015 |  2018년 4월 21일 | 01:0C:06:95:A6:98:19:14:FF:BF:5F:C6:B0:B6:95:EA:29:E9:12:A6 | 
| ecacc |  2018년 4월 21일 | 28:90:3A:63:5B:52:80:FA:E6:77:4C:0B:6D:A7:D6:BA:A6:4A:F2:E8 | 
| hellenicacademicandresearchinstitutionsrootca2011 |  2018년 4월 21일 | FE:45:65:9B:79:03:5B:98:A1:61:B5:51:2E:AC:DA:58:09:48:22:4D | 
| verisignclass3publicprimarycertificationauthorityg5 |  2018년 4월 21일 | 4E:B6:D5:78:49:9B:1C:CF:5F:58:1E:AD:56:BE:3D:9B:67:44:A5:E5 | 
| verisignclass3publicprimarycertificationauthorityg4 |  2018년 4월 21일 | 22:D5:D8:DF:8F:02:31:D1:8D:F7:9D:B7:CF:8A:2D:64:C9:3F:6C:3A | 
| verisignclass3publicprimarycertificationauthorityg3 |  2018년 4월 21일 | 13:2D:0D:45:53:4B:69:97:CD:B2:D5:C3:39:E2:55:76:60:9B:5C:C6 | 
| trustisfpsrootca |  2018년 4월 21일 | 3B:C0:38:0B:33:C3:F6:A6:0C:86:15:22:93:D9:DF:F5:4B:81:C0:04 | 
| epkirootcertificationauthority |  2018년 4월 21일 | 67:65:0D:F1:7E:8E:7E:5B:82:40:A4:F4:56:4B:CF:E2:3D:69:C6:F0 | 
| globalchambersignroot2008 |  2018년 4월 21일 | 4A:BD:EE:EC:95:0D:35:9C:89:AE:C7:52:A1:2C:5B:29:F6:D6:AA:0C | 
| camerfirmachambersofcommerceroot |  2018년 4월 21일 | 6E:3A:55:A4:19:0C:19:5C:93:84:3C:C0:DB:72:2E:31:30:61:F0:B1 | 
| mozillacert81.pem |  2014년 3월 13일 | 07:E0:32:E0:20:B7:2C:3F:19:2F:06:28:A2:59:3A:19:A7:0F:06:9E | 
| mozillacert99.pem |  2014년 3월 13일 | F1:7F:6F:B6:31:DC:99:E3:A3:C8:7F:FE:1C:F1:81:10:88:D9:60:33 | 
| mozillacert145.pem |  2014년 3월 13일 | 10:1D:FA:3F:D5:0B:CB:BB:9B:B5:60:0C:19:55:A4:1A:F4:73:3A:04 | 
| mozillacert37.pem |  2014년 3월 13일 | B1:2E:13:63:45:86:A4:6F:1A:B2:60:68:37:58:2D:C4:AC:FD:94:97 | 
| mozillacert4.pem |  2014년 3월 13일 | E3:92:51:2F:0A:CF:F5:05:DF:F6:DE:06:7F:75:37:E1:65:EA:57:4B | 
| mozillacert70.pem |  2014년 3월 13일 | 78:6A:74:AC:76:AB:14:7F:9C:6A:30:50:BA:9E:A8:7E:FE:9A:CE:3C | 
| mozillacert88.pem |  2014년 3월 13일 | FE:45:65:9B:79:03:5B:98:A1:61:B5:51:2E:AC:DA:58:09:48:22:4D | 
| mozillacert134.pem |  2014년 3월 13일 | 70:17:9B:86:8C:00:A4:FA:60:91:52:22:3F:9F:3E:32:BD:E0:05:62 | 
| mozillacert26.pem |  2014년 3월 13일 | 87:82:C6:C3:04:35:3B:CF:D2:96:92:D2:59:3E:7D:44:D9:34:FF:11 | 
| mozillacert77.pem |  2014년 3월 13일 | 13:2D:0D:45:53:4B:69:97:CD:B2:D5:C3:39:E2:55:76:60:9B:5C:C6 | 
| mozillacert123.pem |  2014년 3월 13일 | 2A:B6:28:48:5E:78:FB:F3:AD:9E:79:10:DD:6B:DF:99:72:2C:96:E5 | 
| mozillacert15.pem |  2014년 3월 13일 | 74:20:74:41:72:9C:DD:92:EC:79:31:D8:23:10:8D:C2:81:92:E2:BB | 
| mozillacert66.pem |  2014년 3월 13일 | DD:E1:D2:A9:01:80:2E:1D:87:5E:84:B3:80:7E:4B:B1:FD:99:41:34 | 
| mozillacert112.pem |  2014년 3월 13일 | 43:13:BB:96:F1:D5:86:9B:C1:4E:6A:92:F6:CF:F6:34:69:87:82:37 | 
| mozillacert55.pem |  2014년 3월 13일 | AA:DB:BC:22:23:8F:C4:01:A1:27:BB:38:DD:F4:1D:DB:08:9E:F0:12 | 
| mozillacert101.pem |  2014년 3월 13일 | 99:A6:9B:E6:1A:FE:88:6B:4D:2B:82:00:7C:B8:54:FC:31:7E:15:39 | 
| mozillacert119.pem |  2014년 3월 13일 | 75:E0:AB:B6:13:85:12:27:1C:04:F8:5F:DD:DE:38:E4:B7:24:2E:FE | 
| mozillacert44.pem |  2014년 3월 13일 | 5F:43:E5:B1:BF:F8:78:8C:AC:1C:C7:CA:4A:9A:C6:22:2B:CC:34:C6 | 
| mozillacert108.pem |  2014년 3월 13일 | B1:BC:96:8B:D4:F4:9D:62:2A:A8:9A:81:F2:15:01:52:A4:1D:82:9C | 
| mozillacert95.pem |  2014년 3월 13일 | DA:FA:F7:FA:66:84:EC:06:8F:14:50:BD:C7:C2:81:A5:BC:A9:64:57 | 
| mozillacert141.pem |  2014년 3월 13일 | 31:7A:2A:D0:7F:2B:33:5E:F5:A1:C3:4E:4B:57:E8:B7:D8:F1:FC:A6 | 
| mozillacert33.pem |  2014년 3월 13일 | FE:B8:C4:32:DC:F9:76:9A:CE:AE:3D:D8:90:8F:FD:28:86:65:64:7D | 
| mozillacert0.pem |  2014년 3월 13일 | 97:81:79:50:D8:1C:96:70:CC:34:D8:09:CF:79:44:31:36:7E:F4:74 | 
| mozillacert84.pem |  2014년 3월 13일 | D3:C0:63:F2:19:ED:07:3E:34:AD:5D:75:0B:32:76:29:FF:D5:9A:F2 | 
| mozillacert130.pem |  2014년 3월 13일 | E5:DF:74:3C:B6:01:C4:9B:98:43:DC:AB:8C:E8:6A:81:10:9F:E4:8E | 
| mozillacert148.pem |  2014년 3월 13일 | 04:83:ED:33:99:AC:36:08:05:87:22:ED:BC:5E:46:00:E3:BE:F9:D7 | 
| mozillacert22.pem |  2014년 3월 13일 | 32:3C:11:8E:1B:F7:B8:B6:52:54:E2:E2:10:0D:D6:02:90:37:F0:96 | 
| mozillacert7.pem |  2014년 3월 13일 | AD:7E:1C:28:B0:64:EF:8F:60:03:40:20:14:C3:D0:E3:37:0E:B5:8A | 
| mozillacert73.pem |  2014년 3월 13일 | B5:1C:06:7C:EE:2B:0C:3D:F8:55:AB:2D:92:F4:FE:39:D4:E7:0F:0E | 
| mozillacert137.pem |  2014년 3월 13일 | 4A:65:D5:F4:1D:EF:39:B8:B8:90:4A:4A:D3:64:81:33:CF:C7:A1:D1 | 
| mozillacert11.pem |  2014년 3월 13일 | 05:63:B8:63:0D:62:D7:5A:BB:C8:AB:1E:4B:DF:B5:A8:99:B2:4D:43 | 
| mozillacert29.pem |  2014년 3월 13일 | 74:F8:A3:C3:EF:E7:B3:90:06:4B:83:90:3C:21:64:60:20:E5:DF:CE | 
| mozillacert62.pem |  2014년 3월 13일 | A1:DB:63:93:91:6F:17:E4:18:55:09:40:04:15:C7:02:40:B0:AE:6B | 
| mozillacert126.pem |  2014년 3월 13일 | 25:01:90:19:CF:FB:D9:99:1C:B7:68:25:74:8D:94:5F:30:93:95:42 | 
| mozillacert18.pem |  2014년 3월 13일 | 79:98:A3:08:E1:4D:65:85:E6:C2:1E:15:3A:71:9F:BA:5A:D3:4A:D9 | 
| mozillacert51.pem |  2014년 3월 13일 | FA:B7:EE:36:97:26:62:FB:2D:B0:2A:F6:BF:03:FD:E8:7C:4B:2F:9B | 
| mozillacert69.pem |  2014년 3월 13일 | 2F:78:3D:25:52:18:A7:4A:65:39:71:B5:2C:A2:9C:45:15:6F:E9:19 | 
| mozillacert115.pem |  2014년 3월 13일 | 59:0D:2D:7D:88:4F:40:2E:61:7E:A5:62:32:17:65:CF:17:D8:94:E9 | 
| mozillacert40.pem |  2014년 3월 13일 | 80:25:EF:F4:6E:70:C8:D4:72:24:65:84:FE:40:3B:8A:8D:6A:DB:F5 | 
| mozillacert58.pem |  2014년 3월 13일 | 8D:17:84:D5:37:F3:03:7D:EC:70:FE:57:8B:51:9A:99:E6:10:D7:B0 | 
| mozillacert104.pem |  2014년 3월 13일 | 4F:99:AA:93:FB:2B:D1:37:26:A1:99:4A:CE:7F:F0:05:F2:93:5D:1E | 
| mozillacert91.pem |  2014년 3월 13일 | 3B:C0:38:0B:33:C3:F6:A6:0C:86:15:22:93:D9:DF:F5:4B:81:C0:04 | 
| mozillacert47.pem |  2014년 3월 13일 | 1B:4B:39:61:26:27:6B:64:91:A2:68:6D:D7:02:43:21:2D:1F:1D:96 | 
| mozillacert80.pem |  2014년 3월 13일 | B8:23:6B:00:2F:1D:16:86:53:01:55:6C:11:A4:37:CA:EB:FF:C3:BB | 
| mozillacert98.pem |  2014년 3월 13일 | C9:A8:B9:E7:55:80:5E:58:E3:53:77:A7:25:EB:AF:C3:7B:27:CC:D7 | 
| mozillacert144.pem |  2014년 3월 13일 | 37:F7:6D:E6:07:7C:90:C5:B1:3E:93:1A:B7:41:10:B4:F2:E4:9A:27 | 
| mozillacert36.pem |  2014년 3월 13일 | 23:88:C9:D3:71:CC:9E:96:3D:FF:7D:3C:A7:CE:FC:D6:25:EC:19:0D | 
| mozillacert3.pem |  2014년 3월 13일 | 87:9F:4B:EE:05:DF:98:58:3B:E3:60:D6:33:E7:0D:3F:FE:98:71:AF | 
| mozillacert87.pem |  2014년 3월 13일 | 5F:3B:8C:F2:F8:10:B3:7D:78:B4:CE:EC:19:19:C3:73:34:B9:C7:74 | 
| mozillacert133.pem |  2014년 3월 13일 | 85:B5:FF:67:9B:0C:79:96:1F:C8:6E:44:22:00:46:13:DB:17:92:84 | 
| mozillacert25.pem |  2014년 3월 13일 | 4E:B6:D5:78:49:9B:1C:CF:5F:58:1E:AD:56:BE:3D:9B:67:44:A5:E5 | 
| mozillacert76.pem |  2014년 3월 13일 | F9:B5:B6:32:45:5F:9C:BE:EC:57:5F:80:DC:E9:6E:2C:C7:B2:78:B7 | 
| mozillacert122.pem |  2014년 3월 13일 | 02:FA:F3:E2:91:43:54:68:60:78:57:69:4D:F5:E4:5B:68:85:18:68 | 
| mozillacert14.pem |  2014년 3월 13일 | 5F:B7:EE:06:33:E2:59:DB:AD:0C:4C:9A:E6:D3:8F:1A:61:C7:DC:25 | 
| mozillacert65.pem |  2014년 3월 13일 | 69:BD:8C:F4:9C:D3:00:FB:59:2E:17:93:CA:55:6A:F3:EC:AA:35:FB | 
| mozillacert111.pem |  2014년 3월 13일 | 9C:BB:48:53:F6:A4:F6:D3:52:A4:E8:32:52:55:60:13:F5:AD:AF:65 | 
| mozillacert129.pem |  2014년 3월 13일 | E6:21:F3:35:43:79:05:9A:4B:68:30:9D:8A:2F:74:22:15:87:EC:79 | 
| mozillacert54.pem |  2014년 3월 13일 | 03:9E:ED:B8:0B:E7:A0:3C:69:53:89:3B:20:D2:D9:32:3A:4C:2A:FD | 
| mozillacert100.pem |  2014년 3월 13일 | 58:E8:AB:B0:36:15:33:FB:80:F7:9B:1B:6D:29:D3:FF:8D:5F:00:F0 | 
| mozillacert118.pem |  2014년 3월 13일 | 7E:78:4A:10:1C:82:65:CC:2D:E1:F1:6D:47:B4:40:CA:D9:0A:19:45 | 
| mozillacert151.pem |  2014년 3월 13일 | AC:ED:5F:65:53:FD:25:CE:01:5F:1F:7A:48:3B:6A:74:9F:61:78:C6 | 
| mozillacert43.pem |  2014년 3월 13일 | F9:CD:0E:2C:DA:76:24:C1:8F:BD:F0:F0:AB:B6:45:B8:F7:FE:D5:7A | 
| mozillacert107.pem |  2014년 3월 13일 | 8E:1C:74:F8:A6:20:B9:E5:8A:F4:61:FA:EC:2B:47:56:51:1A:52:C6 | 
| mozillacert94.pem |  2014년 3월 13일 | 49:0A:75:74:DE:87:0A:47:FE:58:EE:F6:C7:6B:EB:C6:0B:12:40:99 | 
| mozillacert140.pem |  2014년 3월 13일 | CA:3A:FB:CF:12:40:36:4B:44:B2:16:20:88:80:48:39:19:93:7C:F7 | 
| mozillacert32.pem |  2014년 3월 13일 | 60:D6:89:74:B5:C2:65:9E:8A:0F:C1:88:7C:88:D2:46:69:1B:18:2C | 
| mozillacert83.pem |  2014년 3월 13일 | A0:73:E5:C5:BD:43:61:0D:86:4C:21:13:0A:85:58:57:CC:9C:EA:46 | 
| mozillacert147.pem |  2014년 3월 13일 | 58:11:9F:0E:12:82:87:EA:50:FD:D9:87:45:6F:4F:78:DC:FA:D6:D4 | 
| mozillacert21.pem |  2014년 3월 13일 | 9B:AA:E5:9F:56:EE:21:CB:43:5A:BE:25:93:DF:A7:F0:40:D1:1D:CB | 
| mozillacert39.pem |  2014년 3월 13일 | AE:50:83:ED:7C:F4:5C:BC:8F:61:C6:21:FE:68:5D:79:42:21:15:6E | 
| mozillacert6.pem |  2014년 3월 13일 | 27:96:BA:E6:3F:18:01:E2:77:26:1B:A0:D7:77:70:02:8F:20:EE:E4 | 
| mozillacert72.pem |  2014년 3월 13일 | 47:BE:AB:C9:22:EA:E8:0E:78:78:34:62:A7:9F:45:C2:54:FD:E6:8B | 
| mozillacert136.pem |  2014년 3월 13일 | D1:EB:23:A4:6D:17:D6:8F:D9:25:64:C2:F1:F1:60:17:64:D8:E3:49 | 
| mozillacert10.pem |  2014년 3월 13일 | 5F:3A:FC:0A:8B:64:F6:86:67:34:74:DF:7E:A9:A2:FE:F9:FA:7A:51 | 
| mozillacert28.pem |  2014년 3월 13일 | 66:31:BF:9E:F7:4F:9E:B6:C9:D5:A6:0C:BA:6A:BE:D1:F7:BD:EF:7B | 
| mozillacert61.pem |  2014년 3월 13일 | E0:B4:32:2E:B2:F6:A5:68:B6:54:53:84:48:18:4A:50:36:87:43:84 | 
| mozillacert79.pem |  2014년 3월 13일 | D8:A6:33:2C:E0:03:6F:B1:85:F6:63:4F:7D:6A:06:65:26:32:28:27 | 
| mozillacert125.pem |  2014년 3월 13일 | B3:1E:B1:B7:40:E3:6C:84:02:DA:DC:37:D4:4D:F5:D4:67:49:52:F9 | 
| mozillacert17.pem |  2014년 3월 13일 | 40:54:DA:6F:1C:3F:40:74:AC:ED:0F:EC:CD:DB:79:D1:53:FB:90:1D | 
| mozillacert50.pem |  2014년 3월 13일 | 8C:96:BA:EB:DD:2B:07:07:48:EE:30:32:66:A0:F3:98:6E:7C:AE:58 | 
| mozillacert68.pem |  2014년 3월 13일 | AE:C5:FB:3F:C8:E1:BF:C4:E5:4F:03:07:5A:9A:E8:00:B7:F7:B6:FA | 
| mozillacert114.pem |  2014년 3월 13일 | 51:C6:E7:08:49:06:6E:F3:92:D4:5C:A0:0D:6D:A3:62:8F:C3:52:39 | 
| mozillacert57.pem |  2014년 3월 13일 | D6:DA:A8:20:8D:09:D2:15:4D:24:B5:2F:CB:34:6E:B2:58:B2:8A:58 | 
| mozillacert103.pem |  2014년 3월 13일 | 70:C1:8D:74:B4:28:81:0A:E4:FD:A5:75:D7:01:9F:99:B0:3D:50:74 | 
| mozillacert90.pem |  2014년 3월 13일 | F3:73:B3:87:06:5A:28:84:8A:F2:F3:4A:CE:19:2B:DD:C7:8E:9C:AC | 
| mozillacert46.pem |  2014년 3월 13일 | 40:9D:4B:D9:17:B5:5C:27:B6:9B:64:CB:98:22:44:0D:CD:09:B8:89 | 
| mozillacert97.pem |  2014년 3월 13일 | 85:37:1C:A6:E5:50:14:3D:CE:28:03:47:1B:DE:3A:09:E8:F8:77:0F | 
| mozillacert143.pem |  2014년 3월 13일 | 36:B1:2B:49:F9:81:9E:D7:4C:9E:BC:38:0F:C6:56:8F:5D:AC:B2:F7 | 
| mozillacert35.pem |  2014년 3월 13일 | 2A:C8:D5:8B:57:CE:BF:2F:49:AF:F2:FC:76:8F:51:14:62:90:7A:41 | 
| mozillacert2.pem |  2014년 3월 13일 | 22:D5:D8:DF:8F:02:31:D1:8D:F7:9D:B7:CF:8A:2D:64:C9:3F:6C:3A | 
| mozillacert86.pem |  2014년 3월 13일 | 74:2C:31:92:E6:07:E4:24:EB:45:49:54:2B:E1:BB:C5:3E:61:74:E2 | 
| mozillacert132.pem |  2014년 3월 13일 | 39:21:C1:15:C1:5D:0E:CA:5C:CB:5B:C4:F0:7D:21:D8:05:0B:56:6A | 
| mozillacert24.pem |  2014년 3월 13일 | 59:AF:82:79:91:86:C7:B4:75:07:CB:CF:03:57:46:EB:04:DD:B7:16 | 
| mozillacert9.pem |  2014년 3월 13일 | F4:8B:11:BF:DE:AB:BE:94:54:20:71:E6:41:DE:6B:BE:88:2B:40:B9 | 
| mozillacert75.pem |  2014년 3월 13일 | D2:32:09:AD:23:D3:14:23:21:74:E4:0D:7F:9D:62:13:97:86:63:3A | 
| mozillacert121.pem |  2014년 3월 13일 | CC:AB:0E:A0:4C:23:01:D6:69:7B:DD:37:9F:CD:12:EB:24:E3:94:9D | 
| mozillacert139.pem |  2014년 3월 13일 | DE:3F:40:BD:50:93:D3:9B:6C:60:F6:DA:BC:07:62:01:00:89:76:C9 | 
| mozillacert13.pem |  2014년 3월 13일 | 06:08:3F:59:3F:15:A1:04:A0:69:A4:6B:A9:03:D0:06:B7:97:09:91 | 
| mozillacert64.pem |  2014년 3월 13일 | 62:7F:8D:78:27:65:63:99:D2:7D:7F:90:44:C9:FE:B3:F3:3E:FA:9A | 
| mozillacert110.pem |  2014년 3월 13일 | 93:05:7A:88:15:C6:4F:CE:88:2F:FA:91:16:52:28:78:BC:53:64:17 | 
| mozillacert128.pem |  2014년 3월 13일 | A9:E9:78:08:14:37:58:88:F2:05:19:B0:6D:2B:0D:2B:60:16:90:7D | 
| mozillacert53.pem |  2014년 3월 13일 | 7F:8A:B0:CF:D0:51:87:6A:66:F3:36:0F:47:C8:8D:8C:D3:35:FC:74 | 
| mozillacert117.pem |  2014년 3월 13일 | D4:DE:20:D0:5E:66:FC:53:FE:1A:50:88:2C:78:DB:28:52:CA:E4:74 | 
| mozillacert150.pem |  2014년 3월 13일 | 33:9B:6B:14:50:24:9B:55:7A:01:87:72:84:D9:E0:2F:C3:D2:D8:E9 | 
| mozillacert42.pem |  2014년 3월 13일 | 85:A4:08:C0:9C:19:3E:5D:51:58:7D:CD:D6:13:30:FD:8C:DE:37:BF | 
| mozillacert106.pem |  2014년 3월 13일 | E7:A1:90:29:D3:D5:52:DC:0D:0F:C6:92:D3:EA:88:0D:15:2E:1A:6B | 
| mozillacert93.pem |  2014년 3월 13일 | 31:F1:FD:68:22:63:20:EE:C6:3B:3F:9D:EA:4A:3E:53:7C:7C:39:17 | 
| mozillacert31.pem |  2014년 3월 13일 | 9F:74:4E:9F:2B:4D:BA:EC:0F:31:2C:50:B6:56:3B:8E:2D:93:C3:11 | 
| mozillacert49.pem |  2014년 3월 13일 | 61:57:3A:11:DF:0E:D8:7E:D5:92:65:22:EA:D0:56:D7:44:B3:23:71 | 
| mozillacert82.pem |  2014년 3월 13일 | 2E:14:DA:EC:28:F0:FA:1E:8E:38:9A:4E:AB:EB:26:C0:0A:D3:83:C3 | 
| mozillacert146.pem |  2014년 3월 13일 | 21:FC:BD:8E:7F:6C:AF:05:1B:D1:B3:43:EC:A8:E7:61:47:F2:0F:8A | 
| mozillacert20.pem |  2014년 3월 13일 | D8:C5:38:8A:B7:30:1B:1B:6E:D4:7A:E6:45:25:3A:6F:9F:1A:27:61 | 
| mozillacert38.pem |  2014년 3월 13일 | CB:A1:C5:F8:B0:E3:5E:B8:B9:45:12:D3:F9:34:A2:E9:06:10:D3:36 | 
| mozillacert5.pem |  2014년 3월 13일 | B8:01:86:D1:EB:9C:86:A5:41:04:CF:30:54:F3:4C:52:B7:E5:58:C6 | 
| mozillacert71.pem |  2014년 3월 13일 | 4A:BD:EE:EC:95:0D:35:9C:89:AE:C7:52:A1:2C:5B:29:F6:D6:AA:0C | 
| mozillacert89.pem |  2014년 3월 13일 | C8:EC:8C:87:92:69:CB:4B:AB:39:E9:8D:7E:57:67:F3:14:95:73:9D | 
| mozillacert135.pem |  2014년 3월 13일 | 62:52:DC:40:F7:11:43:A2:2F:DE:9E:F7:34:8E:06:42:51:B1:81:18 | 
| mozillacert27.pem |  2014년 3월 13일 | 3A:44:73:5A:E5:81:90:1F:24:86:61:46:1E:3B:9C:C4:5F:F5:3A:1B | 
| mozillacert60.pem |  2014년 3월 13일 | 3B:C4:9F:48:F8:F3:73:A0:9C:1E:BD:F8:5B:B1:C3:65:C7:D8:11:B3 | 
| mozillacert78.pem |  2014년 3월 13일 | 29:36:21:02:8B:20:ED:02:F5:66:C5:32:D1:D6:ED:90:9F:45:00:2F | 
| mozillacert124.pem |  2014년 3월 13일 | 4D:23:78:EC:91:95:39:B5:00:7F:75:8F:03:3B:21:1E:C5:4D:8B:CF | 
| mozillacert16.pem |  2014년 3월 13일 | DA:C9:02:4F:54:D8:F6:DF:94:93:5F:B1:73:26:38:CA:6A:D7:7C:13 | 
| mozillacert67.pem |  2014년 3월 13일 | D6:9B:56:11:48:F0:1C:77:C5:45:78:C1:09:26:DF:5B:85:69:76:AD | 
| mozillacert113.pem |  2014년 3월 13일 | 50:30:06:09:1D:97:D4:F5:AE:39:F7:CB:E7:92:7D:7D:65:2D:34:31 | 
| mozillacert56.pem |  2014년 3월 13일 | F1:8B:53:8D:1B:E9:03:B6:A6:F0:56:43:5B:17:15:89:CA:F3:6B:F2 | 
| mozillacert102.pem |  2014년 3월 13일 | 96:C9:1B:0B:95:B4:10:98:42:FA:D0:D8:22:79:FE:60:FA:B9:16:83 | 
| mozillacert45.pem |  2014년 3월 13일 | 67:65:0D:F1:7E:8E:7E:5B:82:40:A4:F4:56:4B:CF:E2:3D:69:C6:F0 | 
| mozillacert109.pem |  2014년 3월 13일 | B5:61:EB:EA:A4:DE:E4:25:4B:69:1A:98:A5:57:47:C2:34:C7:D9:71 | 
| mozillacert96.pem |  2014년 3월 13일 | 55:A6:72:3E:CB:F2:EC:CD:C3:23:74:70:19:9D:2A:BE:11:E3:81:D1 | 
| mozillacert142.pem |  2014년 3월 13일 | 1F:49:14:F7:D8:74:95:1D:DD:AE:02:C0:BE:FD:3A:2D:82:75:51:85 | 
| mozillacert34.pem |  2014년 3월 13일 | 59:22:A1:E1:5A:EA:16:35:21:F8:98:39:6A:46:46:B0:44:1B:0F:A9 | 
| mozillacert1.pem |  2014년 3월 13일 | 23:E5:94:94:51:95:F2:41:48:03:B4:D5:64:D2:A3:A3:F5:D8:8B:8C | 
| mozillacert85.pem |  2014년 3월 13일 | CF:9E:87:6D:D3:EB:FC:42:26:97:A3:B5:A3:7A:A0:76:A9:06:23:48 | 
| mozillacert131.pem |  2014년 3월 13일 | 37:9A:19:7B:41:85:45:35:0C:A6:03:69:F3:3C:2E:AF:47:4F:20:79 | 
| mozillacert149.pem |  2014년 3월 13일 | 6E:3A:55:A4:19:0C:19:5C:93:84:3C:C0:DB:72:2E:31:30:61:F0:B1 | 
| mozillacert23.pem |  2014년 3월 13일 | 91:C6:D6:EE:3E:8A:C8:63:84:E5:48:C2:99:29:5C:75:6C:81:7B:81 | 
| mozillacert8.pem |  2014년 3월 13일 | 3E:2B:F7:F2:03:1B:96:F3:8C:E6:C4:D8:A8:5D:3E:2D:58:47:6A:0F | 
| mozillacert74.pem |  2014년 3월 13일 | 92:5A:8F:8D:2C:6D:04:E0:66:5F:59:6A:FF:22:D8:63:E8:25:6F:3F | 
| mozillacert120.pem |  2014년 3월 13일 | DA:40:18:8B:91:89:A3:ED:EE:AE:DA:97:FE:2F:9D:F5:B7:D1:8A:41 | 
| mozillacert138.pem |  2014년 3월 13일 | E1:9F:E3:0E:8B:84:60:9E:80:9B:17:0D:72:A8:C5:BA:6E:14:09:BD | 
| mozillacert12.pem |  2014년 3월 13일 | A8:98:5D:3A:65:E5:E5:C4:B2:D7:D6:6D:40:C6:DD:2F:B1:9C:54:36 | 
| mozillacert63.pem |  2014년 3월 13일 | 89:DF:74:FE:5C:F4:0F:4A:80:F9:E3:37:7D:54:DA:91:E1:01:31:8E | 
| mozillacert127.pem |  2014년 3월 13일 | DE:28:F4:A4:FF:E5:B9:2F:A3:C5:03:D1:A3:49:A7:F9:96:2A:82:12 | 
| mozillacert19.pem |  2014년 3월 13일 | B4:35:D4:E1:11:9D:1C:66:90:A7:49:EB:B3:94:BD:63:7B:A7:82:B7 | 
| mozillacert52.pem |  2014년 3월 13일 | 8B:AF:4C:9B:1D:F0:2A:92:F7:DA:12:8E:B9:1B:AC:F4:98:60:4B:6F | 
| mozillacert116.pem |  2014년 3월 13일 | 2B:B1:F5:3E:55:0C:1D:C5:F1:D4:E6:B7:6A:46:4B:55:06:02:AC:21 | 
| mozillacert41.pem |  2014년 3월 13일 | 6B:2F:34:AD:89:58:BE:62:FD:B0:6B:5C:CE:BB:9D:D9:4F:4E:39:F3 | 
| mozillacert59.pem |  2014년 3월 13일 | 36:79:CA:35:66:87:72:30:4D:30:A5:FB:87:3B:0F:A7:7B:B7:0D:54 | 
| mozillacert105.pem |  2014년 3월 13일 | 77:47:4F:C6:30:E4:0F:4C:47:64:3F:84:BA:B8:C6:95:4A:8A:41:EC | 
| mozillacert92.pem |  2014년 3월 13일 | A3:F1:33:3F:E2:42:BF:CF:C5:D1:4E:8F:39:42:98:40:68:10:D1:A0 | 
| mozillacert30.pem |  2014년 3월 13일 | E7:B4:F6:9D:61:EC:90:69:DB:7E:90:A7:40:1A:3C:F4:7D:4F:E8:EE | 
| mozillacert48.pem |  2014년 3월 13일 | A0:A1:AB:90:C9:FC:84:7B:3B:12:61:E8:97:7D:5F:D3:22:61:D3:CC | 
| verisignc4g2.pem |  2014년 3월 20일 | 0B:77:BE:BB:CB:7A:A2:47:05:DE:CC:0F:BD:6A:02:FC:7A:BD:9B:52 | 
| verisignc2g3.pem |  2014년 3월 20일 | 61:EF:43:D7:7F:CA:D4:61:51:BC:98:E0:C3:59:12:AF:9F:EB:63:11 | 
| verisignc1g6.pem |  2014년 12월 31일 | 51:7F:61:1E:29:91:6B:53:82:FB:72:E7:44:D9:8D:C3:CC:53:6D:64 | 
| verisignc2g2.pem |  2014년 3월 20일 | B3:EA:C4:47:76:C9:C8:1C:EA:F2:9D:95:B6:CC:A0:08:1B:67:EC:9D | 
| verisignroot.pem |  2014년 3월 20일 | 36:79:CA:35:66:87:72:30:4D:30:A5:FB:87:3B:0F:A7:7B:B7:0D:54 | 
| verisignc2g1.pem |  2014년 3월 20일 | 67:82:AA:E0:ED:EE:E2:1A:58:39:D3:C0:CD:14:68:0A:4F:60:14:2A | 
| verisignc3g5.pem |  2014년 3월 20일 | 4E:B6:D5:78:49:9B:1C:CF:5F:58:1E:AD:56:BE:3D:9B:67:44:A5:E5 | 
| verisignc1g3.pem |  2014년 3월 20일 | 20:42:85:DC:F7:EB:76:41:95:57:8E:13:6B:D4:B7:D1:E9:8E:46:A5 | 
| verisignc3g4.pem |  2014년 3월 20일 | 22:D5:D8:DF:8F:02:31:D1:8D:F7:9D:B7:CF:8A:2D:64:C9:3F:6C:3A | 
| verisignc1g2.pem |  2014년 3월 20일 | 27:3E:E1:24:57:FD:C4:F9:0C:55:E8:2B:56:16:7F:62:F5:32:E5:47 | 
| verisignc3g3.pem |  2014년 3월 20일 | 13:2D:0D:45:53:4B:69:97:CD:B2:D5:C3:39:E2:55:76:60:9B:5C:C6 | 
| verisignc1g1.pem |  2014년 3월 20일 | 90:AE:A2:69:85:FF:14:80:4C:43:49:52:EC:E9:60:84:77:AF:55:6F | 
| verisignc3g2.pem |  2014년 3월 20일 | 85:37:1C:A6:E5:50:14:3D:CE:28:03:47:1B:DE:3A:09:E8:F8:77:0F | 
| verisignc3g1.pem |  2014년 3월 20일 | A1:DB:63:93:91:6F:17:E4:18:55:09:40:04:15:C7:02:40:B0:AE:6B | 
| verisignc2g6.pem |  2014년 12월 31일 | 40:B3:31:A0:E9:BF:E8:55:BC:39:93:CA:70:4F:4E:C2:51:D4:1D:8F | 
| verisignc4g3.pem |  2014년 3월 20일 | C8:EC:8C:87:92:69:CB:4B:AB:39:E9:8D:7E:57:67:F3:14:95:73:9D | 
| gdroot-g2.pem |  2014년 12월 31일 | 47:BE:AB:C9:22:EA:E8:0E:78:78:34:62:A7:9F:45:C2:54:FD:E6:8B | 
| gd-class2-root.pem |  2014년 12월 31일 | 27:96:BA:E6:3F:18:01:E2:77:26:1B:A0:D7:77:70:02:8F:20:EE:E4 | 
| gd\$1bundle-g2.pem |  2014년 12월 31일 | 27:AC:93:69:FA:F2:52:07:BB:26:27:CE:FA:CC:BE:4E:F9:C3:19:B8 | 
| dstacescax6 |  2018년 6월 18일 | 40:54:DA:6F:1C:3F:40:74:AC:ED:0F:EC:CD:DB:79:D1:53:FB:90:1D | 
| gd\$1bundle-g2.pem |  2018년 6월 18일 | 27:AC:93:69:FA:F2:52:07:BB:26:27:CE:FA:CC:BE:4E:F9:C3:19:B8 | 
| verisignc4g3.pem |  2018년 6월 18일 | C8:EC:8C:87:92:69:CB:4B:AB:39:E9:8D:7E:57:67:F3:14:95:73:9D | 
| swisssignplatinumg2ca |  2018년 4월 21일 | 56:E0:FA:C0:3B:8F:18:23:55:18:E5:D3:11:CA:E8:C2:43:31:AB:66 | 
| geotrustprimarycertificationauthorityg3 |  2018년 6월 18일 | 03:9E:ED:B8:0B:E7:A0:3C:69:53:89:3B:20:D2:D9:32:3A:4C:2A:FD | 
| geotrustprimarycertificationauthorityg2 |  2018년 6월 18일 | 8D:17:84:D5:37:F3:03:7D:EC:70:FE:57:8B:51:9A:99:E6:10:D7:B0 | 
| buypassclass2rootca |  2018년 6월 18일 | 49:0A:75:74:DE:87:0A:47:FE:58:EE:F6:C7:6B:EB:C6:0B:12:40:99 | 
| camerfirmachambersofcommerceroot |  2018년 6월 18일 | 6E:3A:55:A4:19:0C:19:5C:93:84:3C:C0:DB:72:2E:31:30:61:F0:B1 | 
| mozillacert20.pem |  2018년 6월 18일 | D8:C5:38:8A:B7:30:1B:1B:6E:D4:7A:E6:45:25:3A:6F:9F:1A:27:61 | 
| mozillacert12.pem |  2018년 6월 18일 | A8:98:5D:3A:65:E5:E5:C4:B2:D7:D6:6D:40:C6:DD:2F:B1:9C:54:36 | 
| mozillacert90.pem |  2018년 6월 18일 | F3:73:B3:87:06:5A:28:84:8A:F2:F3:4A:CE:19:2B:DD:C7:8E:9C:AC | 
| mozillacert82.pem |  2018년 6월 18일 | 2E:14:DA:EC:28:F0:FA:1E:8E:38:9A:4E:AB:EB:26:C0:0A:D3:83:C3 | 
| mozillacert140.pem |  2018년 6월 18일 | CA:3A:FB:CF:12:40:36:4B:44:B2:16:20:88:80:48:39:19:93:7C:F7 | 
| mozillacert74.pem |  2018년 6월 18일 | 92:5A:8F:8D:2C:6D:04:E0:66:5F:59:6A:FF:22:D8:63:E8:25:6F:3F | 
| mozillacert132.pem |  2018년 6월 18일 | 39:21:C1:15:C1:5D:0E:CA:5C:CB:5B:C4:F0:7D:21:D8:05:0B:56:6A | 
| mozillacert66.pem |  2018년 6월 18일 | DD:E1:D2:A9:01:80:2E:1D:87:5E:84:B3:80:7E:4B:B1:FD:99:41:34 | 
| mozillacert124.pem |  2018년 6월 18일 | 4D:23:78:EC:91:95:39:B5:00:7F:75:8F:03:3B:21:1E:C5:4D:8B:CF | 
| mozillacert58.pem |  2018년 6월 18일 | 8D:17:84:D5:37:F3:03:7D:EC:70:FE:57:8B:51:9A:99:E6:10:D7:B0 | 
| securitycommunicationrootca2 |  2018년 6월 18일 | 5F:3B:8C:F2:F8:10:B3:7D:78:B4:CE:EC:19:19:C3:73:34:B9:C7:74 | 
| mozillacert116.pem |  2018년 6월 18일 | 2B:B1:F5:3E:55:0C:1D:C5:F1:D4:E6:B7:6A:46:4B:55:06:02:AC:21 | 
| mozillacert108.pem |  2018년 6월 18일 | B1:BC:96:8B:D4:F4:9D:62:2A:A8:9A:81:F2:15:01:52:A4:1D:82:9C | 
| certigna |  2018년 6월 18일 | B1:2E:13:63:45:86:A4:6F:1A:B2:60:68:37:58:2D:C4:AC:FD:94:97 | 
| mozillacert3.pem |  2018년 6월 18일 | 87:9F:4B:EE:05:DF:98:58:3B:E3:60:D6:33:E7:0D:3F:FE:98:71:AF | 
| verisignc1g1.pem |  2018년 6월 18일 | 90:AE:A2:69:85:FF:14:80:4C:43:49:52:EC:E9:60:84:77:AF:55:6F | 
| verisignc4g2.pem |  2018년 6월 18일 | 0B:77:BE:BB:CB:7A:A2:47:05:DE:CC:0F:BD:6A:02:FC:7A:BD:9B:52 | 
| deutschetelekomrootca2 |  2018년 6월 18일 | 85:A4:08:C0:9C:19:3E:5D:51:58:7D:CD:D6:13:30:FD:8C:DE:37:BF | 
| starfieldrootg2ca |  2018년 4월 21일 | B5:1C:06:7C:EE:2B:0C:3D:F8:55:AB:2D:92:F4:FE:39:D4:E7:0F:0E | 
| comodoecccertificationauthority |  2018년 6월 18일 | 9F:74:4E:9F:2B:4D:BA:EC:0F:31:2C:50:B6:56:3B:8E:2D:93:C3:11 | 
| digicertglobalrootg3 |  2018년 6월 18일 | 7E:04:DE:89:6A:3E:66:6D:00:E6:87:D3:3F:FA:D9:3B:E8:3D:34:9E | 
| digicertglobalrootg2 |  2018년 6월 18일 | DF:3C:24:F9:BF:D6:66:76:1B:26:80:73:FE:06:D1:CC:8D:4F:82:A4 | 
| mozillacert11.pem |  2018년 6월 18일 | 05:63:B8:63:0D:62:D7:5A:BB:C8:AB:1E:4B:DF:B5:A8:99:B2:4D:43 | 
| mozillacert81.pem |  2018년 6월 18일 | 07:E0:32:E0:20:B7:2C:3F:19:2F:06:28:A2:59:3A:19:A7:0F:06:9E | 
| mozillacert73.pem |  2018년 6월 18일 | B5:1C:06:7C:EE:2B:0C:3D:F8:55:AB:2D:92:F4:FE:39:D4:E7:0F:0E | 
| szafirrootca2 |  2018년 6월 18일 | E2:52:FA:95:3F:ED:DB:24:60:BD:6E:28:F3:9C:CC:CF:5E:B3:3F:DE | 
| mozillacert131.pem |  2018년 6월 18일 | 37:9A:19:7B:41:85:45:35:0C:A6:03:69:F3:3C:2E:AF:47:4F:20:79 | 
| ecacc |  2018년 6월 18일 | 28:90:3A:63:5B:52:80:FA:E6:77:4C:0B:6D:A7:D6:BA:A6:4A:F2:E8 | 
| mozillacert65.pem |  2018년 6월 18일 | 69:BD:8C:F4:9C:D3:00:FB:59:2E:17:93:CA:55:6A:F3:EC:AA:35:FB | 
| turktrustelektroniksertifikahizmetsaglayicisih5 |  2018년 6월 18일 | C4:18:F6:4D:46:D1:DF:00:3D:27:30:13:72:43:A9:12:11:C6:75:FB | 
| mozillacert123.pem |  2018년 6월 18일 | 2A:B6:28:48:5E:78:FB:F3:AD:9E:79:10:DD:6B:DF:99:72:2C:96:E5 | 
| mozillacert57.pem |  2018년 6월 18일 | D6:DA:A8:20:8D:09:D2:15:4D:24:B5:2F:CB:34:6E:B2:58:B2:8A:58 | 
| mozillacert115.pem |  2018년 6월 18일 | 59:0D:2D:7D:88:4F:40:2E:61:7E:A5:62:32:17:65:CF:17:D8:94:E9 | 
| mozillacert49.pem |  2018년 6월 18일 | 61:57:3A:11:DF:0E:D8:7E:D5:92:65:22:EA:D0:56:D7:44:B3:23:71 | 
| mozillacert107.pem |  2018년 6월 18일 | 8E:1C:74:F8:A6:20:B9:E5:8A:F4:61:FA:EC:2B:47:56:51:1A:52:C6 | 
| verisignclass3g4ca |  2018년 4월 21일 | 22:D5:D8:DF:8F:02:31:D1:8D:F7:9D:B7:CF:8A:2D:64:C9:3F:6C:3A | 
| securetrustca |  2018년 6월 18일 | 87:82:C6:C3:04:35:3B:CF:D2:96:92:D2:59:3E:7D:44:D9:34:FF:11 | 
| mozillacert2.pem |  2018년 6월 18일 | 22:D5:D8:DF:8F:02:31:D1:8D:F7:9D:B7:CF:8A:2D:64:C9:3F:6C:3A | 
| buypassclass2ca |  2018년 4월 21일 | 49:0A:75:74:DE:87:0A:47:FE:58:EE:F6:C7:6B:EB:C6:0B:12:40:99 | 
| secomscrootca2 |  2018년 4월 21일 | 5F:3B:8C:F2:F8:10:B3:7D:78:B4:CE:EC:19:19:C3:73:34:B9:C7:74 | 
| secomscrootca1 |  2018년 4월 21일 | 36:B1:2B:49:F9:81:9E:D7:4C:9E:BC:38:0F:C6:56:8F:5D:AC:B2:F7 | 
| trustisfpsrootca |  2018년 6월 18일 | 3B:C0:38:0B:33:C3:F6:A6:0C:86:15:22:93:D9:DF:F5:4B:81:C0:04 | 
| hongkongpostrootca1 |  2018년 6월 18일 | D6:DA:A8:20:8D:09:D2:15:4D:24:B5:2F:CB:34:6E:B2:58:B2:8A:58 | 
| certsignrootca |  2018년 6월 18일 | FA:B7:EE:36:97:26:62:FB:2D:B0:2A:F6:BF:03:FD:E8:7C:4B:2F:9B | 
| geotrustprimaryca |  2018년 4월 21일 | 32:3C:11:8E:1B:F7:B8:B6:52:54:E2:E2:10:0D:D6:02:90:37:F0:96 | 
| twcaglobalrootca |  2018년 6월 18일 | 9C:BB:48:53:F6:A4:F6:D3:52:A4:E8:32:52:55:60:13:F5:AD:AF:65 | 
| camerfirmachambersca |  2018년 4월 21일 | 78:6A:74:AC:76:AB:14:7F:9C:6A:30:50:BA:9E:A8:7E:FE:9A:CE:3C | 
| mozillacert10.pem |  2018년 6월 18일 | 5F:3A:FC:0A:8B:64:F6:86:67:34:74:DF:7E:A9:A2:FE:F9:FA:7A:51 | 
| mozillacert80.pem |  2018년 6월 18일 | B8:23:6B:00:2F:1D:16:86:53:01:55:6C:11:A4:37:CA:EB:FF:C3:BB | 
| mozillacert72.pem |  2018년 6월 18일 | 47:BE:AB:C9:22:EA:E8:0E:78:78:34:62:A7:9F:45:C2:54:FD:E6:8B | 
| comodoaaaca |  2018년 4월 21일 | D1:EB:23:A4:6D:17:D6:8F:D9:25:64:C2:F1:F1:60:17:64:D8:E3:49 | 
| mozillacert130.pem |  2018년 6월 18일 | E5:DF:74:3C:B6:01:C4:9B:98:43:DC:AB:8C:E8:6A:81:10:9F:E4:8E | 
| mozillacert64.pem |  2018년 6월 18일 | 62:7F:8D:78:27:65:63:99:D2:7D:7F:90:44:C9:FE:B3:F3:3E:FA:9A | 
| mozillacert122.pem |  2018년 6월 18일 | 02:FA:F3:E2:91:43:54:68:60:78:57:69:4D:F5:E4:5B:68:85:18:68 | 
| mozillacert56.pem |  2018년 6월 18일 | F1:8B:53:8D:1B:E9:03:B6:A6:F0:56:43:5B:17:15:89:CA:F3:6B:F2 | 
| equifaxsecureebusinessca1 |  2018년 4월 21일 | AE:E6:3D:70:E3:76:FB:C7:3A:EB:B0:A1:C1:D4:C4:7A:A7:40:B3:F4 | 
| camerfirmachambersignca |  2018년 4월 21일 | 4A:BD:EE:EC:95:0D:35:9C:89:AE:C7:52:A1:2C:5B:29:F6:D6:AA:0C | 
| mozillacert114.pem |  2018년 6월 18일 | 51:C6:E7:08:49:06:6E:F3:92:D4:5C:A0:0D:6D:A3:62:8F:C3:52:39 | 
| mozillacert48.pem |  2018년 6월 18일 | A0:A1:AB:90:C9:FC:84:7B:3B:12:61:E8:97:7D:5F:D3:22:61:D3:CC | 
| pscprocert |  2018년 6월 18일 | 70:C1:8D:74:B4:28:81:0A:E4:FD:A5:75:D7:01:9F:99:B0:3D:50:74 | 
| mozillacert106.pem |  2018년 6월 18일 | E7:A1:90:29:D3:D5:52:DC:0D:0F:C6:92:D3:EA:88:0D:15:2E:1A:6B | 
| mozillacert1.pem |  2018년 6월 18일 | 23:E5:94:94:51:95:F2:41:48:03:B4:D5:64:D2:A3:A3:F5:D8:8B:8C | 
| eecertificationcentrerootca |  2018년 6월 18일 | C9:A8:B9:E7:55:80:5E:58:E3:53:77:A7:25:EB:AF:C3:7B:27:CC:D7 | 
| digicertglobalrootca |  2018년 6월 18일 | A8:98:5D:3A:65:E5:E5:C4:B2:D7:D6:6D:40:C6:DD:2F:B1:9C:54:36 | 
| thawteprimaryrootcag3 |  2018년 6월 18일 | F1:8B:53:8D:1B:E9:03:B6:A6:F0:56:43:5B:17:15:89:CA:F3:6B:F2 | 
| thawteprimaryrootcag2 |  2018년 6월 18일 | AA:DB:BC:22:23:8F:C4:01:A1:27:BB:38:DD:F4:1D:DB:08:9E:F0:12 | 
| entrustrootcertificationauthorityec1 |  2018년 6월 18일 | 20:D8:06:40:DF:9B:25:F5:12:25:3A:11:EA:F7:59:8A:EB:14:B5:47 | 
| valicertclass2ca |  2018년 4월 21일 | 31:7A:2A:D0:7F:2B:33:5E:F5:A1:C3:4E:4B:57:E8:B7:D8:F1:FC:A6 | 
| globalchambersignroot2008 |  2018년 6월 18일 | 4A:BD:EE:EC:95:0D:35:9C:89:AE:C7:52:A1:2C:5B:29:F6:D6:AA:0C | 
| amazonrootca4 |  2018년 6월 18일 | F6:10:84:07:D6:F8:BB:67:98:0C:C2:E2:44:C2:EB:AE:1C:EF:63:BE | 
| gd-class2-root.pem |  2018년 6월 18일 | 27:96:BA:E6:3F:18:01:E2:77:26:1B:A0:D7:77:70:02:8F:20:EE:E4 | 
| amazonrootca3 |  2018년 6월 18일 | 0D:44:DD:8C:3C:8C:1A:1A:58:75:64:81:E9:0F:2E:2A:FF:B3:D2:6E | 
| amazonrootca2 |  2018년 6월 18일 | 5A:8C:EF:45:D7:A6:98:59:76:7A:8C:8B:44:96:B5:78:CF:47:4B:1A | 
| securitycommunicationrootca |  2018년 6월 18일 | 36:B1:2B:49:F9:81:9E:D7:4C:9E:BC:38:0F:C6:56:8F:5D:AC:B2:F7 | 
| amazonrootca1 |  2018년 6월 18일 | 8D:A7:F9:65:EC:5E:FC:37:91:0F:1C:6E:59:FD:C1:CC:6A:6E:DE:16 | 
| acraizfnmtrcm |  2018년 6월 18일 | EC:50:35:07:B2:15:C4:95:62:19:E2:A8:9A:5B:42:99:2C:4C:2C:20 | 
| quovadisrootca3g3 |  2018년 6월 18일 | 48:12:BD:92:3C:A8:C4:39:06:E7:30:6D:27:96:E6:A4:CF:22:2E:7D | 
| certplusrootcag2 |  2018년 6월 18일 | 4F:65:8E:1F:E9:06:D8:28:02:E9:54:47:41:C9:54:25:5D:69:CC:1A | 
| certplusrootcag1 |  2018년 6월 18일 | 22:FD:D0:B7:FD:A2:4E:0D:AC:49:2C:A0:AC:A6:7B:6A:1F:E3:F7:66 | 
| mozillacert71.pem |  2018년 6월 18일 | 4A:BD:EE:EC:95:0D:35:9C:89:AE:C7:52:A1:2C:5B:29:F6:D6:AA:0C | 
| mozillacert63.pem |  2018년 6월 18일 | 89:DF:74:FE:5C:F4:0F:4A:80:F9:E3:37:7D:54:DA:91:E1:01:31:8E | 
| mozillacert121.pem |  2018년 6월 18일 | CC:AB:0E:A0:4C:23:01:D6:69:7B:DD:37:9F:CD:12:EB:24:E3:94:9D | 
| ttelesecglobalrootclass3ca |  2018년 4월 21일 | 55:A6:72:3E:CB:F2:EC:CD:C3:23:74:70:19:9D:2A:BE:11:E3:81:D1 | 
| mozillacert55.pem |  2018년 6월 18일 | AA:DB:BC:22:23:8F:C4:01:A1:27:BB:38:DD:F4:1D:DB:08:9E:F0:12 | 
| mozillacert113.pem |  2018년 6월 18일 | 50:30:06:09:1D:97:D4:F5:AE:39:F7:CB:E7:92:7D:7D:65:2D:34:31 | 
| baltimorecybertrustca |  2018년 4월 21일 | D4:DE:20:D0:5E:66:FC:53:FE:1A:50:88:2C:78:DB:28:52:CA:E4:74 | 
| mozillacert47.pem |  2018년 6월 18일 | 1B:4B:39:61:26:27:6B:64:91:A2:68:6D:D7:02:43:21:2D:1F:1D:96 | 
| mozillacert105.pem |  2018년 6월 18일 | 77:47:4F:C6:30:E4:0F:4C:47:64:3F:84:BA:B8:C6:95:4A:8A:41:EC | 
| mozillacert39.pem |  2018년 6월 18일 | AE:50:83:ED:7C:F4:5C:BC:8F:61:C6:21:FE:68:5D:79:42:21:15:6E | 
| usertrustecccertificationauthority |  2018년 6월 18일 | D1:CB:CA:5D:B2:D5:2A:7F:69:3B:67:4D:E5:F0:5A:1D:0C:95:7D:F0 | 
| mozillacert0.pem |  2018년 6월 18일 | 97:81:79:50:D8:1C:96:70:CC:34:D8:09:CF:79:44:31:36:7E:F4:74 | 
| securitycommunicationevrootca1 |  2018년 6월 18일 | FE:B8:C4:32:DC:F9:76:9A:CE:AE:3D:D8:90:8F:FD:28:86:65:64:7D | 
| verisignc3g5.pem |  2018년 6월 18일 | 4E:B6:D5:78:49:9B:1C:CF:5F:58:1E:AD:56:BE:3D:9B:67:44:A5:E5 | 
| globalsignr3ca |  2018년 4월 21일 | D6:9B:56:11:48:F0:1C:77:C5:45:78:C1:09:26:DF:5B:85:69:76:AD | 
| trustcoreca1 |  2018년 6월 18일 | 58:D1:DF:95:95:67:6B:63:C0:F0:5B:1C:17:4D:8B:84:0B:C8:78:BD | 
| equifaxsecureglobalebusinessca1 |  2018년 4월 21일 | 3A:74:CB:7A:47:DB:70:DE:89:1F:24:35:98:64:B8:2D:82:BD:1A:36 | 
| geotrustuniversalca |  2018년 6월 18일 | E6:21:F3:35:43:79:05:9A:4B:68:30:9D:8A:2F:74:22:15:87:EC:79 | 
| affirmtrustpremiumca |  2018년 4월 21일 | D8:A6:33:2C:E0:03:6F:B1:85:F6:63:4F:7D:6A:06:65:26:32:28:27 | 
| staatdernederlandenrootcag3 |  2018년 6월 18일 | D8:EB:6B:41:51:92:59:E0:F3:E7:85:00:C0:3D:B6:88:97:C9:EE:FC | 
| staatdernederlandenrootcag2 |  2018년 6월 18일 | 59:AF:82:79:91:86:C7:B4:75:07:CB:CF:03:57:46:EB:04:DD:B7:16 | 
| mozillacert70.pem |  2018년 6월 18일 | 78:6A:74:AC:76:AB:14:7F:9C:6A:30:50:BA:9E:A8:7E:FE:9A:CE:3C | 
| secomevrootca1 |  2018년 4월 21일 | FE:B8:C4:32:DC:F9:76:9A:CE:AE:3D:D8:90:8F:FD:28:86:65:64:7D | 
| geotrustglobalca |  2018년 6월 18일 | DE:28:F4:A4:FF:E5:B9:2F:A3:C5:03:D1:A3:49:A7:F9:96:2A:82:12 | 
| mozillacert62.pem |  2018년 6월 18일 | A1:DB:63:93:91:6F:17:E4:18:55:09:40:04:15:C7:02:40:B0:AE:6B | 
| mozillacert120.pem |  2018년 6월 18일 | DA:40:18:8B:91:89:A3:ED:EE:AE:DA:97:FE:2F:9D:F5:B7:D1:8A:41 | 
| mozillacert54.pem |  2018년 6월 18일 | 03:9E:ED:B8:0B:E7:A0:3C:69:53:89:3B:20:D2:D9:32:3A:4C:2A:FD | 
| mozillacert112.pem |  2018년 6월 18일 | 43:13:BB:96:F1:D5:86:9B:C1:4E:6A:92:F6:CF:F6:34:69:87:82:37 | 
| mozillacert46.pem |  2018년 6월 18일 | 40:9D:4B:D9:17:B5:5C:27:B6:9B:64:CB:98:22:44:0D:CD:09:B8:89 | 
| swisssigngoldcag2 |  2018년 6월 18일 | D8:C5:38:8A:B7:30:1B:1B:6E:D4:7A:E6:45:25:3A:6F:9F:1A:27:61 | 
| mozillacert104.pem |  2018년 6월 18일 | 4F:99:AA:93:FB:2B:D1:37:26:A1:99:4A:CE:7F:F0:05:F2:93:5D:1E | 
| mozillacert38.pem |  2018년 6월 18일 | CB:A1:C5:F8:B0:E3:5E:B8:B9:45:12:D3:F9:34:A2:E9:06:10:D3:36 | 
| certplusclass3pprimaryca |  2018년 4월 21일 | 21:6B:2A:29:E6:2A:00:CE:82:01:46:D8:24:41:41:B9:25:11:B2:79 | 
| entrustrootcertificationauthorityg2 |  2018년 6월 18일 | 8C:F4:27:FD:79:0C:3A:D1:66:06:8D:E8:1E:57:EF:BB:93:22:72:D4 | 
| godaddyrootg2ca |  2018년 4월 21일 | 47:BE:AB:C9:22:EA:E8:0E:78:78:34:62:A7:9F:45:C2:54:FD:E6:8B | 
| cfcaevroot |  2018년 6월 18일 | E2:B8:29:4B:55:84:AB:6B:58:C2:90:46:6C:AC:3F:B8:39:8F:84:83 | 
| verisignc3g4.pem |  2018년 6월 18일 | 22:D5:D8:DF:8F:02:31:D1:8D:F7:9D:B7:CF:8A:2D:64:C9:3F:6C:3A | 
| geotrustuniversalca2 |  2018년 6월 18일 | 37:9A:19:7B:41:85:45:35:0C:A6:03:69:F3:3C:2E:AF:47:4F:20:79 | 
| starfieldservicesrootg2ca |  2018년 4월 21일 | 92:5A:8F:8D:2C:6D:04:E0:66:5F:59:6A:FF:22:D8:63:E8:25:6F:3F | 
| digicerthighassuranceevrootca |  2018년 6월 18일 | 5F:B7:EE:06:33:E2:59:DB:AD:0C:4C:9A:E6:D3:8F:1A:61:C7:DC:25 | 
| entrustnetpremium2048secureserverca |  2018년 6월 18일 | 50:30:06:09:1D:97:D4:F5:AE:39:F7:CB:E7:92:7D:7D:65:2D:34:31 | 
| camerfirmaglobalchambersignroot |  2018년 6월 18일 | 33:9B:6B:14:50:24:9B:55:7A:01:87:72:84:D9:E0:2F:C3:D2:D8:E9 | 
| verisignclass3g3ca |  2018년 4월 21일 | 13:2D:0D:45:53:4B:69:97:CD:B2:D5:C3:39:E2:55:76:60:9B:5C:C6 | 
| godaddyclass2ca |  2018년 6월 18일 | 27:96:BA:E6:3F:18:01:E2:77:26:1B:A0:D7:77:70:02:8F:20:EE:E4 | 
| mozillacert61.pem |  2018년 6월 18일 | E0:B4:32:2E:B2:F6:A5:68:B6:54:53:84:48:18:4A:50:36:87:43:84 | 
| mozillacert53.pem |  2018년 6월 18일 | 7F:8A:B0:CF:D0:51:87:6A:66:F3:36:0F:47:C8:8D:8C:D3:35:FC:74 | 
| atostrustedroot2011 |  2018년 6월 18일 | 2B:B1:F5:3E:55:0C:1D:C5:F1:D4:E6:B7:6A:46:4B:55:06:02:AC:21 | 
| mozillacert111.pem |  2018년 6월 18일 | 9C:BB:48:53:F6:A4:F6:D3:52:A4:E8:32:52:55:60:13:F5:AD:AF:65 | 
| staatdernederlandenevrootca |  2018년 6월 18일 | 76:E2:7E:C1:4F:DB:82:C1:C0:A6:75:B5:05:BE:3D:29:B4:ED:DB:BB | 
| mozillacert45.pem |  2018년 6월 18일 | 67:65:0D:F1:7E:8E:7E:5B:82:40:A4:F4:56:4B:CF:E2:3D:69:C6:F0 | 
| mozillacert103.pem |  2018년 6월 18일 | 70:C1:8D:74:B4:28:81:0A:E4:FD:A5:75:D7:01:9F:99:B0:3D:50:74 | 
| mozillacert37.pem |  2018년 6월 18일 | B1:2E:13:63:45:86:A4:6F:1A:B2:60:68:37:58:2D:C4:AC:FD:94:97 | 
| mozillacert29.pem |  2018년 6월 18일 | 74:F8:A3:C3:EF:E7:B3:90:06:4B:83:90:3C:21:64:60:20:E5:DF:CE | 
| izenpecom |  2018년 6월 18일 | 2F:78:3D:25:52:18:A7:4A:65:39:71:B5:2C:A2:9C:45:15:6F:E9:19 | 
| comodorsacertificationauthority |  2018년 6월 18일 | AF:E5:D2:44:A8:D1:19:42:30:FF:47:9F:E2:F8:97:BB:CD:7A:8C:B4 | 
| mozillacert99.pem |  2018년 6월 18일 | F1:7F:6F:B6:31:DC:99:E3:A3:C8:7F:FE:1C:F1:81:10:88:D9:60:33 | 
| mozillacert149.pem |  2018년 6월 18일 | 6E:3A:55:A4:19:0C:19:5C:93:84:3C:C0:DB:72:2E:31:30:61:F0:B1 | 
| utnuserfirstobjectca |  2018년 4월 21일 | E1:2D:FB:4B:41:D7:D9:C3:2B:30:51:4B:AC:1D:81:D8:38:5E:2D:46 | 
| verisignc3g3.pem |  2018년 6월 18일 | 13:2D:0D:45:53:4B:69:97:CD:B2:D5:C3:39:E2:55:76:60:9B:5C:C6 | 
| dstrootcax3 |  2018년 6월 18일 | DA:C9:02:4F:54:D8:F6:DF:94:93:5F:B1:73:26:38:CA:6A:D7:7C:13 | 
| addtrustexternalroot |  2018년 6월 18일 | 02:FA:F3:E2:91:43:54:68:60:78:57:69:4D:F5:E4:5B:68:85:18:68 | 
| certumtrustednetworkca |  2018년 6월 18일 | 07:E0:32:E0:20:B7:2C:3F:19:2F:06:28:A2:59:3A:19:A7:0F:06:9E | 
| affirmtrustpremiumecc |  2018년 6월 18일 | B8:23:6B:00:2F:1D:16:86:53:01:55:6C:11:A4:37:CA:EB:FF:C3:BB | 
| starfieldclass2ca |  2018년 6월 18일 | AD:7E:1C:28:B0:64:EF:8F:60:03:40:20:14:C3:D0:E3:37:0E:B5:8A | 
| actalisauthenticationrootca |  2018년 6월 18일 | F3:73:B3:87:06:5A:28:84:8A:F2:F3:4A:CE:19:2B:DD:C7:8E:9C:AC | 
| verisignclass2g3ca |  2018년 4월 21일 | 61:EF:43:D7:7F:CA:D4:61:51:BC:98:E0:C3:59:12:AF:9F:EB:63:11 | 
| isrgrootx1 |  2018년 6월 18일 | CA:BD:2A:79:A1:07:6A:31:F2:1D:25:36:35:CB:03:9D:43:29:A5:E8 | 
| godaddyrootcertificateauthorityg2 |  2018년 6월 18일 | 47:BE:AB:C9:22:EA:E8:0E:78:78:34:62:A7:9F:45:C2:54:FD:E6:8B | 
| mozillacert60.pem |  2018년 6월 18일 | 3B:C4:9F:48:F8:F3:73:A0:9C:1E:BD:F8:5B:B1:C3:65:C7:D8:11:B3 | 
| chunghwaepkirootca |  2018년 4월 21일 | 67:65:0D:F1:7E:8E:7E:5B:82:40:A4:F4:56:4B:CF:E2:3D:69:C6:F0 | 
| mozillacert52.pem |  2018년 6월 18일 | 8B:AF:4C:9B:1D:F0:2A:92:F7:DA:12:8E:B9:1B:AC:F4:98:60:4B:6F | 
| microseceszignorootca2009 |  2018년 6월 18일 | 89:DF:74:FE:5C:F4:0F:4A:80:F9:E3:37:7D:54:DA:91:E1:01:31:8E | 
| securesignrootca11 |  2018년 6월 18일 | 3B:C4:9F:48:F8:F3:73:A0:9C:1E:BD:F8:5B:B1:C3:65:C7:D8:11:B3 | 
| mozillacert110.pem |  2018년 6월 18일 | 93:05:7A:88:15:C6:4F:CE:88:2F:FA:91:16:52:28:78:BC:53:64:17 | 
| mozillacert44.pem |  2018년 6월 18일 | 5F:43:E5:B1:BF:F8:78:8C:AC:1C:C7:CA:4A:9A:C6:22:2B:CC:34:C6 | 
| mozillacert102.pem |  2018년 6월 18일 | 96:C9:1B:0B:95:B4:10:98:42:FA:D0:D8:22:79:FE:60:FA:B9:16:83 | 
| mozillacert36.pem |  2018년 6월 18일 | 23:88:C9:D3:71:CC:9E:96:3D:FF:7D:3C:A7:CE:FC:D6:25:EC:19:0D | 
| mozillacert28.pem |  2018년 6월 18일 | 66:31:BF:9E:F7:4F:9E:B6:C9:D5:A6:0C:BA:6A:BE:D1:F7:BD:EF:7B | 
| baltimorecybertrustroot |  2018년 6월 18일 | D4:DE:20:D0:5E:66:FC:53:FE:1A:50:88:2C:78:DB:28:52:CA:E4:74 | 
| amzninternalrootca |  2008년 12월 12일 | A7:B7:F6:15:8A:FF:1E:C8:85:13:38:BC:93:EB:A2:AB:A4:09:EF:06 | 
| mozillacert98.pem |  2018년 6월 18일 | C9:A8:B9:E7:55:80:5E:58:E3:53:77:A7:25:EB:AF:C3:7B:27:CC:D7 | 
| mozillacert148.pem |  2018년 6월 18일 | 04:83:ED:33:99:AC:36:08:05:87:22:ED:BC:5E:46:00:E3:BE:F9:D7 | 
| verisignc3g2.pem |  2018년 6월 18일 | 85:37:1C:A6:E5:50:14:3D:CE:28:03:47:1B:DE:3A:09:E8:F8:77:0F | 
| quovadisrootca2g3 |  2018년 6월 18일 | 09:3C:61:F3:8B:8B:DC:7D:55:DF:75:38:02:05:00:E1:25:F5:C8:36 | 
| geotrustprimarycertificationauthority |  2018년 6월 18일 | 32:3C:11:8E:1B:F7:B8:B6:52:54:E2:E2:10:0D:D6:02:90:37:F0:96 | 
| opentrustrootcag3 |  2018년 6월 18일 | 6E:26:64:F3:56:BF:34:55:BF:D1:93:3F:7C:01:DE:D8:13:DA:8A:A6 | 
| opentrustrootcag2 |  2018년 6월 18일 | 79:5F:88:60:C5:AB:7C:3D:92:E6:CB:F4:8D:E1:45:CD:11:EF:60:0B | 
| opentrustrootcag1 |  2018년 6월 18일 | 79:91:E8:34:F7:E2:EE:DD:08:95:01:52:E9:55:2D:14:E9:58:D5:7E | 
| verisignclass3ca |  2018년 4월 21일 | A1:DB:63:93:91:6F:17:E4:18:55:09:40:04:15:C7:02:40:B0:AE:6B | 
| globalsignca |  2018년 4월 21일 | B1:BC:96:8B:D4:F4:9D:62:2A:A8:9A:81:F2:15:01:52:A4:1D:82:9C | 
| ttelesecglobalrootclass2ca |  2018년 4월 21일 | 59:0D:2D:7D:88:4F:40:2E:61:7E:A5:62:32:17:65:CF:17:D8:94:E9 | 
| verisignclass1g3ca |  2018년 4월 21일 | 20:42:85:DC:F7:EB:76:41:95:57:8E:13:6B:D4:B7:D1:E9:8E:46:A5 | 
| verisignuniversalrootca |  2018년 4월 21일 | 36:79:CA:35:66:87:72:30:4D:30:A5:FB:87:3B:0F:A7:7B:B7:0D:54 | 
| soneraclass2ca |  2018년 4월 21일 | 37:F7:6D:E6:07:7C:90:C5:B1:3E:93:1A:B7:41:10:B4:F2:E4:9A:27 | 
| starfieldservicesrootcertificateauthorityg2 |  2018년 6월 18일 | 92:5A:8F:8D:2C:6D:04:E0:66:5F:59:6A:FF:22:D8:63:E8:25:6F:3F | 
| mozillacert51.pem |  2018년 6월 18일 | FA:B7:EE:36:97:26:62:FB:2D:B0:2A:F6:BF:03:FD:E8:7C:4B:2F:9B | 
| mozillacert43.pem |  2018년 6월 18일 | F9:CD:0E:2C:DA:76:24:C1:8F:BD:F0:F0:AB:B6:45:B8:F7:FE:D5:7A | 
| mozillacert101.pem |  2018년 6월 18일 | 99:A6:9B:E6:1A:FE:88:6B:4D:2B:82:00:7C:B8:54:FC:31:7E:15:39 | 
| mozillacert35.pem |  2018년 6월 18일 | 2A:C8:D5:8B:57:CE:BF:2F:49:AF:F2:FC:76:8F:51:14:62:90:7A:41 | 
| globalsignr2ca |  2018년 4월 21일 | 75:E0:AB:B6:13:85:12:27:1C:04:F8:5F:DD:DE:38:E4:B7:24:2E:FE | 
| mozillacert27.pem |  2018년 6월 18일 | 3A:44:73:5A:E5:81:90:1F:24:86:61:46:1E:3B:9C:C4:5F:F5:3A:1B | 
| affirmtrustpremium |  2018년 6월 18일 | D8:A6:33:2C:E0:03:6F:B1:85:F6:63:4F:7D:6A:06:65:26:32:28:27 | 
| mozillacert19.pem |  2018년 6월 18일 | B4:35:D4:E1:11:9D:1C:66:90:A7:49:EB:B3:94:BD:63:7B:A7:82:B7 | 
| mozillacert97.pem |  2018년 6월 18일 | 85:37:1C:A6:E5:50:14:3D:CE:28:03:47:1B:DE:3A:09:E8:F8:77:0F | 
| netlockaranyclassgoldfotanusitvany |  2018년 6월 18일 | 06:08:3F:59:3F:15:A1:04:A0:69:A4:6B:A9:03:D0:06:B7:97:09:91 | 
| mozillacert89.pem |  2018년 6월 18일 | C8:EC:8C:87:92:69:CB:4B:AB:39:E9:8D:7E:57:67:F3:14:95:73:9D | 
| verisignroot.pem |  2018년 6월 18일 | 36:79:CA:35:66:87:72:30:4D:30:A5:FB:87:3B:0F:A7:7B:B7:0D:54 | 
| mozillacert147.pem |  2018년 6월 18일 | 58:11:9F:0E:12:82:87:EA:50:FD:D9:87:45:6F:4F:78:DC:FA:D6:D4 | 
| aolrootca2 |  2018년 4월 21일 | 85:B5:FF:67:9B:0C:79:96:1F:C8:6E:44:22:00:46:13:DB:17:92:84 | 
| cia-crt-g3-01-ca |  2016년 11월 23일 | 2B:EE:2C:BA:A3:1D:B5:FE:60:40:41:95:08:ED:46:82:39:4D:ED:E2 | 
| aolrootca1 |  2018년 4월 21일 | 39:21:C1:15:C1:5D:0E:CA:5C:CB:5B:C4:F0:7D:21:D8:05:0B:56:6A | 
| verisignc3g1.pem |  2018년 6월 18일 | A1:DB:63:93:91:6F:17:E4:18:55:09:40:04:15:C7:02:40:B0:AE:6B | 
| mozillacert139.pem |  2018년 6월 18일 | DE:3F:40:BD:50:93:D3:9B:6C:60:F6:DA:BC:07:62:01:00:89:76:C9 | 
| soneraclass2rootca |  2018년 6월 18일 | 37:F7:6D:E6:07:7C:90:C5:B1:3E:93:1A:B7:41:10:B4:F2:E4:9A:27 | 
| swisssignsilverg2ca |  2018년 4월 21일 | 9B:AA:E5:9F:56:EE:21:CB:43:5A:BE:25:93:DF:A7:F0:40:D1:1D:CB | 
| thawteprimaryrootca |  2018년 6월 18일 | 91:C6:D6:EE:3E:8A:C8:63:84:E5:48:C2:99:29:5C:75:6C:81:7B:81 | 
| gdcatrustauthr5root |  2018년 6월 18일 | 0F:36:38:5B:81:1A:25:C3:9B:31:4E:83:CA:E9:34:66:70:CC:74:B4 | 
| trustcenterclass4caii |  2018년 4월 21일 | A6:9A:91:FD:05:7F:13:6A:42:63:0B:B1:76:0D:2D:51:12:0C:16:50 | 
| usertrustrsacertificationauthority |  2018년 6월 18일 | 2B:8F:1B:57:33:0D:BB:A2:D0:7A:6C:51:F7:0E:E9:0D:DA:B9:AD:8E | 
| digicertassuredidrootg3 |  2018년 6월 18일 | F5:17:A2:4F:9A:48:C6:C9:F8:A2:00:26:9F:DC:0F:48:2C:AB:30:89 | 
| digicertassuredidrootg2 |  2018년 6월 18일 | A1:4B:48:D9:43:EE:0A:0E:40:90:4F:3C:E0:A4:C0:91:93:51:5D:3F | 
| mozillacert50.pem |  2018년 6월 18일 | 8C:96:BA:EB:DD:2B:07:07:48:EE:30:32:66:A0:F3:98:6E:7C:AE:58 | 
| mozillacert42.pem |  2018년 6월 18일 | 85:A4:08:C0:9C:19:3E:5D:51:58:7D:CD:D6:13:30:FD:8C:DE:37:BF | 
| mozillacert100.pem |  2018년 6월 18일 | 58:E8:AB:B0:36:15:33:FB:80:F7:9B:1B:6D:29:D3:FF:8D:5F:00:F0 | 
| mozillacert34.pem |  2018년 6월 18일 | 59:22:A1:E1:5A:EA:16:35:21:F8:98:39:6A:46:46:B0:44:1B:0F:A9 | 
| affirmtrustcommercialca |  2018년 4월 21일 | F9:B5:B6:32:45:5F:9C:BE:EC:57:5F:80:DC:E9:6E:2C:C7:B2:78:B7 | 
| mozillacert26.pem |  2018년 6월 18일 | 87:82:C6:C3:04:35:3B:CF:D2:96:92:D2:59:3E:7D:44:D9:34:FF:11 | 
| globalsigneccrootcar5 |  2018년 6월 18일 | 1F:24:C6:30:CD:A4:18:EF:20:69:FF:AD:4F:DD:5F:46:3A:1B:69:AA | 
| globalsigneccrootcar4 |  2018년 6월 18일 | 69:69:56:2E:40:80:F4:24:A1:E7:19:9F:14:BA:F3:EE:58:AB:6A:BB | 
| buypassclass3rootca |  2018년 6월 18일 | DA:FA:F7:FA:66:84:EC:06:8F:14:50:BD:C7:C2:81:A5:BC:A9:64:57 | 
| mozillacert18.pem |  2018년 6월 18일 | 79:98:A3:08:E1:4D:65:85:E6:C2:1E:15:3A:71:9F:BA:5A:D3:4A:D9 | 
| mozillacert96.pem |  2018년 6월 18일 | 55:A6:72:3E:CB:F2:EC:CD:C3:23:74:70:19:9D:2A:BE:11:E3:81:D1 | 
| verisignc2g6.pem |  2018년 6월 18일 | 40:B3:31:A0:E9:BF:E8:55:BC:39:93:CA:70:4F:4E:C2:51:D4:1D:8F | 
| secomvalicertclass1ca |  2018년 4월 21일 | E5:DF:74:3C:B6:01:C4:9B:98:43:DC:AB:8C:E8:6A:81:10:9F:E4:8E | 
| mozillacert88.pem |  2018년 6월 18일 | FE:45:65:9B:79:03:5B:98:A1:61:B5:51:2E:AC:DA:58:09:48:22:4D | 
| accvraiz1 |  2018년 6월 18일 | 93:05:7A:88:15:C6:4F:CE:88:2F:FA:91:16:52:28:78:BC:53:64:17 | 
| mozillacert146.pem |  2018년 6월 18일 | 21:FC:BD:8E:7F:6C:AF:05:1B:D1:B3:43:EC:A8:E7:61:47:F2:0F:8A | 
| mozillacert138.pem |  2018년 6월 18일 | E1:9F:E3:0E:8B:84:60:9E:80:9B:17:0D:72:A8:C5:BA:6E:14:09:BD | 
| verisignclass3g2ca |  2018년 4월 21일 | 85:37:1C:A6:E5:50:14:3D:CE:28:03:47:1B:DE:3A:09:E8:F8:77:0F | 
| dtrustrootclass3ca2ev2009 |  2018년 6월 18일 | 96:C9:1B:0B:95:B4:10:98:42:FA:D0:D8:22:79:FE:60:FA:B9:16:83 | 
| xrampglobalca |  2018년 4월 21일 | B8:01:86:D1:EB:9C:86:A5:41:04:CF:30:54:F3:4C:52:B7:E5:58:C6 | 
| mozillacert9.pem |  2018년 6월 18일 | F4:8B:11:BF:DE:AB:BE:94:54:20:71:E6:41:DE:6B:BE:88:2B:40:B9 | 
| verisignuniversalrootcertificationauthority |  2018년 6월 18일 | 36:79:CA:35:66:87:72:30:4D:30:A5:FB:87:3B:0F:A7:7B:B7:0D:54 | 
| tubitakkamusmsslkoksertifikasisurum1 |  2018년 6월 18일 | 31:43:64:9B:EC:CE:27:EC:ED:3A:3F:0B:8F:0D:E4:E8:91:DD:EE:CA | 
| mozillacert41.pem |  2018년 6월 18일 | 6B:2F:34:AD:89:58:BE:62:FD:B0:6B:5C:CE:BB:9D:D9:4F:4E:39:F3 | 
| mozillacert33.pem |  2018년 6월 18일 | FE:B8:C4:32:DC:F9:76:9A:CE:AE:3D:D8:90:8F:FD:28:86:65:64:7D | 
| mozillacert25.pem |  2018년 6월 18일 | 4E:B6:D5:78:49:9B:1C:CF:5F:58:1E:AD:56:BE:3D:9B:67:44:A5:E5 | 
| mozillacert17.pem |  2018년 6월 18일 | 40:54:DA:6F:1C:3F:40:74:AC:ED:0F:EC:CD:DB:79:D1:53:FB:90:1D | 
| mozillacert95.pem |  2018년 6월 18일 | DA:FA:F7:FA:66:84:EC:06:8F:14:50:BD:C7:C2:81:A5:BC:A9:64:57 | 
| affirmtrustpremiumeccca |  2018년 4월 21일 | B8:23:6B:00:2F:1D:16:86:53:01:55:6C:11:A4:37:CA:EB:FF:C3:BB | 
| mozillacert87.pem |  2018년 6월 18일 | 5F:3B:8C:F2:F8:10:B3:7D:78:B4:CE:EC:19:19:C3:73:34:B9:C7:74 | 
| mozillacert145.pem |  2018년 6월 18일 | 10:1D:FA:3F:D5:0B:CB:BB:9B:B5:60:0C:19:55:A4:1A:F4:73:3A:04 | 
| mozillacert79.pem |  2018년 6월 18일 | D8:A6:33:2C:E0:03:6F:B1:85:F6:63:4F:7D:6A:06:65:26:32:28:27 | 
| mozillacert137.pem |  2018년 6월 18일 | 4A:65:D5:F4:1D:EF:39:B8:B8:90:4A:4A:D3:64:81:33:CF:C7:A1:D1 | 
| digicertassuredidrootca |  2018년 6월 18일 | 05:63:B8:63:0D:62:D7:5A:BB:C8:AB:1E:4B:DF:B5:A8:99:B2:4D:43 | 
| addtrustqualifiedca |  2018년 4월 21일 | 4D:23:78:EC:91:95:39:B5:00:7F:75:8F:03:3B:21:1E:C5:4D:8B:CF | 
| mozillacert129.pem |  2018년 6월 18일 | E6:21:F3:35:43:79:05:9A:4B:68:30:9D:8A:2F:74:22:15:87:EC:79 | 
| verisignclass2g2ca |  2018년 4월 21일 | B3:EA:C4:47:76:C9:C8:1C:EA:F2:9D:95:B6:CC:A0:08:1B:67:EC:9D | 
| baltimorecodesigningca |  2018년 4월 21일 | 30:46:D8:C8:88:FF:69:30:C3:4A:FC:CD:49:27:08:7C:60:56:7B:0D | 
| luxtrustglobalroot2 |  2018년 6월 18일 | 1E:0E:56:19:0A:D1:8B:25:98:B2:04:44:FF:66:8A:04:17:99:5F:3F | 
| visaecommerceroot |  2018년 6월 18일 | 70:17:9B:86:8C:00:A4:FA:60:91:52:22:3F:9F:3E:32:BD:E0:05:62 | 
| oistewisekeyglobalrootgbca |  2018년 6월 18일 | 0F:F9:40:76:18:D3:D7:6A:4B:98:F0:A8:35:9E:0C:FD:27:AC:CC:ED | 
| mozillacert8.pem |  2018년 6월 18일 | 3E:2B:F7:F2:03:1B:96:F3:8C:E6:C4:D8:A8:5D:3E:2D:58:47:6A:0F | 
| comodocertificationauthority |  2018년 6월 18일 | 66:31:BF:9E:F7:4F:9E:B6:C9:D5:A6:0C:BA:6A:BE:D1:F7:BD:EF:7B | 
| cia-crt-g3-02-ca |  2016년 11월 23일 | 96:4A:BB:A7:BD:DA:FC:97:34:C0:0A:2D:F0:05:98:F7:E6:C6:6F:09 | 
| verisignc1g6.pem |  2018년 6월 18일 | 51:7F:61:1E:29:91:6B:53:82:FB:72:E7:44:D9:8D:C3:CC:53:6D:64 | 
| trustcenterclass2caii |  2018년 4월 21일 | AE:50:83:ED:7C:F4:5C:BC:8F:61:C6:21:FE:68:5D:79:42:21:15:6E | 
| quovadisrootca1g3 |  2018년 6월 18일 | 1B:8E:EA:57:96:29:1A:C9:39:EA:B8:0A:81:1A:73:73:C0:93:79:67 | 
| mozillacert40.pem |  2018년 6월 18일 | 80:25:EF:F4:6E:70:C8:D4:72:24:65:84:FE:40:3B:8A:8D:6A:DB:F5 | 
| cadisigrootr2 |  2018년 6월 18일 | B5:61:EB:EA:A4:DE:E4:25:4B:69:1A:98:A5:57:47:C2:34:C7:D9:71 | 
| cadisigrootr1 |  2018년 6월 18일 | 8E:1C:74:F8:A6:20:B9:E5:8A:F4:61:FA:EC:2B:47:56:51:1A:52:C6 | 
| mozillacert32.pem |  2018년 6월 18일 | 60:D6:89:74:B5:C2:65:9E:8A:0F:C1:88:7C:88:D2:46:69:1B:18:2C | 
| utndatacorpsgcca |  2018년 4월 21일 | 58:11:9F:0E:12:82:87:EA:50:FD:D9:87:45:6F:4F:78:DC:FA:D6:D4 | 
| mozillacert24.pem |  2018년 6월 18일 | 59:AF:82:79:91:86:C7:B4:75:07:CB:CF:03:57:46:EB:04:DD:B7:16 | 
| addtrustclass1ca |  2018년 4월 21일 | CC:AB:0E:A0:4C:23:01:D6:69:7B:DD:37:9F:CD:12:EB:24:E3:94:9D | 
| mozillacert16.pem |  2018년 6월 18일 | DA:C9:02:4F:54:D8:F6:DF:94:93:5F:B1:73:26:38:CA:6A:D7:7C:13 | 
| affirmtrustnetworkingca |  2018년 4월 21일 | 29:36:21:02:8B:20:ED:02:F5:66:C5:32:D1:D6:ED:90:9F:45:00:2F | 
| mozillacert94.pem |  2018년 6월 18일 | 49:0A:75:74:DE:87:0A:47:FE:58:EE:F6:C7:6B:EB:C6:0B:12:40:99 | 
| mozillacert86.pem |  2018년 6월 18일 | 74:2C:31:92:E6:07:E4:24:EB:45:49:54:2B:E1:BB:C5:3E:61:74:E2 | 
| mozillacert144.pem |  2018년 6월 18일 | 37:F7:6D:E6:07:7C:90:C5:B1:3E:93:1A:B7:41:10:B4:F2:E4:9A:27 | 
| mozillacert78.pem |  2018년 6월 18일 | 29:36:21:02:8B:20:ED:02:F5:66:C5:32:D1:D6:ED:90:9F:45:00:2F | 
| mozillacert136.pem |  2018년 6월 18일 | D1:EB:23:A4:6D:17:D6:8F:D9:25:64:C2:F1:F1:60:17:64:D8:E3:49 | 
| mozillacert128.pem |  2018년 6월 18일 | A9:E9:78:08:14:37:58:88:F2:05:19:B0:6D:2B:0D:2B:60:16:90:7D | 
| verisignclass1g2ca |  2018년 4월 21일 | 27:3E:E1:24:57:FD:C4:F9:0C:55:E8:2B:56:16:7F:62:F5:32:E5:47 | 
| hellenicacademicandresearchinstitutionsrootca2015 |  2018년 6월 18일 | 01:0C:06:95:A6:98:19:14:FF:BF:5F:C6:B0:B6:95:EA:29:E9:12:A6 | 
| soneraclass1ca |  2018년 4월 21일 | 07:47:22:01:99:CE:74:B9:7C:B0:3D:79:B2:64:A2:C8:55:E9:33:FF | 
| hellenicacademicandresearchinstitutionsrootca2011 |  2018년 6월 18일 | FE:45:65:9B:79:03:5B:98:A1:61:B5:51:2E:AC:DA:58:09:48:22:4D | 
| certumtrustednetworkca2 |  2018년 6월 18일 | D3:DD:48:3E:2B:BF:4C:05:E8:AF:10:F5:FA:76:26:CF:D3:DC:30:92 | 
| equifaxsecureca |  2018년 4월 21일 | D2:32:09:AD:23:D3:14:23:21:74:E4:0D:7F:9D:62:13:97:86:63:3A | 
| thawteserverca |  2018년 4월 21일 | 9F:AD:91:A6:CE:6A:C6:C5:00:47:C4:4E:C9:D4:A5:0D:92:D8:49:79 | 
| mozillacert7.pem |  2018년 6월 18일 | AD:7E:1C:28:B0:64:EF:8F:60:03:40:20:14:C3:D0:E3:37:0E:B5:8A | 
| affirmtrustnetworking |  2018년 6월 18일 | 29:36:21:02:8B:20:ED:02:F5:66:C5:32:D1:D6:ED:90:9F:45:00:2F | 
| deprecateditsecca |  2012년 1월 27일 | 12:12:0B:03:0E:15:14:54:F4:DD:B3:F5:DE:13:6E:83:5A:29:72:9D | 
| globalsignrootcar3 |  2018년 6월 18일 | D6:9B:56:11:48:F0:1C:77:C5:45:78:C1:09:26:DF:5B:85:69:76:AD | 
| globalsignrootcar2 |  2018년 6월 18일 | 75:E0:AB:B6:13:85:12:27:1C:04:F8:5F:DD:DE:38:E4:B7:24:2E:FE | 
| quovadisrootca |  2018년 6월 18일 | DE:3F:40:BD:50:93:D3:9B:6C:60:F6:DA:BC:07:62:01:00:89:76:C9 | 
| mozillacert31.pem |  2018년 6월 18일 | 9F:74:4E:9F:2B:4D:BA:EC:0F:31:2C:50:B6:56:3B:8E:2D:93:C3:11 | 
| entrustrootcertificationauthority |  2018년 6월 18일 | B3:1E:B1:B7:40:E3:6C:84:02:DA:DC:37:D4:4D:F5:D4:67:49:52:F9 | 
| mozillacert23.pem |  2018년 6월 18일 | 91:C6:D6:EE:3E:8A:C8:63:84:E5:48:C2:99:29:5C:75:6C:81:7B:81 | 
| mozillacert15.pem |  2018년 6월 18일 | 74:20:74:41:72:9C:DD:92:EC:79:31:D8:23:10:8D:C2:81:92:E2:BB | 
| verisignc2g3.pem |  2018년 6월 18일 | 61:EF:43:D7:7F:CA:D4:61:51:BC:98:E0:C3:59:12:AF:9F:EB:63:11 | 
| mozillacert93.pem |  2018년 6월 18일 | 31:F1:FD:68:22:63:20:EE:C6:3B:3F:9D:EA:4A:3E:53:7C:7C:39:17 | 
| mozillacert151.pem |  2018년 6월 18일 | AC:ED:5F:65:53:FD:25:CE:01:5F:1F:7A:48:3B:6A:74:9F:61:78:C6 | 
| mozillacert85.pem |  2018년 6월 18일 | CF:9E:87:6D:D3:EB:FC:42:26:97:A3:B5:A3:7A:A0:76:A9:06:23:48 | 
| certplusclass2primaryca |  2018년 6월 18일 | 74:20:74:41:72:9C:DD:92:EC:79:31:D8:23:10:8D:C2:81:92:E2:BB | 
| mozillacert143.pem |  2018년 6월 18일 | 36:B1:2B:49:F9:81:9E:D7:4C:9E:BC:38:0F:C6:56:8F:5D:AC:B2:F7 | 
| mozillacert77.pem |  2018년 6월 18일 | 13:2D:0D:45:53:4B:69:97:CD:B2:D5:C3:39:E2:55:76:60:9B:5C:C6 | 
| mozillacert135.pem |  2018년 6월 18일 | 62:52:DC:40:F7:11:43:A2:2F:DE:9E:F7:34:8E:06:42:51:B1:81:18 | 
| mozillacert69.pem |  2018년 6월 18일 | 2F:78:3D:25:52:18:A7:4A:65:39:71:B5:2C:A2:9C:45:15:6F:E9:19 | 
| mozillacert127.pem |  2018년 6월 18일 | DE:28:F4:A4:FF:E5:B9:2F:A3:C5:03:D1:A3:49:A7:F9:96:2A:82:12 | 
| mozillacert119.pem |  2018년 6월 18일 | 75:E0:AB:B6:13:85:12:27:1C:04:F8:5F:DD:DE:38:E4:B7:24:2E:FE | 
| geotrustprimarycag3 |  2018년 4월 21일 | 03:9E:ED:B8:0B:E7:A0:3C:69:53:89:3B:20:D2:D9:32:3A:4C:2A:FD | 
| identrustpublicsectorrootca1 |  2018년 6월 18일 | BA:29:41:60:77:98:3F:F4:F3:EF:F2:31:05:3B:2E:EA:6D:4D:45:FD | 
| geotrustprimarycag2 |  2018년 4월 21일 | 8D:17:84:D5:37:F3:03:7D:EC:70:FE:57:8B:51:9A:99:E6:10:D7:B0 | 
| trustcorrootcertca2 |  2018년 6월 18일 | B8:BE:6D:CB:56:F1:55:B9:63:D4:12:CA:4E:06:34:C7:94:B2:1C:C0 | 
| mozillacert6.pem |  2018년 6월 18일 | 27:96:BA:E6:3F:18:01:E2:77:26:1B:A0:D7:77:70:02:8F:20:EE:E4 | 
| trustcorrootcertca1 |  2018년 6월 18일 | FF:BD:CD:E7:82:C8:43:5E:3C:6F:26:86:5C:CA:A8:3A:45:5B:C3:0A | 
| networksolutionscertificateauthority |  2018년 6월 18일 | 74:F8:A3:C3:EF:E7:B3:90:06:4B:83:90:3C:21:64:60:20:E5:DF:CE | 
| twcarootcertificationauthority |  2018년 6월 18일 | CF:9E:87:6D:D3:EB:FC:42:26:97:A3:B5:A3:7A:A0:76:A9:06:23:48 | 
| addtrustexternalca |  2018년 4월 21일 | 02:FA:F3:E2:91:43:54:68:60:78:57:69:4D:F5:E4:5B:68:85:18:68 | 
| verisignclass3g5ca |  2018년 4월 21일 | 4E:B6:D5:78:49:9B:1C:CF:5F:58:1E:AD:56:BE:3D:9B:67:44:A5:E5 | 
| autoridaddecertificacionfirmaprofesionalcifa62634068 |  2018년 6월 18일 | AE:C5:FB:3F:C8:E1:BF:C4:E5:4F:03:07:5A:9A:E8:00:B7:F7:B6:FA | 
| hellenicacademicandresearchinstitutionseccrootca2015 |  2018년 6월 18일 | 9F:F1:71:8D:92:D5:9A:F3:7D:74:97:B4:BC:6F:84:68:0B:BA:B6:66 | 
| verisigntsaca |  2018년 4월 21일 | 20:CE:B1:F0:F5:1C:0E:19:A9:F3:8D:B1:AA:8E:03:8C:AA:7A:C7:01 | 
| utnuserfirsthardwareca |  2018년 4월 21일 | 04:83:ED:33:99:AC:36:08:05:87:22:ED:BC:5E:46:00:E3:BE:F9:D7 | 
| identrustcommercialrootca1 |  2018년 6월 18일 | DF:71:7E:AA:4A:D9:4E:C9:55:84:99:60:2D:48:DE:5F:BC:F0:3A:25 | 
| dtrustrootclass3ca22009 |  2018년 6월 18일 | 58:E8:AB:B0:36:15:33:FB:80:F7:9B:1B:6D:29:D3:FF:8D:5F:00:F0 | 
| epkirootcertificationauthority |  2018년 6월 18일 | 67:65:0D:F1:7E:8E:7E:5B:82:40:A4:F4:56:4B:CF:E2:3D:69:C6:F0 | 
| mozillacert30.pem |  2018년 6월 18일 | E7:B4:F6:9D:61:EC:90:69:DB:7E:90:A7:40:1A:3C:F4:7D:4F:E8:EE | 
| teliasonerarootcav1 |  2018년 6월 18일 | 43:13:BB:96:F1:D5:86:9B:C1:4E:6A:92:F6:CF:F6:34:69:87:82:37 | 
| buypassclass3ca |  2018년 4월 21일 | DA:FA:F7:FA:66:84:EC:06:8F:14:50:BD:C7:C2:81:A5:BC:A9:64:57 | 
| mozillacert22.pem |  2018년 6월 18일 | 32:3C:11:8E:1B:F7:B8:B6:52:54:E2:E2:10:0D:D6:02:90:37:F0:96 | 
| mozillacert14.pem |  2018년 6월 18일 | 5F:B7:EE:06:33:E2:59:DB:AD:0C:4C:9A:E6:D3:8F:1A:61:C7:DC:25 | 
| verisignc2g2.pem |  2018년 6월 18일 | B3:EA:C4:47:76:C9:C8:1C:EA:F2:9D:95:B6:CC:A0:08:1B:67:EC:9D | 
| certumca |  2018년 4월 21일 | 62:52:DC:40:F7:11:43:A2:2F:DE:9E:F7:34:8E:06:42:51:B1:81:18 | 
| mozillacert92.pem |  2018년 6월 18일 | A3:F1:33:3F:E2:42:BF:CF:C5:D1:4E:8F:39:42:98:40:68:10:D1:A0 | 
| mozillacert150.pem |  2018년 6월 18일 | 33:9B:6B:14:50:24:9B:55:7A:01:87:72:84:D9:E0:2F:C3:D2:D8:E9 | 
| mozillacert84.pem |  2018년 6월 18일 | D3:C0:63:F2:19:ED:07:3E:34:AD:5D:75:0B:32:76:29:FF:D5:9A:F2 | 
| ttelesecglobalrootclass3 |  2018년 6월 18일 | 55:A6:72:3E:CB:F2:EC:CD:C3:23:74:70:19:9D:2A:BE:11:E3:81:D1 | 
| globalsignrootca |  2018년 6월 18일 | B1:BC:96:8B:D4:F4:9D:62:2A:A8:9A:81:F2:15:01:52:A4:1D:82:9C | 
| ttelesecglobalrootclass2 |  2018년 6월 18일 | 59:0D:2D:7D:88:4F:40:2E:61:7E:A5:62:32:17:65:CF:17:D8:94:E9 | 
| mozillacert142.pem |  2018년 6월 18일 | 1F:49:14:F7:D8:74:95:1D:DD:AE:02:C0:BE:FD:3A:2D:82:75:51:85 | 
| mozillacert76.pem |  2018년 6월 18일 | F9:B5:B6:32:45:5F:9C:BE:EC:57:5F:80:DC:E9:6E:2C:C7:B2:78:B7 | 
| mozillacert134.pem |  2018년 6월 18일 | 70:17:9B:86:8C:00:A4:FA:60:91:52:22:3F:9F:3E:32:BD:E0:05:62 | 
| mozillacert68.pem |  2018년 6월 18일 | AE:C5:FB:3F:C8:E1:BF:C4:E5:4F:03:07:5A:9A:E8:00:B7:F7:B6:FA | 
| etugracertificationauthority |  2018년 6월 18일 | 51:C6:E7:08:49:06:6E:F3:92:D4:5C:A0:0D:6D:A3:62:8F:C3:52:39 | 
| mozillacert126.pem |  2018년 6월 18일 | 25:01:90:19:CF:FB:D9:99:1C:B7:68:25:74:8D:94:5F:30:93:95:42 | 
| keynectisrootca |  2018년 4월 21일 | 9C:61:5C:4D:4D:85:10:3A:53:26:C2:4D:BA:EA:E4:A2:D2:D5:CC:97 | 
| mozillacert118.pem |  2018년 6월 18일 | 7E:78:4A:10:1C:82:65:CC:2D:E1:F1:6D:47:B4:40:CA:D9:0A:19:45 | 
| quovadisrootca3 |  2018년 6월 18일 | 1F:49:14:F7:D8:74:95:1D:DD:AE:02:C0:BE:FD:3A:2D:82:75:51:85 | 
| quovadisrootca2 |  2018년 6월 18일 | CA:3A:FB:CF:12:40:36:4B:44:B2:16:20:88:80:48:39:19:93:7C:F7 | 
| mozillacert5.pem |  2018년 6월 18일 | B8:01:86:D1:EB:9C:86:A5:41:04:CF:30:54:F3:4C:52:B7:E5:58:C6 | 
| verisignc1g3.pem |  2018년 6월 18일 | 20:42:85:DC:F7:EB:76:41:95:57:8E:13:6B:D4:B7:D1:E9:8E:46:A5 | 
| cybertrustglobalroot |  2018년 6월 18일 | 5F:43:E5:B1:BF:F8:78:8C:AC:1C:C7:CA:4A:9A:C6:22:2B:CC:34:C6 | 
| amzninternalinfoseccag3 |  2015년 2월 27일 | B9:B1:CA:38:F7:BF:9C:D2:D4:95:E7:B6:5E:75:32:9B:A8:78:2E:F6 | 
| starfieldrootcertificateauthorityg2 |  2018년 6월 18일 | B5:1C:06:7C:EE:2B:0C:3D:F8:55:AB:2D:92:F4:FE:39:D4:E7:0F:0E | 
| entrust2048ca |  2018년 4월 21일 | 50:30:06:09:1D:97:D4:F5:AE:39:F7:CB:E7:92:7D:7D:65:2D:34:31 | 
| swisssignsilvercag2 |  2018년 6월 18일 | 9B:AA:E5:9F:56:EE:21:CB:43:5A:BE:25:93:DF:A7:F0:40:D1:1D:CB | 
| affirmtrustcommercial |  2018년 6월 18일 | F9:B5:B6:32:45:5F:9C:BE:EC:57:5F:80:DC:E9:6E:2C:C7:B2:78:B7 | 
| certinomisrootca |  2018년 6월 18일 | 9D:70:BB:01:A5:A4:A0:18:11:2E:F7:1C:01:B9:32:C5:34:E7:88:A8 | 
| xrampglobalcaroot |  2018년 6월 18일 | B8:01:86:D1:EB:9C:86:A5:41:04:CF:30:54:F3:4C:52:B7:E5:58:C6 | 
| secureglobalca |  2018년 6월 18일 | 3A:44:73:5A:E5:81:90:1F:24:86:61:46:1E:3B:9C:C4:5F:F5:3A:1B | 
| swisssigngoldg2ca |  2018년 4월 21일 | D8:C5:38:8A:B7:30:1B:1B:6E:D4:7A:E6:45:25:3A:6F:9F:1A:27:61 | 
| mozillacert21.pem |  2018년 6월 18일 | 9B:AA:E5:9F:56:EE:21:CB:43:5A:BE:25:93:DF:A7:F0:40:D1:1D:CB | 
| mozillacert13.pem |  2018년 6월 18일 | 06:08:3F:59:3F:15:A1:04:A0:69:A4:6B:A9:03:D0:06:B7:97:09:91 | 
| verisignc2g1.pem |  2018년 6월 18일 | 67:82:AA:E0:ED:EE:E2:1A:58:39:D3:C0:CD:14:68:0A:4F:60:14:2A | 
| mozillacert91.pem |  2018년 6월 18일 | 3B:C0:38:0B:33:C3:F6:A6:0C:86:15:22:93:D9:DF:F5:4B:81:C0:04 | 
| oistewisekeyglobalrootgaca |  2018년 6월 18일 | 59:22:A1:E1:5A:EA:16:35:21:F8:98:39:6A:46:46:B0:44:1B:0F:A9 | 
| mozillacert83.pem |  2018년 6월 18일 | A0:73:E5:C5:BD:43:61:0D:86:4C:21:13:0A:85:58:57:CC:9C:EA:46 | 
| entrustevca |  2018년 4월 21일 | B3:1E:B1:B7:40:E3:6C:84:02:DA:DC:37:D4:4D:F5:D4:67:49:52:F9 | 
| mozillacert141.pem |  2018년 6월 18일 | 31:7A:2A:D0:7F:2B:33:5E:F5:A1:C3:4E:4B:57:E8:B7:D8:F1:FC:A6 | 
| mozillacert75.pem |  2018년 6월 18일 | D2:32:09:AD:23:D3:14:23:21:74:E4:0D:7F:9D:62:13:97:86:63:3A | 
| mozillacert133.pem |  2018년 6월 18일 | 85:B5:FF:67:9B:0C:79:96:1F:C8:6E:44:22:00:46:13:DB:17:92:84 | 
| mozillacert67.pem |  2018년 6월 18일 | D6:9B:56:11:48:F0:1C:77:C5:45:78:C1:09:26:DF:5B:85:69:76:AD | 
| mozillacert125.pem |  2018년 6월 18일 | B3:1E:B1:B7:40:E3:6C:84:02:DA:DC:37:D4:4D:F5:D4:67:49:52:F9 | 
| mozillacert59.pem |  2018년 6월 18일 | 36:79:CA:35:66:87:72:30:4D:30:A5:FB:87:3B:0F:A7:7B:B7:0D:54 | 
| thawtepremiumserverca |  2018년 4월 21일 | E0:AB:05:94:20:72:54:93:05:60:62:02:36:70:F7:CD:2E:FC:66:66 | 
| mozillacert117.pem |  2018년 6월 18일 | D4:DE:20:D0:5E:66:FC:53:FE:1A:50:88:2C:78:DB:28:52:CA:E4:74 | 
| utnuserfirstclientauthemailca |  2018년 4월 21일 | B1:72:B1:A5:6D:95:F9:1F:E5:02:87:E1:4D:37:EA:6A:44:63:76:8A | 
| entrustrootcag2 |  2018년 4월 21일 | 8C:F4:27:FD:79:0C:3A:D1:66:06:8D:E8:1E:57:EF:BB:93:22:72:D4 | 
| mozillacert109.pem |  2018년 6월 18일 | B5:61:EB:EA:A4:DE:E4:25:4B:69:1A:98:A5:57:47:C2:34:C7:D9:71 | 
| digicerttrustedrootg4 |  2018년 6월 18일 | DD:FB:16:CD:49:31:C9:73:A2:03:7D:3F:C8:3A:4D:7D:77:5D:05:E4 | 
| gdroot-g2.pem |  2018년 6월 18일 | 47:BE:AB:C9:22:EA:E8:0E:78:78:34:62:A7:9F:45:C2:54:FD:E6:8B | 
| comodoaaaservicesroot |  2018년 6월 18일 | D1:EB:23:A4:6D:17:D6:8F:D9:25:64:C2:F1:F1:60:17:64:D8:E3:49 | 
| mozillacert4.pem |  2018년 6월 18일 | E3:92:51:2F:0A:CF:F5:05:DF:F6:DE:06:7F:75:37:E1:65:EA:57:4B | 
| verisignclass3publicprimarycertificationauthorityg5 |  2018년 6월 18일 | 4E:B6:D5:78:49:9B:1C:CF:5F:58:1E:AD:56:BE:3D:9B:67:44:A5:E5 | 
| chambersofcommerceroot2008 |  2018년 6월 18일 | 78:6A:74:AC:76:AB:14:7F:9C:6A:30:50:BA:9E:A8:7E:FE:9A:CE:3C | 
| verisignclass3publicprimarycertificationauthorityg4 |  2018년 6월 18일 | 22:D5:D8:DF:8F:02:31:D1:8D:F7:9D:B7:CF:8A:2D:64:C9:3F:6C:3A | 
| verisignclass3publicprimarycertificationauthorityg3 |  2018년 6월 18일 | 13:2D:0D:45:53:4B:69:97:CD:B2:D5:C3:39:E2:55:76:60:9B:5C:C6 | 
| thawtepersonalfreemailca |  2018년 4월 21일 | E6:18:83:AE:84:CA:C1:C1:CD:52:AD:E8:E9:25:2B:45:A6:4F:B7:E2 | 
| verisignc1g2.pem |  2018년 6월 18일 | 27:3E:E1:24:57:FD:C4:F9:0C:55:E8:2B:56:16:7F:62:F5:32:E5:47 | 
| gtecybertrustglobalca |  2018년 4월 21일 | 97:81:79:50:D8:1C:96:70:CC:34:D8:09:CF:79:44:31:36:7E:F4:74 | 
| trustcenteruniversalcai |  2018년 4월 21일 | 6B:2F:34:AD:89:58:BE:62:FD:B0:6B:5C:CE:BB:9D:D9:4F:4E:39:F3 | 
| camerfirmachamberscommerceca |  2018년 4월 21일 | 6E:3A:55:A4:19:0C:19:5C:93:84:3C:C0:DB:72:2E:31:30:61:F0:B1 | 
| verisignclass1ca |  2018년 4월 21일 | CE:6A:64:A3:09:E4:2F:BB:D9:85:1C:45:3E:64:09:EA:E8:7D:60:F1 | 

# AWS AppSync 해석기 매핑 템플릿 변경 로그
<a name="resolver-mapping-template-changelog"></a>

**참고**  
이제 우리는 주로 APPSYNC\$1JS 런타임과 해당 문서를 지원합니다. [여기](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)에서 APPSYNC\$1JS 런타임과 해당 안내서를 사용해 보세요.

해석기 및 함수 매핑 템플릿에는 버전이 지정됩니다. `2018-05-29` 등 매핑 템플릿 버전은 다음을 결정합니다.
+ 요청 템플릿에서 제공하는 데이터 소스 요청 구성의 예상 모양
+ 요청 매핑 템플릿 및 응답 매핑 템플릿의 실행 동작

버전은 YYYY-MM-DD 형식으로 표시되는데, 이후 날짜는 최신 버전에 해당합니다. 이 페이지에는 AWS AppSync에서 현재 지원되는 매핑 템플릿 버전 간의 차이가 나와 있습니다.

**Topics**
+ [버전 매트릭스에 따른 데이터 원본 작업 가용성](#aws-appsync-resolver-mapping-template-operation-availability-per-version)
+ [유닛 해석기 매핑 템플릿에 대한 버전 변경](#changing-the-version-on-a-unit-resolver-mapping-template)
+ [함수에 대한 버전 변경](#changing-the-version-on-a-function)
+ [2018-05-29](#aws-appsync-resolver-mapping-template-version-2018-05-29)
+ [2017-02-28](#aws-appsync-resolver-mapping-template-version-2017-02-28)

## 버전 매트릭스에 따른 데이터 원본 작업 가용성
<a name="aws-appsync-resolver-mapping-template-operation-availability-per-version"></a>


| 지원되지 않는 작업/버전 | 2017-02-28 | 2018-05-29 | 
| --- | --- | --- | 
|  AWS Lambda 간접 호출  |  예  |  예  | 
|  AWS Lambda BatchInvoke  |  예  |  예  | 
|  None Datasource  |  예  |  예  | 
|  Amazon OpenSearch GET  |  예  |  예  | 
|  Amazon OpenSearch POST  |  예  |  예  | 
|  Amazon OpenSearch PUT  |  예  |  예  | 
|  Amazon OpenSearch DELETE  |  예  |  예  | 
|  Amazon OpenSearch GET  |  예  |  예  | 
|  DynamoDB GetItem  |  예  |  예  | 
|  DynamoDB Scan  |  예  |  예  | 
|  DynamoDB Query  |  예  |  예  | 
|  DynamoDB DeleteItem  |  예  |  예  | 
|  DynamoDB PutItem  |  예  |  예  | 
|  DynamoDB BatchGetItem  |  아니요  |  예  | 
|  DynamoDB BatchPutItem  |  아니요  |  예  | 
|  DynamoDB BatchDeleteItem  |  아니요  |  예  | 
|  HTTP  |  아니요  |  예  | 
|  Amazon RDS  |  아니요  |  예  | 

 **참고**: 현재, 함수에서는 **2018-05-29** 버전만 지원됩니다.

## 유닛 해석기 매핑 템플릿에 대한 버전 변경
<a name="changing-the-version-on-a-unit-resolver-mapping-template"></a>

유닛 해석기의 경우 버전은 요청 매핑 템플릿 본문의 일부로 지정됩니다. 버전을 업데이트하려면 `version` 필드를 새 버전으로 업데이트하기만 하면 됩니다.

예를 들어 AWS Lambda 템플릿에서 버전을 업데이트하려면

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

아래와 같이 버전 필드를 `2017-02-28`에서 `2018-05-29`로 업데이트해야 합니다.

```
{
    "version": "2018-05-29", ## Note the version
    "operation": "Invoke",
    "payload": {
        "field": "getPost",
        "arguments": $utils.toJson($context.arguments)
    }
}
```

## 함수에 대한 버전 변경
<a name="changing-the-version-on-a-function"></a>

함수의 경우 버전은 함수 객체에 대한 `functionVersion` 필드로 지정됩니다. 버전을 업데이트하려면 `functionVersion`을 업데이트하기만 하면 됩니다. *참고:* 현재, 함수에는 `2018-05-29`만 지원됩니다.

다음은 기존 함수 버전을 업데이트하기 위한 CLI 명령 예제입니다.

```
aws appsync update-function \
--api-id REPLACE_WITH_API_ID \
--function-id REPLACE_WITH_FUNCTION_ID \
--data-source-name "PostTable" \
--function-version "2018-05-29" \
--request-mapping-template "{...}" \
--response-mapping-template "\$util.toJson(\$ctx.result)"
```

 **참고:** 적용되지 않을 것이기 때문에 버전 필드는 함수 요청 매핑 템플릿에서 생략하는 것이 좋습니다. 함수 요청 매핑 템플릿 내에서 버전을 지정하면 `functionVersion` 필드의 값으로 버전이 재지정됩니다.

## 2018-05-29
<a name="aws-appsync-resolver-mapping-template-version-2018-05-29"></a>

### 동작 변경
<a name="behavior-change"></a>
+ 데이터 원본 호출 결과가 `null`이면 응답 매핑 템플릿이 실행됩니다.
+ 데이터 원본을 호출했는데 오류가 발생하면 오류는 직접 처리해야 합니다. 평가된 응답 매핑 템플릿은 **항상** GraphQL 응답 `data` 블록 내에 배치됩니다.

### 추론
<a name="reasoning"></a>
+ `null` 호출 결과에는 의미가 있는데, 일부 애플리케이션 사용 사례에서는 사용자 지정 방식으로 `null` 결과를 처리하고자 할 수 있습니다. 예를 들어, 애플리케이션이 권한 부여 확인을 수행하기 위해 Amazon DynamoDB 테이블에 레코드가 있는지 확인하려고 할 수 있습니다. 이러한 경우 `null` 호출 결과는 사용자가 인증되지 않았을 수 있음을 의미합니다. 이제, 응답 매핑 템플릿을 실행하면 권한 없음 오류를 발생시킬 수 있습니다. 이 동작은 API 설계자에게 더 정확한 제어 권한을 제공합니다.

다음 응답 매핑 템플릿에 대해 생각해 보겠습니다.

```
$util.toJson($ctx.result)
```

이전에는 `2017-02-28`을 사용했을 때 `$ctx.result`가 null을 반환하면 응답 매핑 템플릿이 실행되지 않았습니다. 이제, `2018-05-29`를 사용하면 이 시나리오를 처리할 수 있습니다. 예를 들어, 다음과 같이 권한 부여 오류가 실행되도록 선택할 수 있습니다.

```
# throw an unauthorized error if the result is null
#if ( $util.isNull($ctx.result) )
    $util.unauthorized()
#end
$util.toJson($ctx.result)
```

 **참고:** 데이터 원본에서 반환되는 오류는 때때로 치명적이지 않고 심지어 예측되는 경우도 있는데, 이는 응답 매핑 템플릿에 호출 오류를 처리하고 해당 오류를 무시하거나, 다시 실행하거나, 다른 오류를 실행할지 여부를 결정할 수 있는 유연성이 있어야 하기 때문입니다.

다음 응답 매핑 템플릿에 대해 생각해 보겠습니다.

```
$util.toJson($ctx.result)
```

이전에 `2017-02-28`을 사용했을 때 호출 오류가 발생하면 응답 매핑 템플릿이 평가되고 그 결과가 GraphQL 응답의 `errors` 블록에 자동으로 배치되었습니다. 이제, `2018-05-29`를 사용하면 오류와 관련해 수행할 작업을 선택하거나, 오류를 다시 실행하거나, 다른 오류를 실행하거나, 데이터를 반환하는 동안 오류를 추가할 수 있습니다.

### 호출 오류 다시 실행
<a name="re-raise-an-invocation-error"></a>

다음 응답 템플릿에서는 데이터 원본에서 반환되는 것과 동일한 오류를 실행합니다.

```
#if ( $ctx.error )
    $util.error($ctx.error.message, $ctx.error.type)
#end
$util.toJson($ctx.result)
```

호출 오류(예: `$ctx.error` is present)가 발생하면 응답은 다음과 같이 표시됩니다.

```
{
    "data": {
        "getPost": null
    },
    "errors": [
        {
            "path": [
                "getPost"
            ],
            "errorType": "DynamoDB:ConditionalCheckFailedException",
            "message": "Conditional check failed exception...",
            "locations": [
                {
                    "line": 5,
                    "column": 5
                }
            ]
        }
    ]
}
```

### 다른 오류 실행
<a name="raise-a-different-error"></a>

다음 응답 템플릿에서는 데이터 원본에서 반환되는 오류를 처리한 후 고유한 사용자 지정 오류를 실행합니다.

```
#if ( $ctx.error )
    #if ( $ctx.error.type.equals("ConditionalCheckFailedException") )
        ## we choose here to change the type and message of the error for ConditionalCheckFailedExceptions
        $util.error("Error while updating the post, try again. Error: $ctx.error.message", "UpdateError")
    #else
        $util.error($ctx.error.message, $ctx.error.type)
    #end
#end
$util.toJson($ctx.result)
```

호출 오류(예: `$ctx.error` is present)가 발생하면 응답은 다음과 같이 표시됩니다.

```
{
    "data": {
        "getPost": null
    },
    "errors": [
        {
            "path": [
                "getPost"
            ],
            "errorType": "UpdateError",
            "message": "Error while updating the post, try again. Error: Conditional check failed exception...",
            "locations": [
                {
                    "line": 5,
                    "column": 5
                }
            ]
        }
    ]
}
```

### 반환 데이터에 오류 추가
<a name="append-an-error-to-return-data"></a>

다음 응답 템플릿에서는 응답 내에서 데이터를 반환하는 동안 데이터 원본에서 반환되는 것과 동일한 오류를 추가합니다. 이를 부분 응답이라고도 합니다.

```
#if ( $ctx.error )
    $util.appendError($ctx.error.message, $ctx.error.type)
    #set($defaultPost = {id: "1", title: 'default post'})
    $util.toJson($defaultPost)
#else
    $util.toJson($ctx.result)
#end
```

호출 오류(예: `$ctx.error` is present)가 발생하면 응답은 다음과 같이 표시됩니다.

```
{
    "data": {
        "getPost": {
            "id": "1",
            "title: "A post"
        }
    },
    "errors": [
        {
            "path": [
                "getPost"
            ],
            "errorType": "ConditionalCheckFailedException",
            "message": "Conditional check failed exception...",
            "locations": [
                {
                    "line": 5,
                    "column": 5
                }
            ]
        }
    ]
}
```

#### *2017-02-28*에서 *2018-05-29*로 마이그레이션
<a name="migrating-from-2017-02-28-to-2018-05-29"></a>

**2017-02-28**에서 **2018-05-29**로 마이그레이션은 간단합니다. 해석기 요청 매핑 템플릿 또는 함수 버전 객체에서 버전 필드를 변경합니다. 그러나 **2018-05-29** 실행은 **2017-02-28** 실행과 다르게 동작하는데, 동작 변경 사항은 [여기](#aws-appsync-resolver-mapping-template-version-2018-05-29)에 간단하게 정리되어 있습니다.

#### *2017-02-28*에서 *2018-05-29*로 동일한 실행 동작 보존
<a name="preserving-the-same-execution-behavior-from-2017-02-28-to-2018-05-29"></a>

경우에 따라 **2018-05-29** 버전의 템플릿을 실행하는 동안 **2017-02-28** 버전과 동일한 실행 동작을 유지할 수 있습니다.

### 예: DynamoDB PutItem
<a name="example-dynamodb-putitem"></a>

다음과 같은 **2017-02-28** DynamoDB PutItem 요청 템플릿이 있습니다.

```
{
    "version" : "2017-02-28",
    "operation" : "PutItem",
    "key": {
        "foo" : ... typed value,
        "bar" : ... typed value
    },
    "attributeValues" : {
        "baz" : ... typed value
    },
    "condition" : {
       ...
    }
}
```

응답 템플릿은 다음과 같습니다.

```
$util.toJson($ctx.result)
```

**2018-05-29**로 마이그레이션하면 이러한 템플릿은 다음과 같이 변경됩니다.

```
{
    "version" : "2018-05-29", ## Note the new 2018-05-29 version
    "operation" : "PutItem",
    "key": {
        "foo" : ... typed value,
        "bar" : ... typed value
    },
    "attributeValues" : {
        "baz" : ... typed value
    },
    "condition" : {
       ...
    }
}
```

응답 템플릿은 다음과 같이 변경됩니다.

```
## If there is a datasource invocation error, we choose to raise the same error
## the field data will be set to null.
#if($ctx.error)
  $util.error($ctx.error.message, $ctx.error.type, $ctx.result)
#end

## If the data source invocation is null, we return null.
#if($util.isNull($ctx.result))
  #return
#end

$util.toJson($ctx.result)
```

따라서 오류를 처리하는 것은 고객의 책임입니다. 여기서는 DynamoDB에서 반환된 `$util.error()`를 사용하여 동일한 오류를 실행하도록 선택합니다. 이 코드 조각은 매핑 템플릿을 **2018-05-29**로 변환하도록 수정할 수 있습니다. 응답 템플릿이 다른 경우에는 실행 동작의 변경을 고려해야 합니다.

### 예: DynamoDB GetItem
<a name="example-dynamodb-getitem"></a>

다음과 같은 **2017-02-28** DynamoDB GetItem 요청 템플릿이 있습니다.

```
{
    "version" : "2017-02-28",
    "operation" : "GetItem",
    "key" : {
        "foo" : ... typed value,
        "bar" : ... typed value
    },
    "consistentRead" : true
}
```

응답 템플릿은 다음과 같습니다.

```
## map table attribute postId to field Post.id
$util.qr($ctx.result.put("id", $ctx.result.get("postId")))

$util.toJson($ctx.result)
```

**2018-05-29**로 마이그레이션하면 이러한 템플릿은 다음과 같이 변경됩니다.

```
{
    "version" : "2018-05-29", ## Note the new 2018-05-29 version
    "operation" : "GetItem",
    "key" : {
        "foo" : ... typed value,
        "bar" : ... typed value
    },
    "consistentRead" : true
}
```

응답 템플릿은 다음과 같이 변경됩니다.

```
## If there is a datasource invocation error, we choose to raise the same error
#if($ctx.error)
  $util.error($ctx.error.message, $ctx.error.type)
#end

## If the data source invocation is null, we return null.
#if($util.isNull($ctx.result))
  #return
#end

## map table attribute postId to field Post.id
$util.qr($ctx.result.put("id", $ctx.result.get("postId")))

$util.toJson($ctx.result)
```

**2017-02-28** 버전에서 데이터 원본 호출이 `null`이었으면 이는 키를 일치시키는 DynamoDB 테이블에 항목이 없음을 의미해 응답 매핑 템플릿이 실행되지 않았을 것입니다. 대부분의 경우 이러한 결과는 괜찮을 수 있지만, `$ctx.result`가 `null`이 아니길 기대하는 경우에는 이제, 해당 시나리오를 처리해야 합니다.

## 2017-02-28
<a name="aws-appsync-resolver-mapping-template-version-2017-02-28"></a>

### 특성
<a name="characteristics"></a>
+ 데이터 원본 호출 결과가 `null`이면 응답 매핑 템플릿이 실행되지 **않습니다**.
+ 데이터 원본 호출 시 오류가 발생하면 응답 매핑 템플릿이 실행되고 평가된 결과가 GraphQL 응답 `errors.data` 블록 내에 배치됩니다.