

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

# AWS AppSync 해석기 참조(JavaScript)
<a name="resolver-reference-js-version"></a>

다음 섹션에 `APPSYNC_JS` 런타임 및 JavaScript 해석기 참조가 포함되어 있습니다.
+  [ JavaScript 해석기 개요 ](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html) - AWS AppSync에서 해석기가 작동하는 방법에 대해 자세히 알아봅니다.
+  [ 해석기 컨텍스트 객체 참조 ](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference-js.html) - 컨텍스트 객체와 이 객체가 해석기에서 사용되는 방식에 대해 자세히 알아봅니다.
+  [ 해석기 및 함수용 JavaScript 런타임 기능 ](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-util-reference-js.html) - 지원되는 런타임 기능과 유틸리티를 사용하여 코드를 단순화하는 방법에 대해 자세히 알아봅니다.
+  [ DynamoDB용 JavaScript 해석기 함수 참조 ](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html) - 해석기가 DynamoDB와 상호 작용하는 방법에 대해 자세히 알아봅니다.
+  [ OpenSearch용 JavaScript 해석기 함수 참조 ](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-elasticsearch-js.html) - 해석기 요청과 응답 구조 및 OpenSearch Service와의 상호 작용에 대해 자세히 알아봅니다.
+  [ Lambda용 JavaScript 해석기 함수 참조 ](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-lambda-js.html) - 해석기 요청과 응답 구조 및 Lambda와의 상호 작용에 대해 자세히 알아봅니다.
+  [ EventBridge 데이터 소스용 JavaScript 해석기 함수 참조 ](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-eventbridge-js.html) - 해석기 요청과 응답 구조 및 EventBridge와의 상호 작용에 대해 자세히 알아봅니다.
+  [ None 데이터 소스용 JavaScript 해석기 함수 참조 ](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-none-js.html) - 해석기 요청과 응답 구조 및 None 데이터 소스와의 상호 작용에 대해 자세히 알아봅니다.
+  [ HTTP용 JavaScript 해석기 함수 참조 ](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-http-js.html) - 해석기 요청과 응답 구조 및 HTTP 엔드포인트와의 상호 작용에 대해 자세히 알아봅니다.
+  [ Amazon RDS용 JavaScript 해석기 함수 참조 ](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-rds-js.html) - 해석기 구조 및 RDS와의 상호 작용에 대해 자세히 알아봅니다.
+  [ Amazon Bedrock용 JavaScript 해석기 함수 참조](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-bedrock-js.html) - 해석기 구조 및 Bedrock과의 상호 작용에 대해 자세히 알아봅니다.

# AWS AppSync JavaScript 해석기 개요
<a name="resolver-reference-overview-js"></a>

AWS AppSync를 사용하면 데이터 소스에 대한 작업을 수행하여 GraphQL 요청에 응답할 수 있습니다. 쿼리, 뮤테이션 또는 구독을 실행하려는 각 GraphQL 필드에 대해 해석기를 첨부해야 합니다.

해석기는 GraphQL과 데이터 소스를 연결하는 커넥터입니다. 수신되는 GraphQL 요청을 백엔드 데이터 소스에 대한 지침으로 변환하는 방법과 해당 데이터 소스의 응답을 다시 GraphQL 응답으로 변환하는 방법을 AWS AppSync에 알려줍니다. AWS AppSync를 사용하면 JavaScript를 사용하여 해석기를 작성하고 AWS AppSync(`APPSYNC_JS`) 환경에서 실행할 수 있습니다.

AWS AppSync를 사용하면 파이프라인에서 여러 AWS AppSync 함수로 구성된 단위 해석기 또는 파이프라인 해석기를 작성할 수 있습니다.

## 지원되는 런타임 기능
<a name="runtime-support-js"></a>

 AWS AppSync JavaScript 런타임은 JavaScript 라이브러리, 유틸리티 및 기능의 하위 집합을 제공합니다. `APPSYNC_JS` 런타임에서 지원되는 전체 기능 목록은 [해석기 및 함수에 대한 JavaScript 런타임 기능](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-util-reference-js.html)을 참조하세요.

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

유닛 해석기는 데이터 소스에 대해 실행되는 요청 및 응답 핸들러를 정의하는 코드로 구성됩니다. 요청 핸들러는 컨텍스트 객체를 인수로 사용하고 데이터 소스를 호출하는 데 사용된 요청 페이로드를 반환합니다. 응답 핸들러는 실행된 요청의 결과와 함께 데이터 소스로부터 페이로드를 다시 받습니다. 응답 핸들러는 페이로드를 GraphQL 응답으로 변환하여 GraphQL 필드를 해결합니다. 아래 예제에서 해석기는 DynamoDB 데이터 소스에서 항목을 검색합니다.

```
import * as ddb from '@aws-appsync/utils/dynamodb'

export function request(ctx) {
  return ddb.get({ key: { id: ctx.args.id } });
}

export const response = (ctx) => ctx.result;
```

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

파이프라인 해석기는 요청 핸들러 및 응답 핸들러와 함수 목록을 정의하는 코드로 구성됩니다. 각 함수에는 데이터 소스에 대해 실행되는 **요청** 및 **응답** 핸들러가 있습니다. 파이프라인 해석기는 함수 목록에 실행을 위임하기 때문에 자신은 어떠한 데이터 소스에도 연결되지 않습니다. 유닛 해석기와 함수는 데이터 원본에 대해 작업을 실행하는 기본 요소입니다.

### 파이프라인 해석기 요청 핸들러
<a name="request-handler-js"></a>

이 파이프라인 해석기의 요청 핸들러(이전 단계)를 사용하면 정의된 함수를 실행하기 전에 몇 가지 준비 로직을 수행할 수 있습니다.

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

파이프라인 해석기가 순서대로 실행하는 함수 목록입니다. 파이프라인 해석기 요청 핸들러 평가 결과는 첫 번째 함수에 `ctx.prev.result`로 사용할 수 있습니다. 각 함수 평가 결과는 다음 함수에 `ctx.prev.result`로 사용할 수 있습니다.

### 파이프라인 해석기 응답 핸들러
<a name="response-handler-js"></a>

이 파이프라인 해석기의 응답 핸들러를 사용하면 마지막 함수의 출력에서 예상 GraphQL 필드 유형으로 몇 가지 최종 로직을 수행할 수 있습니다. 함수 목록의 마지막 함수 출력은 파이프라인 해석기 응답 핸들러에서 `ctx.prev.result` 또는 `ctx.result`로 사용할 수 있습니다.

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

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

1.  파이프라인 해석기 요청 핸들러

1.  함수 1: 함수 요청 핸들러 

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

1.  함수 1: 함수 응답 핸들러 

1.  함수 2: 함수 요청 핸들러 

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

1.  함수 2: 함수 응답 핸들러 

1.  파이프라인 해석기 응답 핸들러 

![\[GraphQL request flow diagram showing interactions between request, data sources, and response components.\]](http://docs.aws.amazon.com/ko_kr/appsync/latest/devguide/images/appsync-js-resolver-logic.png)


### 유용한 `APPSYNC_JS` 런타임 내장 유틸리티
<a name="useful-utilities-js"></a>

다음 유틸리티는 파이프라인 해석기로 작업할 때 유용할 수 있습니다.

#### ctx.stash
<a name="ctx-stash-js"></a>

stash는 각 해석기 및 함수 요청 및 응답 핸들러 내에서 사용할 수 있는 객체입니다. 단일 해석기가 실행되는 동안에는 동일한 stash 인스턴스가 사용됩니다. 즉, stash를 사용하여 요청 및 응답 핸들러와 파이프라인 해석기의 함수 간에 임의의 데이터를 전달할 수 있습니다. 정규 JavaScript 객체처럼 stash를 테스트할 수 있습니다.

#### ctx.prev.result
<a name="ctx-prev-result-js"></a>

`ctx.prev.result`는 파이프라인에서 실행된 이전 작업의 결과를 나타냅니다. 이전 작업이 파이프라인 해석기 요청 처리기였던 경우, `ctx.prev.result`는 체인의 첫 번째 함수에서 사용할 수 있게 됩니다. 이전 작업이 첫 번째 함수였으면 `ctx.prev.result`는 첫 번째 함수의 결과를 나타내고, 파이프라인의 두 번째 함수에 사용할 수 있습니다. 이전 작업이 마지막 함수였으면 `ctx.prev.result`는 마지막 함수의 결과를 나타내고, 파이프라인 해석기 응답 핸들러에 사용할 수 있습니다.

#### util.error
<a name="util-error-js"></a>

`util.error` 유틸리티는 필드 오류를 발생시키는 데 유용합니다. 함수 요청 또는 응답 핸들러 내에서 `util.error`를 사용하면 즉시 필드 오류가 발생해 후속 함수가 실행되지 않도록 방지합니다. 자세한 내용과 기타 `util.error` 서명을 보려면 [해석기 및 함수에 대한 JavaScript 런타임 기능](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-util-reference-js.html)을 방문하세요.

#### util.appendError
<a name="util-appenderror-js"></a>

`util.appendError`는 `util.error()`와 유사하지만 핸들러 평가를 중단하지 않는다는 큰 차이점이 있습니다. 대신 필드에 오류가 있다는 신호를 보내지만 핸들러가 계속해서 평가되도록 하고 이어서 데이터를 반환합니다. 함수 내에서 `util.appendError`를 사용하면 파이프라인의 실행 흐름이 중단되지 않습니다. 자세한 내용과 기타 `util.error` 서명을 보려면 [해석기 및 함수에 대한 JavaScript 런타임 기능](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-util-reference-js.html)을 방문하세요.

#### runtime.earlyReturn
<a name="runtime-earlyreturn-js"></a>

이 `runtime.earlyReturn` 함수를 사용하면 모든 요청 함수에서 조기에 반환할 수 있습니다. `runtime.earlyReturn`을 해석기 요청 핸들러 내에서 사용하면 해석기에서 반환됩니다. AWS AppSync 함수 요청 핸들러에서 호출하면 함수에서 반환되어 파이프라인의 다음 함수 또는 해석기 응답 핸들러로 계속 실행됩니다.

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

파이프라인 해석기에는 파이프라인의 함수 실행을 둘러싼 요청 및 응답 핸들러도 있습니다. 요청 핸들러는 첫 번째 함수 요청 전에 실행되고, 응답 핸들러는 마지막 함수 응답 후에 실행됩니다. 해석기 요청 핸들러는 파이프라인의 함수에서 사용할 데이터를 설정할 수 있습니다. 해석기 응답 핸들러는 GraphQL 필드 출력 유형에 매핑되는 데이터를 반환하는 역할을 합니다. 아래 예에서 해석기 요청 처리기는 `allowedGroups`를 정의합니다. 반환된 데이터는 이러한 그룹 중 하나에 속해야 합니다. 이 값은 해석기의 함수에서 데이터를 요청하는 데 사용할 수 있습니다. 해석기의 응답 핸들러는 최종 검사를 수행하고 결과를 필터링하여 허용된 그룹에 속한 항목만 반환되도록 합니다.

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

/**
 * Called before the request function of the first AppSync function in the pipeline.
 *  @param ctx the context object holds contextual information about the function invocation.
 */
export function request(ctx) {
  ctx.stash.allowedGroups = ['admin'];
  ctx.stash.startedAt = util.time.nowISO8601();
  return {};
}
/**
 * Called after the response function of the last AppSync function in the pipeline.
 * @param ctx the context object holds contextual information about the function invocation.
 */
export function response(ctx) {
  const result = [];
  for (const item of ctx.prev.result) {
    if (ctx.stash.allowedGroups.indexOf(item.group) > -1) result.push(item);
  }
  return result;
}
```

#### AWS AppSync 함수 작성
<a name="writing-functions"></a>

AWS AppSync 함수를 사용하면 스키마의 여러 해석기에서 재사용할 수 있는 공통 로직을 작성할 수 있습니다. 예를 들어 Amazon DynamoDB 데이터 소스에서 항목을 쿼리`QUERY_ITEMS`하는 역할을 하는 라는 one AWS AppSync 함수가 있을 수 있습니다. 항목을 쿼리하려는 해석기의 경우 해석기의 파이프라인에 함수를 추가하고 사용할 쿼리 색인을 제공하면 됩니다. 로직을 다시 구현할 필요는 없습니다.

## 추가 주제
<a name="supplemental-topics"></a>

**주제**
+ [Amazon DynamoDB를 사용한 파이프라인 해석기 예제](https://docs.aws.amazon.com/appsync/latest/devguide/writing-code.html)
+ [`APPSYNC_JS` 런타임의 유틸리티 구성](https://docs.aws.amazon.com/appsync/latest/devguide/utility-resolvers.html)
+ [`APPSYNC_JS` 런타임용 번들링, TypeScript 및 소스 맵](https://docs.aws.amazon.com/appsync/latest/devguide/additional-utilities.html)
+ [해석기 및 함수 핸들러 테스트](https://docs.aws.amazon.com/appsync/latest/devguide/test-resolvers.html)
+ [VTL에서 JavaScript로 마이그레이션](https://docs.aws.amazon.com/appsync/latest/devguide/migrating-resolvers.html)
+ [직접 데이터 소스 액세스와 Lambda 데이터 소스를 통한 프록시 중 선택](https://docs.aws.amazon.com/appsync/latest/devguide/choosing-data-source.html)

# Amazon DynamoDB를 사용한 파이프라인 해석기 예제
<a name="writing-code"></a>

다음 GraphQL 쿼리를 사용하여 Amazon DynamoDB 데이터 소스에서 `Post` 유형을 반환하는 `getPost(id:ID!)`라는 필드에 파이프라인 해석기를 연결한다고 가정해 보겠습니다.

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

먼저 아래 코드를 사용하여 간단한 해석기를 `Query.getPost`에 연결합니다. 다음은 간단한 해석기 코드의 예입니다. 요청 핸들러에는 로직이 정의되어 있지 않으며, 응답 핸들러는 단순히 마지막 함수의 결과를 반환합니다.

```
/**
 * Invoked **before** the request handler of the first AppSync function in the pipeline.
 * The resolver `request` handler allows to perform some preparation logic
 * before executing the defined functions in your pipeline.
 * @param ctx the context object holds contextual information about the function invocation.
 */
export function request(ctx) {
  return {}
}

/**
 * Invoked **after** the response handler of the last AppSync function in the pipeline.
 * The resolver `response` handler allows to perform some final evaluation logic
 * from the output of the last function to the expected GraphQL field type.
 * @param ctx the context object holds contextual information about the function invocation.
 */
export function response(ctx) {
  return ctx.prev.result
}
```

다음으로, 데이터 소스에서 사후 항목을 검색하는 함수 `GET_ITEM`을 정의합니다.

```
import { util } from '@aws-appsync/utils'
import * as ddb from '@aws-appsync/utils/dynamodb'

/**
 * Request a single item from the attached DynamoDB table datasource
 * @param ctx the context object holds contextual information about the function invocation.
 */
export function request(ctx) {
	const { id } = ctx.args
	return ddb.get({ key: { id } })
}

/**
 * Returns the result
 * @param ctx the context object holds contextual information about the function invocation.
 */
export function response(ctx) {
	const { error, result } = ctx
	if (error) {
		return util.appendError(error.message, error.type, result)
	}
	return ctx.result
}
```

요청 중에 오류가 발생하면 함수의 응답 핸들러가 GraphQL 응답에서 호출 클라이언트에 반환될 오류를 추가합니다. `GET_ITEM` 함수를 해석기 함수 목록에 추가합니다. 쿼리를 실행하면 `GET_ITEM` 함수의 요청 핸들러는 AWS AppSync의 DynamoDB 모듈에서 제공하는 유틸리티를 사용하여를 키`id`로 사용하여 `DynamoDBGetItem` 요청을 생성합니다.는 적절한 `GetItem` 작업을 `ddb.get({ key: { id } })` 생성합니다.

```
{
    "operation" : "GetItem",
    "key" : {
        "id" : { "S" : "1" }
    }
}
```

AWS AppSync 는 요청을 사용하여 Amazon DynamoDB에서 데이터를 가져옵니다. 데이터가 반환되면 `GET_ITEM` 함수의 응답 핸들러에서 처리되며, 이 핸들러는 오류를 확인한 다음 결과를 반환합니다.

```
{
  "result" : {
    "id": 1,
    "title": "hello world",
    "content": "<long story>"
  }
}
```

마지막으로, 해석기의 응답 핸들러는 결과를 직접 반환합니다.

## 오류 작업
<a name="working-with-errors"></a>

요청 중에 함수에서 오류가 발생하면 `ctx.error`의 함수 응답 핸들러에서 오류를 확인할 수 있습니다. `util.appendError` 유틸리티를 사용하여 GraphQL 응답에 오류를 추가할 수 있습니다. stash를 사용하여 파이프라인의 다른 함수에서 오류를 확인하도록 할 수 있습니다. 아래 예를 참조하세요.

```
/**
 * Returns the result
 * @param ctx the context object holds contextual information about the function invocation.
 */
export function response(ctx) {
  const { error, result } = ctx;
  if (error) {
    if (!ctx.stash.errors) ctx.stash.errors = []
    ctx.stash.errors.push(ctx.error)
    return util.appendError(error.message, error.type, result);
  }
  return ctx.result;
}
```

# `APPSYNC_JS` 런타임의 유틸리티 구성
<a name="utility-resolvers"></a>

AWS AppSync 는 `APPSYNC_JS` 런타임으로 해석기를 개발하는 데 도움이 되는 두 개의 라이브러리를 제공합니다.
+ `@aws-appsync/eslint-plugin` - 개발 중에 문제를 빠르게 발견하고 수정합니다.
+ `@aws-appsync/utils` - 코드 편집기에서 유형 검증 및 자동 완성 기능을 제공합니다.

## eslint 플러그인 구성
<a name="utility-resolvers-configuring-eslint-plugin"></a>

[ESLint](https://eslint.org/)는 코드를 정적으로 분석하여 문제를 빠르게 찾아내는 도구입니다. 지속적인 통합 파이프라인의 일부로 ESLint를 실행할 수 있습니다. `@aws-appsync/eslint-plugin`은 `APPSYNC_JS` 런타임을 활용할 때 코드에서 잘못된 구문을 찾아내는 ESLint 플러그인입니다. 플러그인을 사용하면 변경 내용을 클라우드로 푸시하지 않고도 개발 중에 코드에 대한 피드백을 빠르게 받을 수 있습니다.

`@aws-appsync/eslint-plugin`은 개발 중에 사용할 수 있는 두 가지 규칙 세트를 제공합니다.

**"plugin:@aws-appsync/base"**는 프로젝트에서 활용할 수 있는 다음 기본 규칙 세트를 구성합니다.


| 규칙 | 설명 | 
| --- | --- | 
| no-async | 비동기식 프로세스 및 약속은 지원되지 않습니다. | 
| no-await | 비동기식 프로세스 및 약속은 지원되지 않습니다. | 
| no-classes | 클래스는 지원되지 않습니다. | 
| no-for | for는 지원되지 않습니다(for-in 및 for-of는 지원되는 경우 제외). | 
| no-continue | continue는 지원되지 않습니다. | 
| no-generators | 생성기는 지원되지 않습니다. | 
| no-yield | yield는 지원되지 않습니다. | 
| no-labels | 레이블은 지원되지 않습니다. | 
| no-this | this 키워드는 지원되지 않습니다. | 
| no-try | Try/catch 구조는 지원되지 않습니다. | 
| no-while | while 루프는 지원되지 않습니다. | 
| no-disallowed-unary-operators | \$1\$1, -- 및 \$1 단항 연산자는 허용되지 않습니다. | 
| no-disallowed-binary-operators | instanceof 연산자는 허용되지 않습니다. | 
| no-promise | 비동기식 프로세스 및 약속은 지원되지 않습니다. | 

**"plugin:@aws-appsync/recommended"**는 몇 가지 추가 규칙을 제공하지만 프로젝트에 TypeScript 구성을 추가해야 합니다.


| 규칙 | 설명 | 
| --- | --- | 
| no-recursion | 재귀 함수 호출은 허용되지 않습니다. | 
| no-disallowed-methods | 일부 메서드는 허용되지 않습니다. 지원되는 내장 함수 전체 세트는 [참조](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-util-reference-js.html)를 참조하세요. | 
| no-function-passing | 함수를 함수 인수로 함수에 전달하는 것은 허용되지 않습니다. | 
| no-function-reassign | 함수는 재할당할 수 없습니다. | 
| no-function-return | 함수는 함수의 반환값이 될 수 없습니다. | 

프로젝트에 플러그인을 추가하려면 [ESLint 시작하기](https://eslint.org/docs/latest/user-guide/getting-started#installation-and-usage)의 설치 및 사용 단계를 따르세요. 그런 다음 프로젝트 패키지 관리자(예: npm, Yarn 또는 pnpm)를 사용하여 프로젝트에 [플러그인](https://www.npmjs.com/package/@aws-appsync/eslint-plugin)을 설치합니다.

```
$ npm install @aws-appsync/eslint-plugin
```

`.eslintrc.{js,yml,json}` 파일에서 `extends` 속성에 **"plugin:@aws-appsync/base"** 또는 **"plugin:@aws-appsync/recommended"**를 추가합니다. 아래 코드 조각은 JavaScript의 기본 샘플 `.eslintrc` 구성입니다.

```
{
  "extends": ["plugin:@aws-appsync/base"]
}
```

**"plugin:@aws-appsync/recommended"** 규칙 세트를 사용하려면 필수 종속성을 설치하세요.

```
$ npm install -D @typescript-eslint/parser
```

그런 다음 `.eslintrc.js` 파일을 생성하려면:

```
{
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "ecmaVersion": 2018,
    "project": "./tsconfig.json"
  },
  "extends": ["plugin:@aws-appsync/recommended"]
}
```

# `APPSYNC_JS` 런타임용 번들링, TypeScript 및 소스 맵
<a name="additional-utilities"></a>

TypeScript는 유형 안전 및 조기 오류 감지를 제공하여 AWS AppSync 개발을 개선합니다. TypeScript 코드를 `APPSYNC_JS` 런타임에 사용하기 전에 로컬로 작성하고 JavaScript로 트랜스파일할 수 있습니다. 이 프로세스는 TypeScript를 설치하고 `APPSYNC_JS` 환경에 tsconfig.json을 구성하는 것으로 시작됩니다. 그런 다음, esbuild와 같은 번들링 도구를 사용하여 코드를 컴파일하고 번들링할 수 있습니다. Amplify CLI는 GraphQL 스키마에서 유형을 생성하므로 해석기 코드에서 해당 유형을 사용할 수 있습니다.

해석기 및 함수 코드에서는 `APPSYNC_JS` 요구 사항을 준수하는 한 사용자 지정 라이브러리와 외부 라이브러리를 모두 활용할 수 있습니다. 번들링 도구는 코드를 단일 파일로 결합하여 사용할 수 있습니다 AWS AppSync. 디버깅을 돕기 위해 소스 맵을 포함할 수 있습니다.

## 라이브러리 활용 및 코드 번들링
<a name="using-external-libraries"></a>

해석기 및 함수 코드에서는 `APPSYNC_JS` 요구 사항을 준수하는 한 사용자 지정 라이브러리와 외부 라이브러리를 모두 활용할 수 있습니다. 이렇게 하면 애플리케이션에서 기존 코드를 재사용할 수 있습니다. 여러 파일로 정의된 라이브러리를 사용하려면 [esbuild](https://esbuild.github.io/)와 같은 번들링 도구를 사용하여 코드를 단일 파일로 결합한 다음 AWS AppSync 해석기 또는 함수에 저장할 수 있습니다.

코드를 번들링할 때 다음 사항에 유의하세요.
+ `APPSYNC_JS`는 ECMAScript 모듈(ESM)만 지원합니다.
+ `@aws-appsync/*` 모듈은 `APPSYNC_JS`에 통합되므로 코드와 함께 번들로 제공해서는 안 됩니다.
+ `APPSYNC_JS` 런타임 환경은 코드가 브라우저 환경에서 실행되지 않는다는 점에서 NodeJS와 유사합니다.
+ 선택적 소스 맵을 포함할 수 있습니다. 그러나 소스 콘텐츠는 포함되지 마세요.

  소스 맵에 대한 자세한 내용은 [소스 맵 사용](#source-maps)을 참조하세요.

예를 들어 `src/appsync/getPost.resolver.js`에 있는 해석기 코드를 번들로 묶으려면 다음 esbuild CLI 명령을 사용하면 됩니다.

```
$ esbuild --bundle \
--sourcemap=inline \
--sources-content=false \
--target=esnext \
--platform=node \
--format=esm \
--external:@aws-appsync/utils \
--outdir=out/appsync \
 src/appsync/getPost.resolver.js
```

## 코드 작성 및 TypeScript로 작업하기
<a name="working-with-typescript"></a>

[TypeScript](https://www.typescriptlang.org/)는 Microsoft에서 개발한 프로그래밍 언어로, TypeScript 타이핑 시스템과 함께 JavaScript의 모든 기능을 제공합니다. TypeScript를 사용하여 type-safe 코드를 작성하고 코드를 AWS AppSync에 저장하기 전에 빌드 시 오류와 버그를 잡을 수 있습니다. `@aws-appsync/utils` 패키지가 완전히 입력되었습니다.

`APPSYNC_JS` 런타임은 TypeScript를 직접 지원하지 않습니다. 코드를 AWS AppSync에 저장하기 전에 먼저 TypeScript 코드를 `APPSYNC_JS` 런타임이 지원하는 JavaScript 코드로 변환해야 합니다. TypeScript를 사용하여 로컬 통합 개발 환경(IDE)에서 코드를 작성할 수 있지만 AWS AppSync 콘솔에서는 TypeScript 코드를 생성할 수 없습니다.

시작하려면 프로젝트에 [TypeScript](https://www.typescriptlang.org/download)가 설치되어 있는지 확인하세요. 그런 다음 [TSConfig](https://www.typescriptlang.org/tsconfig)를 사용하여 `APPSYNC_JS` 런타임에서 작동하도록 TypeScript 트랜스컴파일 설정을 구성합니다. 사용할 수 있는 기본 `tsconfig.json` 파일의 예는 다음과 같습니다.

```
// tsconfig.json
{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
   "noEmit": true,
   "moduleResolution": "node",
  }
}
```

그런 다음 esbuild와 같은 번들링 도구를 사용하여 코드를 컴파일하고 번들링할 수 있습니다. 예를 들어 AWS AppSync 코드가에 있는 프로젝트의 `src/appsync`경우 다음 명령을 사용하여 코드를 컴파일하고 번들링할 수 있습니다.

```
$ esbuild --bundle \
--sourcemap=inline \
--sources-content=false \
--target=esnext \
--platform=node \
--format=esm \
--external:@aws-appsync/utils \
--outdir=out/appsync \
 src/appsync/**/*.ts
```

### Amplify codegen 사용
<a name="working-with-amplify-codegen"></a>

[Amplify CLI](https://docs.amplify.aws/cli/)를 사용하여 스키마의 유형을 생성할 수 있습니다. `schema.graphql` 파일이 있는 디렉터리에서 다음 명령을 실행하고 프롬프트를 검토하여 codegen을 구성합니다.

```
$  npx @aws-amplify/cli codegen add
```

특정 상황(예: 스키마 업데이트 시)에서 codegen을 재생성하려면 다음 명령을 실행합니다.

```
$ npx @aws-amplify/cli codegen
```

그런 다음 생성된 유형을 해석기 코드에 사용할 수 있습니다. 예를 들어 다음과 같은 스키마가 있습니다.

```
type Todo {
  id: ID!
  title: String!
  description: String
}

type Mutation {
  createTodo(title: String!, description: String): Todo
}

type Query {
  listTodos: Todo
}
```

다음 예제 AWS AppSync 함수에서 생성된 유형을 사용할 수 있습니다.

```
import { Context, util } from '@aws-appsync/utils'
import * as ddb from '@aws-appsync/utils/dynamodb'
import { CreateTodoMutationVariables, Todo } from './API' // codegen

export function request(ctx: Context<CreateTodoMutationVariables>) {
	ctx.args.description = ctx.args.description ?? 'created on ' + util.time.nowISO8601()
	return ddb.put<Todo>({ key: { id: util.autoId() }, item: ctx.args })
}

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

### TypeScript에서 제네릭 사용
<a name="working-with-typescript-generics"></a>

제네릭을 제공된 여러 유형과 함께 사용할 수 있습니다. 예를 들어 아래 코드 조각은 `Todo` 유형입니다.

```
export type Todo = {
  __typename: "Todo",
  id: string,
  title: string,
  description?: string | null,
};
```

`Todo`를 사용하는 구독용 해석기를 작성할 수 있습니다. IDE에서 유형 정의 및 자동 완성 힌트는 `toSubscriptionFilter` 변환 유틸리티를 올바르게 사용하는 방법을 안내합니다.

```
import { util, Context, extensions } from '@aws-appsync/utils'
import { Todo } from './API'

export function request(ctx: Context) {
  return {}
}

export function response(ctx: Context) {
  const filter = util.transform.toSubscriptionFilter<Todo>({
    title: { beginsWith: 'hello' },
    description: { contains: 'created' },
  })
  extensions.setSubscriptionFilter(filter)
  return null
}
```

## 번들 린팅
<a name="using-lint-with-bundles"></a>

`esbuild-plugin-eslint` 플러그인을 가져와서 번들을 자동으로 린트할 수 있습니다. 그런 다음 eslint 기능을 활성화하는 `plugins` 값을 제공하여 활성화할 수 있습니다. 아래는 `build.mjs`라는 파일에서 esbuild JavaScript API를 사용하는 코드 조각입니다.

```
/* eslint-disable */
import { build } from 'esbuild'
import eslint from 'esbuild-plugin-eslint'
import glob from 'glob'
const files = await glob('src/**/*.ts')

await build({
  format: 'esm',
  target: 'esnext',
  platform: 'node',
  external: ['@aws-appsync/utils'],
  outdir: 'dist/',
  entryPoints: files,
  bundle: true,
  plugins: [eslint({ useEslintrc: true })],
})
```

## 소스 맵 사용
<a name="source-maps"></a>

JavaScript 코드로 인라인 소스 맵(`sourcemap`)을 제공할 수 있습니다. 소스 맵은 JavaScript 또는 TypeScript 코드를 번들로 제공하고 로그 및 런타임 JavaScript 오류 메시지에서 입력 소스 파일에 대한 참조를 확인하려는 경우에 유용합니다.

`sourcemap`은 코드 끝에 표시되어야 합니다. 이 코드는 다음 형식을 따르는 단일 주석 행으로 정의됩니다.

```
//# sourceMappingURL=data:application/json;base64,<base64 encoded string>
```

다음은 그 예입니다.

```
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsibGliLmpzIiwgImNvZGUuanMiXSwKICAibWFwcGluZ3MiOiAiO0FBQU8sU0FBUyxRQUFRO0FBQ3RCLFNBQU87QUFDVDs7O0FDRE8sU0FBUyxRQUFRLEtBQUs7QUFDM0IsU0FBTyxNQUFNO0FBQ2Y7IiwKICAibmFtZXMiOiBbXQp9Cg==
```

esbuild를 사용하여 소스 맵을 생성할 수 있습니다. 아래 예제는 코드를 빌드하고 번들링할 때 esbuild JavaScript API를 사용하여 인라인 소스 맵을 포함하는 방법을 보여줍니다.

```
/* eslint-disable */
import { build } from 'esbuild'
import eslint from 'esbuild-plugin-eslint'
import glob from 'glob'
const files = await glob('src/**/*.ts')

await build({
  sourcemap: 'inline',
  sourcesContent: false,
  
  format: 'esm',
  target: 'esnext',
  platform: 'node',
  external: ['@aws-appsync/utils'],
  outdir: 'dist/',
  entryPoints: files,
  bundle: true,
  plugins: [eslint({ useEslintrc: true })],
})
```

특히 `sourcemap` 및 `sourcesContent` 옵션은 각 빌드가 끝날 때마다 소스 맵을 줄지어 추가하되 소스 콘텐츠는 포함하지 않도록 지정합니다. 규칙에 따라 소스 콘텐츠는 `sourcemap`에 포함하지 않는 것이 좋습니다. `sources-content`를 `false`로 설정하여 esbuild에서 이를 비활성화할 수 있습니다.

소스 맵의 작동 방식을 설명하려면 해석기 코드가 도우미 라이브러리의 도우미 함수를 참조하는 다음 예제를 검토하세요. 코드에는 해석기 코드와 도우미 라이브러리의 로그 명령문이 포함되어 있습니다.

**./src/default.resolver.ts**(사용자의 해석기)

```
import { Context } from '@aws-appsync/utils'
import { hello, logit } from './helper'

export function request(ctx: Context) {
  console.log('start >')
  logit('hello world', 42, true)
  console.log('< end')
  return 'test'
}

export function response(ctx: Context): boolean {
  hello()
  return ctx.prev.result
}
```

**.src/helper.ts**(도우미 파일)

```
export const logit = (...rest: any[]) => {
  // a special logger
  console.log('[logger]', ...rest.map((r) => `<${r}>`))
}

export const hello = () => {
  // This just returns a simple sentence, but it could do more.
  console.log('i just say hello..')
}
```

해석기 파일을 빌드하고 번들링하면 해석기 코드에 인라인 소스 맵이 포함됩니다. 해석기가 실행되면 CloudWatch 로그에 다음과 같은 항목이 나타납니다.

![\[CloudWatch log entries showing resolver code execution with inline source map information.\]](http://docs.aws.amazon.com/ko_kr/appsync/latest/devguide/images/cloudwatch-sourcemap.jpeg)


CloudWatch 로그의 항목을 살펴보면 두 파일의 기능이 함께 번들로 묶여 동시에 실행되고 있음을 알 수 있습니다. 각 파일의 원본 파일 이름도 로그에 명확하게 반영됩니다.

# 에서 해석기 및 함수 핸들러 테스트 AWS AppSync
<a name="test-resolvers"></a>

코드를 해석기 또는 함수에 저장하기 전에 `EvaluateCode` API 명령을 사용하여 모의 데이터로 해석기 및 함수 핸들러를 원격으로 테스트할 수 있습니다. 명령어를 시작하려면 정책에 `appsync:evaluatecode` 권한을 추가했는지 확인하세요. 예제:

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "appsync:evaluateCode",
            "Resource": "arn:aws:appsync:us-east-1:111122223333:*"
        }
    ]
}
```

------

[AWS CLI](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/index.html) 또는 [AWS SDK](https://aws.amazon.com/tools/)를 사용하여 명령을 활용할 수 있습니다. 예를 들어 CLI를 사용하여 코드를 테스트하려면 파일을 가리키고, 컨텍스트를 제공하고, 평가할 핸들러를 지정하기만 하면 됩니다.

```
aws appsync evaluate-code \
  --code file://code.js \
  --function request \
  --context file://context.json \
  --runtime name=APPSYNC_JS,runtimeVersion=1.0.0
```

응답에는 핸들러가 반환한 페이로드가 포함된 `evaluationResult`가 포함되어 있습니다. 또한 평가 중에 핸들러가 생성한 로그 목록이 들어 있는 `logs` 객체도 포함되어 있습니다. 이렇게 하면 코드 실행을 쉽게 디버깅하고 평가에 대한 정보를 확인하여 문제를 해결하는 데 도움이 됩니다. 예제:

```
{
    "evaluationResult": "{\"operation\":\"PutItem\",\"key\":{\"id\":{\"S\":\"record-id\"}},\"attributeValues\":{\"owner\":{\"S\":\"John doe\"},\"expectedVersion\":{\"N\":2},\"authorId\":{\"S\":\"Sammy Davis\"}}}",
    "logs": [
        "INFO - code.js:5:3: \"current id\" \"record-id\"",
        "INFO - code.js:9:3: \"request evaluated\""
    ]
}
```

평가 결과를 JSON으로 구문 분석하여 다음과 같은 결과를 얻을 수 있습니다.

```
{
  "operation": "PutItem",
  "key": {
    "id": {
      "S": "record-id"
    }
  },
  "attributeValues": {
    "owner": {
      "S": "John doe"
    },
    "expectedVersion": {
      "N": 2
    },
    "authorId": {
      "S": "Sammy Davis"
    }
  }
}
```

SDK를 사용하면 테스트 제품군의 테스트를 쉽게 통합하여 코드 동작을 검증할 수 있습니다. 이 예제에서는 [Jest 테스팅 프레임워크](https://jestjs.io/)를 사용하지만 어떤 테스트 제품군이든 사용할 수 있습니다. 다음 코드 조각은 가상의 검증 실행을 보여줍니다. 평가 응답은 유효한 JSON일 것으로 예상하므로 `JSON.parse`를 사용하여 문자열 응답에서 JSON을 검색합니다.

```
const AWS = require('aws-sdk')
const fs = require('fs')
const client = new AWS.AppSync({ region: 'us-east-2' })
const runtime = {name:'APPSYNC_JS',runtimeVersion:'1.0.0')

test('request correctly calls DynamoDB', async () => {
  const code = fs.readFileSync('./code.js', 'utf8')
  const context = fs.readFileSync('./context.json', 'utf8')
  const contextJSON = JSON.parse(context)
  
  const response = await client.evaluateCode({ code, context, runtime, function: 'request' }).promise()
  const result = JSON.parse(response.evaluationResult)
  
  expect(result.key.id.S).toBeDefined()
  expect(result.attributeValues.firstname.S).toEqual(contextJSON.arguments.firstname)
})
```

이 결과는 다음과 같아야 합니다.

```
Ran all test suites.
> jest

PASS ./index.test.js
✓ request correctly calls DynamoDB (543 ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 totalTime: 1.511 s, estimated 2 s
```

# 에서 VTL에서 JavaScript로 마이그레이션 AWS AppSync
<a name="migrating-resolvers"></a>

AWS AppSync를 사용하면 VTL 또는 JavaScript를 사용하여 해석기 및 함수에 대한 비즈니스 로직을 작성할 수 있습니다. 두 언어를 모두 사용하면 AWS AppSync 서비스에 데이터 소스와 상호 작용하는 방법을 지시하는 로직을 작성할 수 있습니다. VTL을 사용하면 유효한 JSON으로 인코딩된 문자열로 평가되어야 하는 매핑 템플릿을 작성할 수 있습니다. JavaScript를 사용하면 객체를 반환하는 요청 핸들러 및 응답 핸들러를 작성할 수 있습니다. JSON으로 인코딩된 문자열은 반환하지 않습니다.

예를 들어, 다음 VTL 매핑 템플릿을 사용하여 Amazon DynamoDB 항목을 가져옵니다.

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

유틸리티 `$util.dynamodb.toDynamoDBJson`은 JSON으로 인코딩된 문자열을 반환합니다. `$ctx.args.id`가 `<id>`로 설정된 경우 템플릿은 유효한 JSON 인코딩 문자열로 평가됩니다.

```
{
    "operation": "GetItem",
    "key": {
        "id": {"S": "<id>"},
    }
}
```

JavaScript로 작업할 때 코드 내에서 원시 JSON 인코딩 문자열을 인쇄할 필요가 없으며 `toDynamoDBJson`과 같은 유틸리티를 사용할 필요가 없습니다. 위의 매핑 템플릿과 동일한 예제는 다음과 같습니다.

```
import { util } from '@aws-appsync/utils';
export function request(ctx) {
  return {
    operation: 'GetItem',
    key: {id: util.dynamodb.toDynamoDB(ctx.args.id)}
  };
}
```

대안은 값 객체를 처리하는 데 권장되는 접근 방식인 `util.dynamodb.toMapValues`를 사용하는 것입니다.

```
import { util } from '@aws-appsync/utils';
export function request(ctx) {
  return {
    operation: 'GetItem',
    key: util.dynamodb.toMapValues({ id: ctx.args.id }),
  };
}
```

이 결과는 다음과 같이 평가됩니다.

```
{
  "operation": "GetItem",
  "key": {
    "id": {
      "S": "<id>"
    }
  }
}
```

**참고**  
DynamoDB 모듈을 DynamoDB 데이터 소스와 함께 사용하는 것이 좋습니다.  

```
import * as ddb from '@aws-appsync/utils/dynamodb'

export function request(ctx) {
	ddb.get({ key: { id: ctx.args.id } })
}
```

또 다른 예로, 다음 매핑 템플릿을 사용하여 Amazon DynamoDB 데이터 소스에 항목을 입력합니다.

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

평가 시 이 매핑 템플릿 문자열은 유효한 JSON 인코딩 문자열을 생성해야 합니다. JavaScript를 사용하는 경우 코드는 요청 객체를 직접 반환합니다.

```
import { util } from '@aws-appsync/utils';
export function request(ctx) {
  const { id = util.autoId(), ...values } = ctx.args;
  return {
    operation: 'PutItem',
    key: util.dynamodb.toMapValues({ id }),
    attributeValues: util.dynamodb.toMapValues(values),
  };
}
```

이는 다음과 같이 평가됩니다.

```
{
  "operation": "PutItem",
  "key": {
    "id": { "S": "2bff3f05-ff8c-4ed8-92b4-767e29fc4e63" }
  },
  "attributeValues": {
    "firstname": { "S": "Shaggy" },
    "age": { "N": 4 }
  }
}
```

**참고**  
DynamoDB 모듈을 DynamoDB 데이터 소스와 함께 사용하는 것이 좋습니다.  

```
import { util } from '@aws-appsync/utils'
import * as ddb from '@aws-appsync/utils/dynamodb'

export function request(ctx) {
	const { id = util.autoId(), ...item } = ctx.args
	return ddb.put({ key: { id }, item })
}
```

# 직접 데이터 소스 액세스와 Lambda 데이터 소스를 통한 프록시 중 선택
<a name="choosing-data-source"></a>

 AWS AppSync 및 `APPSYNC_JS` 런타임을 사용하면 AWS AppSync 함수를 사용하여 데이터 소스에 액세스하여 사용자 지정 비즈니스 로직을 구현하는 자체 코드를 작성할 수 있습니다. 따라서 추가 컴퓨팅 AWS 서비스 또는 인프라를 배포할 필요 없이 Amazon DynamoDB, Aurora Serverless, OpenSearch Service, HTTP APIs 및 기타 서비스와 같은 데이터 소스와 직접 상호 작용할 수 있습니다. 또한 AWS AppSync를 사용하면 Lambda 데이터 소스를 구성하여 AWS Lambda 함수와 쉽게 상호 작용할 수 있습니다. Lambda 데이터 소스를 사용하면 AWS Lambda의 전체 설정 기능을 사용하여 복잡한 비즈니스 로직을 실행하여 GraphQL 요청을 해결할 수 있습니다. 대부분의 경우 대상 데이터 소스에 직접 연결된 AWS AppSync 함수는 필요한 모든 기능을 제공합니다. `APPSYNC_JS` 런타임에서 지원하지 않는 복잡한 비즈니스 로직을 구현해야 하는 상황에서는 Lambda 데이터 소스를 프록시로 사용하여 대상 데이터 소스와 상호 작용할 수 있습니다.


|  |  |  | 
| --- |--- |--- |
|  | 직접 데이터 소스 통합 | 프록시로서의 Lambda 데이터 소스 | 
| 사용 사례: | AWS AppSync functions interact directly with API data sources. | AWS AppSync functions call Lambdas that interact with API data sources. | 
| Runtime | APPSYNC\$1JS(JavaScript) | 지원되는 Lambda 런타임 | 
| Maximum size of code |  AWS AppSync 함수당 32,000자 | Lambda당 50MB(직접 업로드용 압축 파일) | 
| External modules | 제한적 - APPSYNC\$1JS는 기능만 지원 | 예 | 
| Call any AWS service | 예 - AWS AppSync HTTP 데이터 소스 사용 | 예 - AWS SDK 사용 | 
| Access to the request header | 예 | 예 | 
| Network access | 아니요 | 예 | 
| File system access | 아니요 | 예 | 
| Logging and metrics | 예 | 예 | 
| Build and test entirely within AppSync | 예 | 아니요 | 
| Cold start | 아니요 | 아니요 - 프로비저닝된 동시성 | 
| Auto-scaling | 예 - AWS AppSync에서 투명하게 표시 | 예 - Lambda에서 구성한 대로 | 
| Pricing | 추가 요금 없음 | Lambda 사용에 대한 요금 부과 | 

대상 데이터 소스와 직접 통합되는AWS AppSync 함수는 다음과 같은 사용 사례에 적합합니다.
+  Amazon DynamoDB, Aurora Serverless 및 OpenSearch Service와의 상호 작용
+  HTTP API와의 상호 작용 및 수신 헤더 전달 
+  HTTP 데이터 소스를 사용하여 AWS 서비스와 상호 작용(제공된 데이터 소스 역할로 요청에 AWS AppSync 자동으로 서명) 
+  데이터 소스에 액세스하기 전에 액세스 제어 구현 
+  요청을 이행하기 전에 검색된 데이터에 대한 필터링 구현 
+  해석기 파이프라인에서 AWS AppSync 함수를 순차적으로 실행하여 간단한 오케스트레이션 구현 
+  쿼리와 뮤테이션의 캐싱 및 구독 연결 제어 

Lambda 데이터 소스를 프록시로 사용하는AWS AppSync 함수는 다음과 같은 사용 사례에 적합합니다.
+  JavaScript 또는 Velocity Template Language(VTL) 이외의 언어 사용 
+  CPU 또는 메모리를 조정 및 제어하여 성능 최적화 
+  타사 라이브러리를 가져오거나 `APPSYNC_JS`에서 지원되지 않는 기능을 요구 
+  여러 네트워크 요청 및/또는 쿼리 수행을 위한 파일 시스템 액세스 권한 얻기 
+  [일괄 처리 구성](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-lambda-js.html)을 사용한 요청 일괄 처리.

# AWS AppSync JavaScript 해석기 컨텍스트 객체 참조
<a name="resolver-context-reference-js"></a>

AWS AppSync 는 요청 및 응답 핸들러 작업을 위한 변수 및 함수 집합을 정의합니다. 이렇게 하면 GraphQL을 사용하는 데이터에 대한 논리적 조작이 더 쉬워집니다. 이 문서에서는 이러한 함수를 설명하고 예를 제공합니다.

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

요청 및 응답 핸들러의 `context` 인수는 해석기 간접 호출에 대한 모든 컨텍스트 정보를 포함하는 객체입니다. 이 변수의 구조는 다음과 같습니다.

```
type Context = {
  arguments: any;
  args: any;
  identity: Identity;
  source: any;
  error?: {
    message: string;
    type: string;
  };
  stash: any;
  result: any;
  prev: any;
  request: Request;
  info: Info;
};
```

**참고**  
`context` 객체를 `ctx`라고 부르는 경우가 종종 있습니다.

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

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

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

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

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

** `stash` **  
stash는 각 해석기 및 함수 핸들러 내에서 사용할 수 있는 객체입니다. 단일 해석기가 실행되는 동안에는 동일한 stash 객체가 사용됩니다. 즉, stash를 사용하여 요청 및 응답 핸들러와 파이프라인 해석기의 함수 간에 임의의 데이터를 전달할 수 있습니다.  
전체 stash를 삭제하거나 바꿀 수는 없지만 stash의 속성을 추가, 업데이트, 삭제 및 읽을 수는 있습니다.
아래 코드 예제 중 하나를 수정하여 stash에 항목을 추가할 수 있습니다.  

```
//Example 1
ctx.stash.newItem = { key: "something" }

//Example 2
Object.assign(ctx.stash, {key1: value1, key2: value})
```
아래 코드를 수정하여 stash에서 항목을 제거할 수 있습니다.  

```
delete ctx.stash.key
```

** `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-js)를 참조하십시오.

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

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

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

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

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

```
type AppSyncIdentityLambda = {
  resolverContext: any;
};
```
`identity`에는 요청을 승인하는 Lambda 함수가 반환한 동일한 `resolverContext` 콘텐츠가 포함된 `resolverContext` 키가 포함되어 있습니다.

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

```
type AppSyncIdentityIAM = {
  accountId: string;
  cognitoIdentityPoolId: string;
  cognitoIdentityId: string;
  sourceIp: string[];
  username: string;
  userArn: string;
  cognitoIdentityAuthType: string;
  cognitoIdentityAuthProvider: string;
};
```

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

```
type AppSyncIdentityCognito = {
  sourceIp: string[];
  username: string;
  groups: string[] | null;
  sub: string;
  issuer: string;
  claims: any;
  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-js"></a>

AWS AppSync는 클라이언트에서 사용자 지정 헤더를 전달하고를 사용하여 GraphQL 해석기에서 액세스할 수 있도록 지원합니다`ctx.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
```

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

```
"custom": util.dynamodb.toDynamoDB(ctx.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
```

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

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

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

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

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

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

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

```
type Info = {
  fieldName: string;
  parentTypeName: string;
  variables: any;
  selectionSetList: string[];
  selectionSetGraphQL: string;
};
```

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

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

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

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

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

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

**참고**  
`JSON.stringify`는 문자열 직렬화에 `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
  }
}
```

핸들러를 처리할 때 사용할 수 있는 전체 `ctx.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"
]
```

# 해석기 및 함수를 위한AWS AppSync JavaScript 런타임 기능
<a name="resolver-util-reference-js"></a>

`APPSYNC_JS` 런타임 환경은 [ECMAScript (ES) 버전 6.0](https://262.ecma-international.org/6.0/)과 유사한 기능을 제공합니다. 일부 기능을 지원하며 ES 사양의 일부가 아닌 몇 가지 추가 메서드(유틸리티)를 제공합니다. 다음 항목에는 지원되는 모든 언어 기능이 나열되어 있습니다.
+  [ 지원되는 런타임 기능 ](https://docs.aws.amazon.com/appsync/latest/devguide/supported-features.html) - 지원되는 핵심 기능, 기본 객체, 기본 제공 객체 및 함수 등을 자세히 알아봅니다.
+  [ 기본 제공 유틸리티 ](https://docs.aws.amazon.com/appsync/latest/devguide/built-in-util-js.html) - util 변수에는 데이터 작업에 도움이 되는 일반 유틸리티 메서드가 포함되어 있습니다. 달리 지정하지 않는 한, 모든 유틸리티는 UTF-8 문자 집합을 사용합니다.
+  [ 기본 제공 모듈 ](https://docs.aws.amazon.com/appsync/latest/devguide/built-in-modules-js.html) - 기본 제공 모듈이 JavaScript 해석기 및 함수를 작성하는 데 어떻게 도움이 되는지 자세히 알아봅니다.
+  [ 런타임 유틸리티 ](https://docs.aws.amazon.com/appsync/latest/devguide/runtime-utils-js.html) - 런타임 라이브러리는 해석기 및 함수의 런타임 속성을 제어하거나 수정하는 유틸리티를 제공합니다.
+  [ util.time의 시간 도우미 ](https://docs.aws.amazon.com/appsync/latest/devguide/time-helpers-in-util-time-js.html) - util.time 변수에는 타임스탬프를 생성하고, 날짜 및 시간 형식 간에 변환하고, 날짜 및 시간 문자열을 구문 분석하는 데 도움이 되는 날짜 및 시간 메서드가 포함되어 있습니다. 날짜 및 시간 형식 구문은 [DateTimeFormatter](https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html)를 기반으로 하며, 여기서 자세한 설명을 참조할 수 있습니다.
+  [ util.dynamodb의 DynamoDB 도우미 ](https://docs.aws.amazon.com/appsync/latest/devguide/dynamodb-helpers-in-util-dynamodb-js.html) - util.dynamodb에는 Amazon DynamoDB에 데이터 쓰기 및 읽기를 더 용이하게 하는 도우미 메서드가 포함되어 있습니다(예: 자동 유형 매핑 및 형식 지정).
+  [ util.http의 HTTP 도우미 ](https://docs.aws.amazon.com/appsync/latest/devguide/http-helpers-in-utils-http-js.html) - util.http 유틸리티는 HTTP 요청 파라미터를 관리하고 응답 헤더를 추가하는 데 사용할 수 있는 도우미 메서드를 제공합니다.
+  [ util.transform - util.transform의 변환 도우미](https://docs.aws.amazon.com/appsync/latest/devguide/transformation-helpers-in-utils-transform-js.html) - util.transform에는 데이터 소스에 대해 복잡한 작업을 더 쉽게 수행할 수 있는 도우미 메서드가 포함되어 있습니다.
+  [ util.str의 문자열 도우미](https://docs.aws.amazon.com/appsync/latest/devguide/str-helpers-in-util-str-js.html) - util.str에는 일반적인 문자열 작업에 도움이 되는 메서드가 포함되어 있습니다.
+  [ 확장 ](https://docs.aws.amazon.com/appsync/latest/devguide/extensions-js.html) - 확장에는 해석기 내에서 추가 작업을 수행할 수 있는 일련의 메서드가 있습니다.
+  [ util.xml - util.xml의 XML 도우미](https://docs.aws.amazon.com/appsync/latest/devguide/xml-helpers-in-util-xml-js.html) - util.xml에는 XML 문자열 변환에 도움이 되는 메서드가 포함되어 있습니다.

**참고**  
현재 이 참조는 런타임 버전 **1.0.0**에만 적용됩니다.

# 지원되는 런타임 기능
<a name="supported-features"></a>

아래 섹션에서는 APPSYNC\$1JS 런타임의 지원되는 기능 세트를 설명합니다.

## 핵심 기능
<a name="core-features"></a>

다음 핵심 기능이 지원됩니다.

------
#### [ Types ]

지원되는 유형은 다음과 같습니다.
+ 번호
+ 문자열
+ 부울
+ 객체
+ 배열
+ 함수

------
#### [ Operators ]

다음을 포함한 연산자가 지원됩니다.
+ 표준 수학 연산자(`+`, `-`, `/`, `%`, `*` 등)
+ nullish 병합 연산자(`??`)
+ 선택적 체인(`?.`)
+ bitwise 연산자
+ `void` 및 `typeof` 연산자
+ 분산 연산자(`...`)

다음 연산자는 지원되지 않습니다.
+ 단항 연산자(`++`, `--` 및 `~`)
+ `in` 연산자
**참고**  
`Object.hasOwn` 연산자를 사용하여 지정된 속성이 지정된 객체에 있는지 확인합니다.

------
#### [ Statements ]

다음 명령문이 지원됩니다.
+ `const`
+ `let`
+ `var`
+ `break`
+ `else`
+ `for-in`
+ `for-of` 
+ `if`
+ `return`
+ `switch`
+ 스프레드 구문

다음은 지원하지 않습니다.
+ `catch`
+ `continue`
+ `do-while`
+ `finally`
+ `for(initialization; condition; afterthought)`
**참고**  
지원되는 예외는 `for-in` 및 `for-of` 표현식입니다.
+ `throw`
+ `try`
+ `while`
+ 레이블이 지정된 명령문

------
#### [ Literals ]

다음 ES 6 [템플릿 리터럴](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals)이 지원됩니다.
+ 여러 줄 문자열
+ 표현식 보간
+ 매핑 템플릿

------
#### [ Functions ]

다음 함수 구문이 지원됩니다.
+ 함수 선언이 지원됩니다.
+ ES 6 화살표 함수가 지원됩니다.
+ ES 6 rest 파라미터 구문이 지원됩니다.

------
#### [ Strict mode ]

함수는 기본적으로 엄격 모드에서 작동하므로 함수 코드에 `use_strict` 명령문을 추가할 필요가 없습니다. 이것은 변경할 수 없습니다.

------

## 기본 객체
<a name="primitive-objects"></a>

다음의 ES 기본 객체와 해당 기능이 지원됩니다.

------
#### [ Object ]

다음 객체가 지원됩니다.
+ `Object.assign()`
+ `Object.entries()` 
+ `Object.hasOwn()`
+ `Object.keys()` 
+ `Object.values()`
+ `delete` 

------
#### [ String ]

다음 문자열이 지원됩니다.
+  `String.prototype.length()` 
+  `String.prototype.charAt()` 
+  `String.prototype.concat()` 
+  `String.prototype.endsWith()` 
+  `String.prototype.indexOf()` 
+  `String.prototype.lastIndexOf()` 
+  `String.raw()` 
+  `String.prototype.replace()`
**참고**  
정규 표현식은 지원되지 않습니다.  
그러나 Java 스타일 정규식 구문은 제공된 파라미터에서 지원됩니다. 자세한 내용은 [패턴](https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html)을 참조하세요.
+ `String.prototype.replaceAll()`
**참고**  
정규 표현식은 지원되지 않습니다.  
그러나 Java 스타일 정규식 구문은 제공된 파라미터에서 지원됩니다. 자세한 내용은 [패턴](https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html)을 참조하세요.
+  `String.prototype.slice()` 
+  `String.prototype.split()` 
+  `String.prototype.startsWith()` 
+  `String.prototype.toLowerCase()` 
+  `String.prototype.toUpperCase()` 
+  `String.prototype.trim()` 
+  `String.prototype.trimEnd()` 
+  `String.prototype.trimStart()` 

------
#### [ Number ]

다음 번호가 지원됩니다.
+  `Number.isFinite` 
+  `Number.isNaN` 

------

## 기본 제공 객체 및 함수
<a name="built-in-objects-functions"></a>

다음 객체 및 함수가 지원됩니다.

------
#### [ Math ]

다음 수학 연산 함수가 지원됩니다.
+  `Math.random()` 
+  `Math.min()` 
+  `Math.max()` 
+  `Math.round()` 
+  `Math.floor()` 
+  `Math.ceil()` 

------
#### [ Array ]

다음 배열 메서드가 지원됩니다.
+ `Array.prototype.length` 
+ `Array.prototype.concat()` 
+ `Array.prototype.fill()` 
+ `Array.prototype.flat()` 
+ `Array.prototype.indexOf()` 
+ `Array.prototype.join()` 
+ `Array.prototype.lastIndexOf()` 
+ `Array.prototype.pop()` 
+ `Array.prototype.push()` 
+ `Array.prototype.reverse()` 
+ `Array.prototype.shift()` 
+ `Array.prototype.slice()` 
+ `Array.prototype.sort()`
**참고**  
`Array.prototype.sort()`는 인수를 지원하지 않습니다.
+ `Array.prototype.splice()` 
+ `Array.prototype.unshift()`
+ `Array.prototype.forEach()`
+ `Array.prototype.map()`
+ `Array.prototype.flatMap()`
+ `Array.prototype.filter()`
+ `Array.prototype.reduce()`
+ `Array.prototype.reduceRight()`
+ `Array.prototype.find()`
+ `Array.prototype.some()`
+ `Array.prototype.every()`
+ `Array.prototype.findIndex()`
+ `Array.prototype.findLast()`
+ `Array.prototype.findLastIndex()`
+ `delete` 

------
#### [ Console ]

콘솔 객체를 디버깅에 사용할 수 있습니다. 라이브 쿼리 실행 중에 콘솔 로그/오류 명령문이 Amazon CloudWatch Logs로 전송됩니다(로깅이 활성화된 경우). `evaluateCode`를 사용하여 코드를 평가하는 동안 명령 응답으로 로그 명령문이 반환됩니다.
+ `console.error()`
+ `console.log()`

------
#### [ Function ]
+ `apply`, `bind` 및 `call` 메서드는 지원되지 않습니다.
+ 함수 생성자는 지원되지 않습니다.
+ 함수를 인수로 전달하는 것은 지원되지 않습니다.
+ 재귀 함수 호출은 지원되지 않습니다.

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

다음 JSON 메서드가 지원됩니다.
+ `JSON.parse()`
**참고**  
구문 분석된 문자열이 유효한 JSON이 아닌 경우 빈 문자열을 반환합니다.
+ `JSON.stringify()`

------
#### [ Promises ]

비동기식 프로세스 및 약속은 지원되지 않습니다.

**참고**  
네트워크 및 파일 시스템 액세스는 `APPSYNC_JS` in AWS AppSync.의 런타임 내에서 지원되지 않습니다.는 AWS AppSync 해석기 또는 AWS AppSync 함수의 요청에 따라 모든 I/O 작업을 AWS AppSync 처리합니다.

------

## Globals
<a name="globals"></a>

다음과 같은 글로벌 제약이 지원됩니다.
+  `NaN` 
+  `Infinity` 
+  `undefined`
+ [https://docs.aws.amazon.com/appsync/latest/devguide/built-in-util-js.html](https://docs.aws.amazon.com/appsync/latest/devguide/built-in-util-js.html)
+ [https://docs.aws.amazon.com/appsync/latest/devguide/extensions-js.html](https://docs.aws.amazon.com/appsync/latest/devguide/extensions-js.html)
+ `runtime`

## 오류 유형
<a name="error-types"></a>

`throw`를 사용한 오류 발생은 지원되지 않습니다. `util.error()` 함수를 사용하여 오류를 반환할 수 있습니다. `util.appendError` 함수를 사용하여 GraphQL 응답에 오류를 포함할 수 있습니다.

자세한 내용은 [오류 유틸리티](https://docs.aws.amazon.com/appsync/latest/devguide/built-in-util-js.html#utility-helpers-in-error-js)를 참조하세요.

# 기본 제공 유틸리티
<a name="built-in-util-js"></a>

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

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

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

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

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

**`util.base64Encode(string) : string`**  
입력을 base64 인코딩 문자열로 인코딩합니다.

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

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

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

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

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

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

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

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

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

 **`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-patterns-js"></a>

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

**`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()`**   
요청에 사용되는 다중 인증 유형을 설명하는 문자열을 반환하고 'IAM 권한 부여', '사용자 풀 권한 부여', 'Open ID Connect 권한 부여' 또는 'API 키 인증'을 반환합니다.

## 반환 값 동작 유틸리티
<a name="utility-helpers-in-cloudwatch-logs-list-js"></a>

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

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

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

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

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

# 기본 제공 모듈
<a name="built-in-modules-js"></a>

모듈은 `APPSYNC_JS` 런타임의 일부이며 JavaScript 해석기 및 함수를 작성하는 데 도움이 되는 유틸리티를 제공합니다. 샘플 및 예제는 [aws-appsync-resolver-samples](https://github.com/aws-samples/aws-appsync-resolver-samples) GitHub 리포지토리를 참조하세요.

## DynamoDB 모듈 함수
<a name="built-in-ddb-modules"></a>

DynamoDB 모듈 함수는 DynamoDB 데이터 소스와 상호 작용할 때 향상된 경험을 제공합니다. 함수를 사용하고 형식 매핑을 추가하지 않고도 DynamoDB 데이터 소스에 요청을 보낼 수 있습니다.

모듈은 `@aws-appsync/utils/dynamodb`를 사용하여 가져옵니다.

```
// Modules are imported using @aws-appsync/utils/dynamodb
import * as ddb from '@aws-appsync/utils/dynamodb';
```

### 함수
<a name="built-in-ddb-modules-functions"></a>

#### 함수 목록
<a name="built-in-ddb-modules-functions-list"></a>

 **` get<T>(payload: GetInput): DynamoDBGetItemRequest`**  
GetInput에 대한 자세한 내용은 [입력](#built-in-ddb-modules-inputs)를 참조하세요.
`DynamoDBGetItemRequest` 객체를 생성하여 DynamoDB에 [GetItem](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-getitem) 요청을 보냅니다.  

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

export function request(ctx) {
	return get({ key: { id: ctx.args.id } });
}
```

 **`put<T>(payload): DynamoDBPutItemRequest`**  
`DynamoDBPutItemRequest` 객체를 생성하여 DynamoDB에 [PutItem](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-putitem) 요청을 보냅니다.  

```
import * as ddb from '@aws-appsync/utils/dynamodb'

export function request(ctx) {
	return ddb.put({ key: { id: util.autoId() }, item: ctx.args });
}
```

**`remove<T>(payload): DynamoDBDeleteItemRequest`**  
`DynamoDBDeleteItemRequest` 객체를 생성하여 DynamoDB에 [DeleteItem](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-deleteitem) 요청을 보냅니다.  

```
import * as ddb from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
	return ddb.remove({ key: { id: ctx.args.id } });
}
```

**`scan<T>(payload): DynamoDBScanRequest`**  
`DynamoDBScanRequest`를 생성하여 DynamoDB에 [Scan](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-scan) 요청을 보냅니다.  

```
import * as ddb from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
	const { limit = 10, nextToken } = ctx.args;
	return ddb.scan({ limit, nextToken });
}
```

**`sync<T>(payload): DynamoDBSyncRequest`**  
`DynamoDBSyncRequest` 객체를 생성하여 [Sync](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-sync) 요청을 보냅니다. 요청은 마지막 쿼리(델타 업데이트) 이후 변경된 데이터만 수신합니다. 버전이 지정된 DynamoDB 데이터 소스에만 요청할 수 있습니다.  

```
import * as ddb from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
	const { limit = 10, nextToken, lastSync } = ctx.args;
	return ddb.sync({ limit, nextToken, lastSync });
}
```

**`update<T>(payload): DynamoDBUpdateItemRequest`**  
`DynamoDBUpdateItemRequest` 객체를 생성하여 DynamoDB에 [UpdateItem](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-updateitem) 요청을 보냅니다.

### 운영
<a name="built-in-ddb-modules-operations"></a>

작업 도우미를 사용하면 업데이트 중에 일부 데이터의 특정 조치를 취할 수 있습니다. 시작하려면 `@aws-appsync/utils/dynamodb`에서 `operations`를 가져옵니다.

```
// Modules are imported using operations
import {operations} from '@aws-appsync/utils/dynamodb';
```

#### 작업 목록
<a name="built-in-ddb-modules-operations-list"></a>

 **`add<T>(payload)`**  
DynamoDB를 업데이트할 때 새 속성 항목을 추가하는 도우미 함수입니다.  
**예제**  
ID 값을 사용하여 기존 DynamoDB 항목에 주소(도로명, 구/군/시, 우편번호)를 추가하려면:  

```
import { update, operations } from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
	const updateObj = {
		address: operations.add({
			street1: '123 Main St',
			city: 'New York',
			zip: '10001',
		}),
	};
	return update({ key: { id: 1 }, update: updateObj });
}
```

**`append <T>(payload)`**  
DynamoDB의 기존 목록에 페이로드를 추가하는 도우미 함수입니다.  
**예제**  
업데이트 중에 새로 추가된 친구 ID(`newFriendIds`)를 기존 친구 목록(`friendsIds`)에 추가하려면:  

```
import { update, operations } from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
	const newFriendIds = [101, 104, 111];
	const updateObj = {
		friendsIds: operations.append(newFriendIds),
	};
	return update({ key: { id: 1 }, update: updateObj });
}
```

**`decrement (by?)`**  
DynamoDB를 업데이트할 때 항목의 기존 속성 값을 감소시키는 도우미 함수입니다.  
**예제**  
친구 카운터(`friendsCount`)를 10씩 줄이려면:  

```
import { update, operations } from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
	const updateObj = {
		friendsCount: operations.decrement(10),
	};
	return update({ key: { id: 1 }, update: updateObj });
}
```

**`increment (by?)`**  
DynamoDB를 업데이트할 때 항목의 기존 속성 값을 증가시키는 도우미 함수입니다.  
**예제**  
친구 카운터(`friendsCount`)를 10씩 늘리려면:  

```
import { update, operations } from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
	const updateObj = {
		friendsCount: operations.increment(10),
	};
	return update({ key: { id: 1 }, update: updateObj });
}
```

**`prepend <T>(payload)`**  
DynamoDB의 기존 목록 앞에 추가되는 도우미 함수입니다.  
**예제**  
업데이트 중에 새로 추가된 친구 ID(`newFriendIds`)를 기존 친구 목록(`friendsIds`)에 추가하려면:  

```
import { update, operations } from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
	const newFriendIds = [101, 104, 111];
	const updateObj = {
		friendsIds: operations.prepend(newFriendIds),
	};
	return update({ key: { id: 1 }, update: updateObj });
}
```

**`replace <T>(payload)`**  
DynamoDB에서 항목을 업데이트할 때 기존 속성을 대체하는 도우미 함수입니다. 이는 페이로드의 키뿐만 아니라 속성의 전체 객체 또는 하위 객체를 업데이트하려는 경우에 유용합니다.  
**예제**  
객체의 주소(도로명, 구/군/시, 우편번호)를 바꾸려면 다음을 수행하세요.  

```
import { update, operations } from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
	const updateObj = {
		info: {
			address: operations.replace({
				street1: '123 Main St',
				city: 'New York',
				zip: '10001',
			}),
		},
	};
	return update({ key: { id: 1 }, update: updateObj });
}
```

**`updateListItem <T>(payload, index)`**  
목록의 항목을 대체하는 도우미 함수입니다.  
**예제**  
업데이트(`newFriendIds`) 범위에서, 이 예에서는 `updateListItem`을 사용하여 목록(`friendsIds`)에 있는 두 번째 항목(인덱스: `1`, 새 ID: `102`)과 세 번째 항목(인덱스: `2`, 새 ID: `112`)의 ID 값을 업데이트했습니다.  

```
import { update, operations as ops } from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
	const newFriendIds = [
		ops.updateListItem('102', 1), ops.updateListItem('112', 2)
	];
	const updateObj = { friendsIds: newFriendIds };
	return update({ key: { id: 1 }, update: updateObj });
}
```

### 입력
<a name="built-in-ddb-modules-inputs"></a>

#### 입력 목록
<a name="built-in-ddb-modules-inputs-list"></a>

 **`Type GetInput<T>`**  

```
GetInput<T>: { 
    consistentRead?: boolean; 
    key: DynamoDBKey<T>; 
}
```
**유형 선언**  
+ `consistentRead?: boolean` (선택 사항)

  DynamoDB를 사용하여 강력히 일관된 읽기를 수행할지 여부를 지정하는 선택적 부울입니다.
+ `key: DynamoDBKey<T>`(필수)

  DynamoDB에서 항목의 키를 지정하는 필수 파라미터입니다. DynamoDB 항목은 단일 해시 키 또는 해시 및 정렬 키를 가질 수 있습니다.

**`Type PutInput<T>`**  

```
PutInput<T>: { 
    _version?: number; 
    condition?: DynamoDBFilterObject<T> | null; 
    customPartitionKey?: string; 
    item: Partial<T>; 
    key: DynamoDBKey<T>; 
    populateIndexFields?: boolean; 
}
```
**유형 선언**  
+ `_version?: number` (선택 사항)
+ `condition?: DynamoDBFilterObject<T> | null` (선택 사항)

  DynamoDB 테이블에 객체를 넣을 때 작업이 수행되기 전에 이미 DynamoDB에 있는 객체의 상태를 기반으로 요청의 성공 여부를 제어하는 조건 표현식을 선택적으로 지정할 수 있습니다.
+ `customPartitionKey?: string` (선택 사항)

  활성화되면 이 문자열 값은 버전 관리가 활성화되었을 때 델타 동기화 테이블에서 사용되는 `ds_sk` 및 `ds_pk` 레코드의 형식을 수정합니다. 활성화되면 `populateIndexFields` 항목 처리도 활성화됩니다.
+ `item: Partial<T>`(필수)

  DynamoDB에 배치할 항목의 나머지 속성입니다.
+ `key: DynamoDBKey<T>`(필수)

  입력이 수행되는 DynamoDB에서 항목의 키를 지정하는 필수 파라미터입니다. DynamoDB 항목은 단일 해시 키 또는 해시 및 정렬 키를 가질 수 있습니다.
+ `populateIndexFields?: boolean` (선택 사항)

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

**`Type QueryInput<T>`**  

```
QueryInput<T>: ScanInput<T> & { 
    query: DynamoDBKeyCondition<Required<T>>; 
}
```
**유형 선언**  
+ `query: DynamoDBKeyCondition<Required<T>>`(필수)

  쿼리할 항목을 설명하는 키 조건을 지정합니다. 지정된 인덱스의 경우 파티션 키의 조건은 동등이어야 하고 정렬 키는 비교 또는 `beginsWith`(문자열인 경우)여야 합니다. 파티션 및 정렬 키에는 숫자 및 문자열 유형만 지원됩니다.

  **예제**

  아래 `User` 유형을 선택하세요.

  ```
  type User = {
    id: string;
    name: string;
    age: number;
    isVerified: boolean;
    friendsIds: string[] 
  }
  ```

  쿼리에는 `id`, `name` 및 `age` 필드만 포함될 수 있습니다.

  ```
  const query: QueryInput<User> = {
      name: { eq: 'John' },
      age: { gt: 20 },
  }
  ```

**`Type RemoveInput<T>`**  

```
RemoveInput<T>: { 
    _version?: number; 
    condition?: DynamoDBFilterObject<T>; 
    customPartitionKey?: string; 
    key: DynamoDBKey<T>; 
    populateIndexFields?: boolean; 
}
```
**유형 선언**  
+ `_version?: number` (선택 사항)
+ `condition?: DynamoDBFilterObject<T>` (선택 사항)

  DynamoDB에서 객체를 제거할 때 작업이 수행되기 전에 이미 DynamoDB에 있는 객체의 상태를 기반으로 요청의 성공 여부를 제어하는 조건 표현식을 선택적으로 지정할 수 있습니다.

  **예제**

  다음 예는 문서의 소유자가 요청한 사용자와 일치하는 경우에만 작업이 성공하도록 허용하는 조건이 포함된 `DeleteItem` 표현식입니다.

  ```
  type Task = {
    id: string;
    title: string;
    description: string;
    owner: string;
    isComplete: boolean;
  }
  const condition: DynamoDBFilterObject<Task> = {
    owner: { eq: 'XXXXXXXXXXXXXXXX' },
  }
  
  remove<Task>({
     key: {
       id: 'XXXXXXXXXXXXXXXX',
    },
    condition,
  });
  ```
+ `customPartitionKey?: string` (선택 사항)

  활성화되면 `customPartitionKey` 값은 버전 관리가 활성화되었을 때 델타 동기화 테이블에서 사용되는 `ds_sk` 및 `ds_pk` 레코드의 형식을 수정합니다. 활성화되면 `populateIndexFields` 항목 처리도 활성화됩니다.
+ `key: DynamoDBKey<T>`(필수)

  제거되는 DynamoDB에서 항목의 키를 지정하는 필수 파라미터입니다. DynamoDB 항목은 단일 해시 키 또는 해시 및 정렬 키를 가질 수 있습니다.

  **예제**

  `User`에 사용자 `id`의 해시 키만 있는 경우 키는 다음과 같습니다.

  ```
  type User = {
  	id: number
  	name: string
  	age: number
  	isVerified: boolean
  }
  const key: DynamoDBKey<User> = {
  	id: 1,
  }
  ```

  테이블 사용자에게 해시 키(`id`)와 정렬 키(`name`)가 있는 경우 키는 다음과 같습니다.

  ```
  type User = {
  	id: number
  	name: string
  	age: number
  	isVerified: boolean
  	friendsIds: string[]
  }
  
  const key: DynamoDBKey<User> = {
  	id: 1,
  	name: 'XXXXXXXXXX',
  }
  ```
+ `populateIndexFields?: boolean` (선택 사항)

  `customPartitionKey`와 함께 활성화되면 델타 동기화 테이블, 특히 `gsi_ds_pk` 및 `gsi_ds_sk` 열의 각 레코드에 대해 새 항목을 생성하는 부울 값입니다.

**`Type ScanInput<T>`**  

```
ScanInput<T>: { 
    consistentRead?: boolean | null; 
    filter?: DynamoDBFilterObject<T> | null; 
    index?: string | null; 
    limit?: number | null; 
    nextToken?: string | null; 
    scanIndexForward?: boolean | null; 
    segment?: number; 
    select?: DynamoDBSelectAttributes; 
    totalSegments?: number; 
}
```
**유형 선언**  
+ `consistentRead?: boolean | null` (선택 사항)

  DynamoDB를 쿼리할 때 일관된 읽기를 나타내는 선택적 부울입니다. 기본값은 `false`입니다.
+ `filter?: DynamoDBFilterObject<T> | null` (선택 사항)

  테이블에서 결과를 검색한 후 결과에 적용할 선택적 필터입니다.
+ `index?: string | null` (선택 사항)

  스캔할 인덱스의 선택적 이름입니다.
+ `limit?: number | null` (선택 사항)

  반환할 선택적 최대 결과 수입니다.
+ `nextToken?: string | null` (선택 사항)

  이전 쿼리를 지속하는 선택적 페이지 매김 토큰입니다. 이 토큰은 이전 쿼리에서 얻습니다.
+ `scanIndexForward?: boolean | null` (선택 사항)

  쿼리가 오름차순 또는 내림차순으로 수행되는지 여부를 나타내는 선택적 부울입니다. 기본적으로 이 값은 `true`로 설정됩니다.
+ `segment?: number` (선택 사항)
+ `select?: DynamoDBSelectAttributes` (선택 사항)

  DynamoDB에서 반환할 속성입니다. 기본적으로 AWS AppSync DynamoDB 해석기는 인덱스로 프로젝션된 속성만 반환합니다. 지원되는 값은 다음과 같습니다.
  + `ALL_ATTRIBUTES`

    지정한 테이블 또는 인덱스에서 항목 속성을 모두 반환합니다. 로컬 보조 인덱스를 쿼리하는 경우 DynamoDB는 인덱스의 일치하는 각 항목에 대해 상위 테이블의 전체 항목을 가져옵니다. 인덱스가 모든 항목 속성을 프로젝션하도록 구성된 경우, 모든 데이터를 로컬의 보조 인덱스에서 얻을 수 있기 때문에 가져올 필요가 없습니다.
  + `ALL_PROJECTED_ATTRIBUTES`

    인덱스로 프로젝션된 모든 속성을 반환합니다. 모든 속성을 프로젝션하도록 인덱스가 구성된 경우 이 반환 값은 `ALL_ATTRIBUTES`를 지정하는 것과 동일합니다.
  + `SPECIFIC_ATTRIBUTES`

    `ProjectionExpression`에 나열된 속성만 반환합니다. 이 반환 값은 `AttributesToGet`에 대한 값을 지정하지 않고 `ProjectionExpression`을 지정하는 것과 같습니다.
+ `totalSegments?: number` (선택 사항)

**`Type DynamoDBSyncInput<T>`**  

```
DynamoDBSyncInput<T>: { 
    basePartitionKey?: string; 
    deltaIndexName?: string; 
    filter?: DynamoDBFilterObject<T> | null; 
    lastSync?: number; 
    limit?: number | null; 
    nextToken?: string | null; 
}
```
**유형 선언**  
+ `basePartitionKey?: string` (선택 사항)

  동기화 작업을 수행할 때 사용되는 기본 테이블의 파티션 키입니다. 이 필드를 사용하면 테이블에서 사용자 지정 파티션 키를 활용할 때 동기화 작업을 수행할 수 있습니다.
+ `deltaIndexName?: string` (선택 사항)

  동기화 작업에 사용되는 인덱스입니다. 이 인덱스는 테이블에서 사용자 지정 파티션 키를 사용할 때 전체 델타 저장소 테이블에서 동기화 작업을 활성화하는 데 필요합니다. 동기화 작업은 GSI(`gsi_ds_pk` 및 `gsi_ds_sk`에서 생성)에서 수행됩니다.
+ `filter?: DynamoDBFilterObject<T> | null` (선택 사항)

  테이블에서 결과를 검색한 후 결과에 적용할 선택적 필터입니다.
+ `lastSync?: number` (선택 사항)

  마지막으로 성공한 동기화 작업이 시작되었던 시간(epoch 밀리초)입니다. 지정된 경우, `lastSync` 이후에 변경된 항목만 반환됩니다. 이 필드는 초기 동기화 작업에서 모든 페이지를 가져온 이후에만 채워져야 합니다. 생략하면 기본 테이블의 결과가 반환됩니다. 그렇지 않으면 델타 테이블의 결과가 반환됩니다.
+ `limit?: number | null` (선택 사항)

  한 번에 평가올 수 있는 선택적인 최대 항목 수입니다. 생략된 경우, 기본 제한이 `100`개 항목으로 설정됩니다. 이 필드의 최대값은 `1000`개 항목입니다.
+ `nextToken?: string | null` (선택 사항)

**`Type DynamoDBUpdateInput<T>`**  

```
DynamoDBUpdateInput<T>: { 
    _version?: number; 
    condition?: DynamoDBFilterObject<T>; 
    customPartitionKey?: string; 
    key: DynamoDBKey<T>; 
    populateIndexFields?: boolean; 
    update: DynamoDBUpdateObject<T>; 
}
```
**유형 선언**  
+ `_version?: number` (선택 사항)
+ `condition?: DynamoDBFilterObject<T>` (선택 사항)

  DynamoDB에서 객체를 업데이트할 때 작업이 수행되기 전에 이미 DynamoDB에 있는 객체의 상태를 기반으로 요청의 성공 여부를 제어하는 조건 표현식을 선택적으로 지정할 수 있습니다.
+ `customPartitionKey?: string` (선택 사항)

  활성화되면 `customPartitionKey` 값은 버전 관리가 활성화되었을 때 델타 동기화 테이블에서 사용되는 `ds_sk` 및 `ds_pk` 레코드의 형식을 수정합니다. 활성화되면 `populateIndexFields` 항목 처리도 활성화됩니다.
+ `key: DynamoDBKey<T>`(필수)

  업데이트되는 DynamoDB에서 항목의 키를 지정하는 필수 파라미터입니다. DynamoDB 항목은 단일 해시 키 또는 해시 및 정렬 키를 가질 수 있습니다.
+ `populateIndexFields?: boolean` (선택 사항)

  `customPartitionKey`와 함께 활성화되면 델타 동기화 테이블, 특히 `gsi_ds_pk` 및 `gsi_ds_sk` 열의 각 레코드에 대해 새 항목을 생성하는 부울 값입니다.
+ `update: DynamoDBUpdateObject<T>`

  업데이트될 속성과 해당 속성에 대한 새 값을 지정하는 객체입니다. 업데이트 객체는 `add`, `remove`, `replace`, `increment`, `decrement`, `append`, `prepend`, `updateListItem`와 함께 사용할 수 있습니다.

## Amazon RDS 모듈 함수
<a name="built-in-rds-modules"></a>

Amazon RDS 모듈 함수는 Amazon RDS 데이터 API로 구성된 데이터베이스와 상호 작용할 때 향상된 경험을 제공합니다. 모듈은 `@aws-appsync/utils/rds`를 사용하여 가져옵니다.

```
import * as rds from '@aws-appsync/utils/rds';
```

함수를 개별적으로 가져올 수도 있습니다. 예를 들어 아래 가져오기는 `sql`을 사용합니다.

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

### 함수
<a name="built-in-rds-modules-functions"></a>

 AWS AppSync RDS 모듈의 유틸리티 헬퍼를 사용하여 데이터베이스와 상호 작용할 수 있습니다.

#### Select
<a name="built-in-rds-modules-functions-select"></a>

`select` 유틸리티는 관계형 데이터베이스를 쿼리하기 위한 `SELECT` 문을 생성합니다.

**기본 사용**

기본 형식에서 쿼리하려는 테이블을 지정할 수 있습니다.

```
import { select, createPgStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {

    // Generates statement: 
    // "SELECT * FROM "persons"
    return createPgStatement(select({table: 'persons'}));
}
```

테이블 식별자에 스키마를 지정할 수도 있습니다.

```
import { select, createPgStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {

    // Generates statement:
    // SELECT * FROM "private"."persons"
    return createPgStatement(select({table: 'private.persons'}));
}
```

**열 지정**

`columns` 속성을 사용하여 열을 지정할 수 있습니다. 값으로 설정되지 않은 경우 기본값은 `*`입니다.

```
export function request(ctx) {

    // Generates statement:
    // SELECT "id", "name"
    // FROM "persons"
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name']
    }));
}
```

열 테이블도 지정할 수 있습니다.

```
export function request(ctx) {

    // Generates statement: 
    // SELECT "id", "persons"."name"
    // FROM "persons"
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'persons.name']
    }));
}
```

**제한 및 오프셋**

쿼리에 `limit` 및 `offset`을 적용할 수 있습니다.

```
export function request(ctx) {

    // Generates statement: 
    // SELECT "id", "name"
    // FROM "persons"
    // LIMIT :limit
    // OFFSET :offset
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name'],
        limit: 10,
        offset: 40
    }));
}
```

**순서 기준**

`orderBy` 속성을 기준으로 결과를 정렬할 수 있습니다. 열을 지정하는 객체 배열과 선택적 `dir` 속성을 제공하십시오.

```
export function request(ctx) {

    // Generates statement: 
    // SELECT "id", "name" FROM "persons"
    // ORDER BY "name", "id" DESC
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name'],
        orderBy: [{column: 'name'}, {column: 'id', dir: 'DESC'}]
    }));
}
```

**필터**

특수 조건 객체를 사용하여 필터를 구축할 수 있습니다.

```
export function request(ctx) {

    // Generates statement:
    // SELECT "id", "name"
    // FROM "persons"
    // WHERE "name" = :NAME
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name'],
        where: {name: {eq: 'Stephane'}}
    }));
}
```

필터를 결합할 수도 있습니다.

```
export function request(ctx) {

    // Generates statement:
    // SELECT "id", "name"
    // FROM "persons"
    // WHERE "name" = :NAME and "id" > :ID
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name'],
        where: {name: {eq: 'Stephane'}, id: {gt: 10}}
    }));
}
```

`OR` 문을 작성할 수 있습니다.

```
export function request(ctx) {

    // Generates statement:
    // SELECT "id", "name"
    // FROM "persons"
    // WHERE "name" = :NAME OR "id" > :ID
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name'],
        where: { or: [
            { name: { eq: 'Stephane'} },
            { id: { gt: 10 } }
        ]}
    }));
}
```

`not`으로 조건을 무효화할 수도 있습니다.

```
export function request(ctx) {

    // Generates statement:
    // SELECT "id", "name"
    // FROM "persons"
    // WHERE NOT ("name" = :NAME AND "id" > :ID)
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name'],
        where: { not: [
            { name: { eq: 'Stephane'} },
            { id: { gt: 10 } }
        ]}
    }));
}
```

다음 작업을 사용하여 값을 비교할 수도 있습니다.


| 
| 
| 연산자 | 설명 | 가능한 값 유형 | 
| --- |--- |--- |
| eq | Equal | number, string, boolean | 
| ne | Not equal | number, string, boolean | 
| le | Less than or equal | number, string | 
| lt | Less than | number, string | 
| ge | Greater than or equal | number, string | 
| gt | Greater than | number, string | 
| contains | Like | string | 
| notContains | Not like | string | 
| beginsWith | Starts with prefix | string | 
| between | Between two values | number, string | 
| attributeExists | The attribute is not null | number, string, boolean | 
| size | checks the length of the element | string | 

#### Insert
<a name="built-in-rds-modules-functions-insert"></a>

이 `insert` 유틸리티는 `INSERT` 작업과 함께 데이터베이스에 단일 행 항목을 삽입하는 간단한 방법을 제공합니다.

**단일 항목 삽입**

항목을 삽입하려면 테이블을 지정한 다음 값 객체를 전달하십시오. 객체 키는 테이블 열에 매핑됩니다. 열 이름은 자동으로 이스케이프 처리되고 변수 맵을 사용하여 값이 데이터베이스로 전송됩니다.

```
import { insert, createMySQLStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const { input: values } = ctx.args;
    const insertStatement = insert({ table: 'persons', values });
    
    // Generates statement:
    // INSERT INTO `persons`(`name`)
    // VALUES(:NAME)
    return createMySQLStatement(insertStatement)
}
```

**MySQL 사용 사례**

`select`가 뒤따르는 `insert`를 결합하여 삽입된 행을 검색할 수 있습니다.

```
import { insert, select, createMySQLStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const { input: values } = ctx.args;
    const insertStatement = insert({  table: 'persons', values });
    const selectStatement = select({
        table: 'persons',
        columns: '*',
        where: { id: { eq: values.id } },
        limit: 1,
    });
    
    // Generates statement:
    // INSERT INTO `persons`(`name`)
    // VALUES(:NAME)
    // and
    // SELECT *
    // FROM `persons`
    // WHERE `id` = :ID
    return createMySQLStatement(insertStatement, selectStatement)
}
```

**Postgres 사용 사례**

Postgres를 사용하면 삽입한 행에서 데이터를 가져오는 데 [https://www.postgresql.org/docs/current/dml-returning.html](https://www.postgresql.org/docs/current/dml-returning.html)을 사용할 수 있습니다. `*` 또는 열 이름 배열을 받아들입니다.

```
import { insert, createPgStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const { input: values } = ctx.args;
    const insertStatement = insert({
        table: 'persons',
        values,
        returning: '*'
    });

    // Generates statement:
    // INSERT INTO "persons"("name")
    // VALUES(:NAME)
    // RETURNING *
    return createPgStatement(insertStatement)
}
```

#### 업데이트
<a name="built-in-rds-modules-functions-update"></a>

`update` 유틸리티를 사용하여 기존 행을 업데이트할 수 있습니다. 조건 객체를 사용하여 조건을 충족하는 모든 행의 지정된 열에 변경 내용을 적용할 수 있습니다. 예를 들어 이러한 변형을 만들 수 있는 스키마가 있다고 가정해 보겠습니다. 해당 `2000` 연도부터 인식(`known_since`)하게 된 경우에만 `Person`의`name`을 `3`의 `id` 값으로 업데이트하려고 합니다.

```
mutation Update {
    updatePerson(
        input: {id: 3, name: "Jon"},
        condition: {known_since: {ge: "2000"}}
    ) {
    id
    name
  }
}
```

업데이트 해석기는 다음과 같이 생겼습니다.

```
import { update, createPgStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const { input: { id, ...values }, condition } = ctx.args;
    const where = {
        ...condition,
        id: { eq: id },
    };
    const updateStatement = update({
        table: 'persons',
        values,
        where,
        returning: ['id', 'name'],
    });

    // Generates statement:
    // UPDATE "persons"
    // SET "name" = :NAME, "birthday" = :BDAY, "country" = :COUNTRY
    // WHERE "id" = :ID
    // RETURNING "id", "name"
    return createPgStatement(updateStatement)
}
```

조건에 검사를 추가하여 `3`와 동등한 프라이머리 키 `id`를 가진 행만 업데이트되도록 할 수 있습니다. 마찬가지로 Postgres `inserts`의 경우 수정된 데이터를 반환하는 데 `returning`을 사용할 수 있습니다.

#### 제거
<a name="built-in-rds-modules-functions-remove"></a>

`remove` 유틸리티를 사용하여 기존 행을 제거할 수 있습니다. 조건을 충족하는 모든 행에서 조건 객체를 사용할 수 있습니다. 참고로 `delete`는 JavaScript에서 예약된 키워드입니다. 대신 `remove`를 사용해야 합니다.

```
import { remove, createPgStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const { input: { id }, condition } = ctx.args;
    const where = { ...condition, id: { eq: id } };
    const deleteStatement = remove({
        table: 'persons',
        where,
        returning: ['id', 'name'],
    });

    // Generates statement:
    // DELETE "persons"
    // WHERE "id" = :ID
    // RETURNING "id", "name"
    return createPgStatement(updateStatement)
}
```

### 캐스팅
<a name="built-in-rds-modules-casting"></a>

올바른 객체 유형을 더 구체적으로 지정하여 문에 사용하려는 경우가 있을 수 있습니다. 제공된 유형 힌트를 사용하여 파라미터 유형을 지정할 수 있습니다.는 데이터 API와 [동일한 유형 힌트](https://docs.aws.amazon.com//rdsdataservice/latest/APIReference/API_SqlParameter.html#rdsdtataservice-Type-SqlParameter-typeHint)를 AWS AppSync 지원합니다. 모듈의 `typeHint` 함수를 사용하여 파라미터를 캐스팅할 AWS AppSync `rds` 수 있습니다.

다음 예시에서는 JSON 객체로 캐스팅된 값으로 배열을 보낼 수 있습니다. `->` 연산자를 사용하여 JSON 배열의 `index` `2`에서 요소를 검색합니다.

```
import { sql, createPgStatement, toJsonObject, typeHint } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const arr = ctx.args.list_of_ids
    const statement = sql`select ${typeHint.JSON(arr)}->2 as value`
    return createPgStatement(statement)
}

export function response(ctx) {
    return toJsonObject(ctx.result)[0][0].value
}
```

캐스팅은 `DATE`, `TIME` 및 `TIMESTAMP` 등을 처리하고 비교할 때도 유용합니다.

```
import { select, createPgStatement, typeHint } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const when = ctx.args.when
    const statement = select({
        table: 'persons',
        where: { createdAt : { gt: typeHint.DATETIME(when) } }
    })
    return createPgStatement(statement)
}
```

다음에서는 현재 날짜와 시간을 보낼 수 있는 방법을 보여줍니다.

```
import { sql, createPgStatement, typeHint } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const now = util.time.nowFormatted('YYYY-MM-dd HH:mm:ss')
    return createPgStatement(sql`select ${typeHint.TIMESTAMP(now)}`)
}
```

**사용 가능한 유형 힌트**
+ `typeHint.DATE` – 해당 파라미터는 `DATE` 유형의 객체로 데이터베이스에 전송됩니다. 승인된 형식은 `YYYY-MM-DD`입니다.
+ `typeHint.DECIMAL` – 해당 파라미터는 `DECIMAL` 유형의 객체로 데이터베이스에 전송됩니다.
+ `typeHint.JSON` – 해당 파라미터는 `JSON` 유형의 객체로 데이터베이스에 전송됩니다.
+ `typeHint.TIME` – 해당 문자열 파라미터 값은 `TIME` 유형의 객체로 데이터베이스에 전송됩니다. 승인된 형식은 `HH:MM:SS[.FFF]`입니다.
+ `typeHint.TIMESTAMP` – 해당 문자열 파라미터 값은 `TIMESTAMP` 유형의 객체로 데이터베이스에 전송됩니다. 승인된 형식은 `YYYY-MM-DD HH:MM:SS[.FFF]`입니다.
+ `typeHint.UUID` – 해당 문자열 파라미터 값은 `UUID` 유형의 객체로 데이터베이스에 전송됩니다.

# 런타임 유틸리티
<a name="runtime-utils-js"></a>

`runtime` 라이브러리는 해석기 및 함수의 런타임 속성을 제어하거나 수정하는 유틸리티를 제공합니다.

## 런타임 유틸리티 목록
<a name="runtime-utils-list-js"></a>

 **`runtime.earlyReturn(obj?: unknown, returnOptions?: {skipTo: 'END' | 'NEXT'}): never`**  
이 함수를 호출하면 현재 컨텍스트에 따라 현재 핸들러, AWS AppSync 함수 또는 해석기(단위 또는 파이프라인 해석기)의 실행이 중지됩니다. 지정된 객체가 결과로 반환됩니다.  
+  AWS AppSync 함수 요청 핸들러에서 호출하면 데이터 소스 및 응답 핸들러가 건너뛰고 다음 함수 요청 핸들러(또는 마지막 AWS AppSync 함수인 경우 파이프라인 해석기 응답 핸들러)가 호출됩니다.
+  AWS AppSync 파이프라인 해석기 요청 핸들러에서 호출되면 파이프라인 실행을 건너뛰고 파이프라인 해석기 응답 핸들러가 즉시 호출됩니다.
+ `returnOptions`가 'END'로 설정된 상태로 `skipTo`와 함께 제공되면 파이프라인 실행을 건너뛰고 파이프라인 해석기 응답 핸들러가 즉시 직접 호출됩니다.
+ `returnOptions`가 'NEXT'로 설정된 상태로 `skipTo`와 함께 제공되면 함수 실행을 건너뛰고 다음 파이프라인 핸들러가 직접 호출합니다.
**예제**  

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

export function request(ctx) {
  runtime.earlyReturn({ hello: 'world' })
  // code below is not executed
  return ctx.args
}

// never called because request returned early
export function response(ctx) {
  return ctx.result
}
```

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

`util.dynamodb`에는 Amazon DynamoDB에 데이터 쓰기 및 읽기를 더 용이하게 하는 도우미 메서드가 포함되어 있습니다(예: 자동 유형 매핑 및 형식 지정).

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

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

 **`util.dynamodb.toDynamoDB(Object)`**   
입력 객체를 적절한 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" }
                       ]
                   }
               }
           }
```

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

**`util.dynamodb.toList(List)`**  
객체 목록을 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" }
                       }
                   }
               ]
           }
```

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

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

 **`util.dynamodb.toMap(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.toMapValues(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)`과 약간 다릅니다. 예를 들어 다음 문은 정확하게 동일합니다.  

```
util.dynamodb.toMapValues(<map>)
util.dynamodb.toMap(<map>)("M")
```

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

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

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

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

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

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

 **`util.dynamodb.fromS3ObjectJson(String)`**  
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" }
```

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

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

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

 **`util.http.copyHeaders(headers)`**  
다음과 같은 제한된 HTTP 헤더를 제외하고 맵에서 헤더를 복사합니다.  
+ transfer-encoding
+ connection
+ host
+ expect
+ keep-alive
+ upgrade
+ proxy-authenticate
+ proxy-authorization
+ te
+ content-length

**`util.http.addResponseHeader(String, Object)`**  
응답의 이름(`String`) 및 값(`Object`)이 포함된 단일 사용자 지정 헤더를 추가합니다. 다음과 같은 제한이 적용됩니다.  
+ `copyHeaders(headers)`의 제한된 헤더 목록 외에도 헤더 이름은 다음 중 하나와 일치할 수 없습니다.
  + 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 {}
}
```

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

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

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

**`util.transform.toDynamoDBFilterExpression(filterObject: DynamoDBFilterObject) : string`**  
입력 문자열을 DynamoDB에 사용할 필터 표현식으로 변환합니다. `toDynamoDBFilterExpression`을 [기본 제공 모듈 함수](https://docs.aws.amazon.com/appsync/latest/devguide/built-in-modules-js.html)와 함께 사용하는 것이 좋습니다.

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

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

```
{
    "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로 가정합니다.

**`util.transform.toSubscriptionFilter(objFilter, ignoredFields?, rules?): SubscriptionFilter`**  
`Map` 입력 객체를 `SubscriptionFilter` 표현식 객체로 변환합니다. `util.transform.toSubscriptionFilter` 메서드는 `extensions.setSubscriptionFilter()` 확장에 대한 입력으로 사용됩니다. 자세한 내용은 [확장](https://docs.aws.amazon.com/appsync/latest/devguide/extensions-js.html)을 참조하세요.  
파라미터와 반환 명령문은 다음과 같습니다.  
*파라미터*  
+ `objFilter`: `SubscriptionFilterObject`

  `SubscriptionFilter` 표현식 객체로 변환되는 `Map` 입력 객체입니다.
+ `ignoredFields`: `SubscriptionFilterExcludeKeysType`(선택 사항)

  무시될 첫 번째 객체의 필드 이름 `List`입니다.
+ `rules`: `SubscriptionFilterRuleObject`(선택 사항)

  `SubscriptionFilter` 표현식 객체를 생성할 때 포함되는 엄격한 규칙이 있는 `Map` 입력 객체입니다. 이러한 엄격한 규칙이 `SubscriptionFilter` 표현식 객체에 포함되므로 최소한 하나의 규칙이 충족되어 구독 필터를 통과할 수 있습니다.
*응답*  
`[SubscriptionFilter](https://docs.aws.amazon.com/appsync/latest/devguide/extensions-js.html)`을 반환합니다.

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

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

**`util.transform.toDynamoDBConditionExpression(conditionObject)`**  
DynamoDB 조건 표현식을 생성합니다.

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

다음 표에서는 다음 유틸리티의 인수를 정의하는 방법을 설명합니다.
+ `Util.transform.toSubscriptionFilter(objFilter, ignoredFields?, rules?): SubscriptionFilter`

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

------

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

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

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

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

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

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

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

**`extensions.evictFromApiCache(typeName: string, fieldName: string, keyValuePair: Record<string, any>) : Object`**  
 AWS AppSync 서버 측 캐시에서 항목을 제거합니다. 첫 번째 인수는 형식 이름입니다. 두 번째 인수는 필드 이름입니다. 세 번째 인수는 캐싱 키 값을 지정하는 키-값 쌍 항목을 포함하는 객체입니다. 캐시된 해석기의 `cachingKey`에 있는 캐싱 키와 동일한 순서로 객체에 항목을 넣어야 합니다. 캐싱에 대한 자세한 정보는 [캐싱 동작](https://docs.aws.amazon.com/appsync/latest/devguide/enabling-caching.html#caching-behavior)을 참조하세요.  
**예제 1:**  
이 예에서는 이름이 `context.arguments.semester`인 캐싱 키가 사용된 해석기 `Query.allClasses`에 대해 캐시된 항목을 제거합니다. 뮤테이션이 호출되고 해석기가 실행될 때 항목이 성공적으로 지워지면 응답에는 삭제된 항목 수를 표시하는 `apiCacheEntriesDeleted` 값이 확장 객체에 포함됩니다.  

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

export const request = (ctx) => ({ payload: null });

export function response(ctx) {
	extensions.evictFromApiCache('Query', 'allClasses', {
		'context.arguments.semester': ctx.args.semester,
	});
	return null;
}
```
이 함수는 뮤테이션**에만** 작동하고 쿼리에는 작동하지 않습니다.

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

**`extensions.setSubscriptionFilter(filterJsonObject)`**  
향상된 구독 필터를 정의합니다. 각 구독 알림 이벤트는 제공된 구독 필터에 대해 평가되고 모든 필터가 `true`로 평가되면 클라이언트에 알림을 전달합니다. 인수는 `filterJsonObject`입니다(이 인수에 대한 자세한 내용은 아래 *인수: filterJsonObject* 섹션에서 확인). [향상된 구독 필터링](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-real-time-enhanced-filtering.html)을 참조하세요.  
이 확장 함수는 구독 해석기의 응답 핸들러에서만 사용할 수 있습니다. 또한 필터를 만들 때는 `util.transform.toSubscriptionFilter`를 사용하는 것이 좋습니다.

**`extensions.setSubscriptionInvalidationFilter(filterJsonObject)`**  
구독 무효화 필터를 정의합니다. 구독 필터는 무효화 페이로드에 대해 평가된 후 필터가 `true`로 평가되면 지정된 구독을 무효화합니다. 인수는 `filterJsonObject`입니다(이 인수에 대한 자세한 내용은 아래 *인수: filterJsonObject* 섹션에서 확인). [향상된 구독 필터링](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-real-time-enhanced-filtering.html)을 참조하세요.  
이 확장 함수는 구독 해석기의 응답 핸들러에서만 사용할 수 있습니다. 또한 필터를 만들 때는 `util.transform.toSubscriptionFilter`를 사용하는 것이 좋습니다.

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

## 인수: filterJsonObject
<a name="extensions-filterJsonObject-js"></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
}
```

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

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

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

  ```
  export const request = (ctx) => ({ payload: null });
  
  export function response(ctx) {
  	extensions.invalidateSubscriptions({
  		subscriptionField: 'onUserDelete',
  		payload: { group: 'Developer', type: 'Full-Time' },
  	});
  	return ctx.result;
  }
  ```

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

 `util.xml`에는 XML 문자열 변환에 도움이 되는 메서드가 있습니다.

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

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

```
Input:

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

Output (object):

{
    "posts":{
      "post":{
        "id":1,
        "title":"Getting started with GraphQL"
      }
    }
}
```
**예제 2:**  

```
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 AppSync</title>
</post>
</posts>

Output (JavaScript object):

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

**`util.xml.toJsonString(String, Boolean?) : String`**  
XML 문자열을 JSON 문자열로 변환합니다. 출력이 문자열인 것을 제외하면 `toMap`과 비슷합니다. 이는 HTTP 객체에서 JSON으로 XML 응답을 직접 변환하고 반환하고자 하는 경우 유용합니다. 선택적 부울 파라미터를 설정하여 JSON을 문자열 인코딩할지 여부를 결정할 수 있습니다.

# DynamoDB용AWS AppSync JavaScript 해석기 함수 참조
<a name="js-resolver-reference-dynamodb"></a>

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

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

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

`GetItem` 요청의 구조는 다음과 같습니다.

```
type DynamoDBGetItem = {
  operation: 'GetItem';
  key: { [key: string]: any };
  consistentRead?: ConsistentRead;
  projection?: {
    expression: string;
    expressionNames?: { [key: string]: string };
  };
};
```

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

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

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

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

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

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

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

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

DynamoDB 유형 변환에 대한 자세한 내용은 [유형 시스템(응답 매핑)](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-responses)을 참조하세요.

JavaScript 해석기에 대한 자세한 내용은 [JavaScript 해석기 개요](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html)를 참조하세요.

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

다음 예제는 GraphQL 쿼리 `getThing(foo: String!, bar: String!)`을 위한 함수 요청 핸들러입니다.

```
export function request(ctx) {
  const {foo, bar} = ctx.args
  return {
    operation : "GetItem",
    key : util.dynamodb.toMapValues({foo, bar}),
    consistentRead : true
  }
}
```

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

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

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

`PutItem` 요청의 구조는 다음과 같습니다.

```
type DynamoDBPutItemRequest = {
  operation: 'PutItem';
  key: { [key: string]: any };
  attributeValues: { [key: string]: any};
  condition?: ConditionCheckExpression;
  customPartitionKey?: string;
  populateIndexFields?: boolean;
  _version?: number;
};
```

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

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

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

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

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

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

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

 **`_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에 기록된 항목은 자동으로 GraphQL 및 JSON 기본 유형으로 변환되며 컨텍스트 결과(`context.result`)에서 사용할 수 있습니다.

DynamoDB 유형 변환에 대한 자세한 내용은 [유형 시스템(응답 매핑)](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-responses)을 참조하세요.

JavaScript 해석기에 대한 자세한 내용은 [JavaScript 해석기 개요](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html)를 참조하세요.

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

다음 예제는 GraphQL 뮤테이션 `updateThing(foo: String!, bar: String!, name: String!, version: Int!)`을 위한 함수 요청 핸들러입니다.

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

```
import { util } from '@aws-appsync/utils';
export function request(ctx) {
  const { foo, bar, ...values} = ctx.args
  return {
    operation: 'PutItem',
    key: util.dynamodb.toMapValues({foo, bar}),
    attributeValues: util.dynamodb.toMapValues(values),
  };
}
```

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

다음 예제는 GraphQL 뮤테이션 `updateThing(foo: String!, bar: String!, name: String!, expectedVersion: Int!)`을 위한 함수 요청 핸들러입니다.

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

```
import { util } from '@aws-appsync/utils';
export function request(ctx) {
  const { foo, bar, name, expectedVersion } = ctx.args;
  const values = { name, version: expectedVersion + 1 };
  let condition = util.transform.toDynamoDBConditionExpression({
    version: { eq: expectedVersion },
  });

  return {
    operation: 'PutItem',
    key: util.dynamodb.toMapValues({ foo, bar }),
    attributeValues: util.dynamodb.toMapValues(values),
    condition,
  };
}
```

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

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

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

`UpdateItem` 요청의 구조는 다음과 같습니다.

```
type DynamoDBUpdateItemRequest = {
  operation: 'UpdateItem';
  key: { [key: string]: any };
  update: {
    expression: string;
    expressionNames?: { [key: string]: string };
    expressionValues?: { [key: string]: any };
  };
  condition?: ConditionCheckExpression;
  customPartitionKey?: string;
  populateIndexFields?: boolean;
  _version?: number;
};
```

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

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

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

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

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

 **`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 자리 표시자에 해당하고 값은 입력된 값이어야 합니다. '입력된 값'을 지정하는 방법에 대한 자세한 내용은 [유형 시스템(요청 매핑)](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request)을 참조하세요. 입력된 값은 지정되어 있어야 합니다. 이 필드는 선택 사항으로, `expression`에 사용된 표현식 속성인 value 자리 표시자의 대체 항목으로만 채워져야 합니다.

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

 **`_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 유형 변환에 대한 자세한 내용은 [유형 시스템(응답 매핑)](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-responses)을 참조하세요.

JavaScript 해석기에 대한 자세한 내용은 [JavaScript 해석기 개요](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html)를 참조하세요.

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

다음 예제는 GraphQL 뮤테이션 `upvote(id: ID!)`를 위한 함수 요청 핸들러입니다.

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

```
import { util } from '@aws-appsync/utils';
export function request(ctx) {
  const { id } = ctx.args;
  return {
    operation: 'UpdateItem',
    key: util.dynamodb.toMapValues({ id }),
    update: {
      expression: 'ADD #votefield :plusOne, version :plusOne',
      expressionNames: { '#votefield': 'upvotes' },
      expressionValues: { ':plusOne': { N: 1 } },
    },
  };
}
```

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

다음 예제는 GraphQL 뮤테이션 `updateItem(id: ID!, title: String, author: String, expectedVersion: Int!)`을 위한 함수 요청 핸들러입니다.

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

```
import { util } from '@aws-appsync/utils';
export function request(ctx) {
  const { args: { input: { id, ...values } } } = ctx;

  const condition = {
    id: { attributeExists: true },
    version: { eq: values.expectedVersion },
  };
  values.expectedVersion += 1;
  return dynamodbUpdateRequest({ keys: { id }, values, condition });
}


/**
 * Helper function to update an item
 * @returns an UpdateItem request
 */
function dynamodbUpdateRequest(params) {
  const { keys, values, condition: inCondObj } = params;

  const sets = [];
  const removes = [];
  const expressionNames = {};
  const expValues = {};

  // Iterate through the keys of the values
  for (const [key, value] of Object.entries(values)) {
    expressionNames[`#${key}`] = key;
    if (value) {
      sets.push(`#${key} = :${key}`);
      expValues[`:${key}`] = value;
    } else {
      removes.push(`#${key}`);
    }
  }

  let expression = sets.length ? `SET ${sets.join(', ')}` : '';
  expression += removes.length ? ` REMOVE ${removes.join(', ')}` : '';

  const condition = JSON.parse(
    util.transform.toDynamoDBConditionExpression(inCondObj)
  );

  return {
    operation: 'UpdateItem',
    key: util.dynamodb.toMapValues(keys),
    condition,
    update: {
      expression,
      expressionNames,
      expressionValues: util.dynamodb.toMapValues(expValues),
    },
  };
}
```

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

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

`DeleteItem` 요청을 통해 AWS AppSync DynamoDB 함수에 DynamoDB에 `DeleteItem` 요청하도록 지시하고 다음을 지정할 수 있습니다.
+ DynamoDB의 항목 키
+ 성공할 작업의 조건

`DeleteItem` 요청의 구조는 다음과 같습니다.

```
type DynamoDBDeleteItemRequest = {
  operation: 'DeleteItem';
  key: { [key: string]: any };
  condition?: ConditionCheckExpression;
  customPartitionKey?: string;
  populateIndexFields?: boolean;
  _version?: number;
};
```

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

## DeleteItem 필드
<a name="js-deleteitem-list"></a>

### DeleteItem 필드 목록
<a name="js-deleteitem-list-col"></a>

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

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

** `condition` **  
DynamoDB에 이미 있는 객체의 상태를 기반으로 요청의 성공 여부를 결정하는 조건. 조건을 지정하지 않으면 `DeleteItem` 요청이 현재 상태와 상관 없이 항목을 삭제합니다. 조건에 대한 자세한 내용은 [조건 표현식](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-condition-expressions)을 참조하세요. 이 값은 선택 사항입니다.

** `_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 유형 변환에 대한 자세한 내용은 [유형 시스템(응답 매핑)](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-responses)을 참조하세요.

JavaScript 해석기에 대한 자세한 내용은 [JavaScript 해석기 개요](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html)를 참조하세요.

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

다음 예제는 GraphQL 뮤테이션 `deleteItem(id: ID!)`을 위한 함수 요청 핸들러입니다. 이 ID를 가진 항목이 있으면 해당 항목은 삭제됩니다.

```
import { util } from '@aws-appsync/utils';
export function request(ctx) {
  return {
    operation: 'DeleteItem',
    key: util.dynamodb.toMapValues({ id: ctx.args.id }),
  };
}
```

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

다음 예제는 GraphQL 뮤테이션 `deleteItem(id: ID!, expectedVersion: Int!)`을 위한 함수 요청 핸들러입니다. 이 ID를 가진 항목이 있으면 해당 항목은 `version` 필드가 `expectedVersion`으로 설정된 경우에만 삭제됩니다.

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

export function request(ctx) {
  const { id, expectedVersion } = ctx.args;
  const condition = {
    id: { attributeExists: true },
    version: { eq: expectedVersion },
  };
  return {
    operation: 'DeleteItem',
    key: util.dynamodb.toMapValues({ id }),
    condition: util.transform.toDynamoDBConditionExpression(condition),
  };
}
```

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

# Query
<a name="js-aws-appsync-resolver-reference-dynamodb-query"></a>

`Query` 요청 객체를 사용하면 AWS AppSync DynamoDB 해석기에 DynamoDB에 `Query` 요청하도록 지시하고 다음을 지정할 수 있습니다.
+ 키 표현식
+ 사용할 인덱스
+ 모든 추가 필터
+ 반환할 항목 수
+ 일관된 읽기를 사용할지 여부
+ 쿼리 방향(앞으로 또는 뒤로)
+ 페이지 매김 토큰입니다

`Query` 요청 객체는 다음과 같은 구조입니다.

```
type DynamoDBQueryRequest = {
  operation: 'Query';
  query: {
    expression: string;
    expressionNames?: { [key: string]: string };
    expressionValues?: { [key: string]: any };
  };
  index?: string;
  nextToken?: string;
  limit?: number;
  scanIndexForward?: boolean;
  consistentRead?: boolean;
  select?: 'ALL_ATTRIBUTES' | 'ALL_PROJECTED_ATTRIBUTES' | 'SPECIFIC_ATTRIBUTES';
  filter?: {
    expression: string;
    expressionNames?: { [key: string]: string };
    expressionValues?: { [key: string]: any };
  };
  projection?: {
    expression: string;
    expressionNames?: { [key: string]: string };
  };
};
```

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

## 쿼리 필드
<a name="js-query-list"></a>

### 쿼리 필드 목록
<a name="js-query-list-col"></a>

** `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 자리 표시자에 해당하고 값은 입력된 값이어야 합니다. '입력된 값'을 지정하는 방법에 대한 자세한 내용은 [유형 시스템(요청 매핑)](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request)을 참조하세요. 이 값은 필수입니다. 이 필드는 선택 사항으로, `expression`에 사용된 표현식 속성인 value 자리 표시자의 대체 항목으로만 채워져야 합니다.

** `filter` **  
반환되기 전 DynamoDB의 결과를 필터링하는 데 사용할 수 있는 추가 필터입니다. 필터에 대한 자세한 내용은 [필터](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-filter)를 참조하십시오. 이 필드는 선택 사항입니다.

** `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/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-projections)을 참조하세요. 이 필드는 선택 사항입니다.

DynamoDB의 결과는 자동으로 GraphQL 및 JSON 기본 유형으로 변환되며 컨텍스트 결과(`context.result`)에서 사용할 수 있습니다.

DynamoDB 유형 변환에 대한 자세한 내용은 [유형 시스템(응답 매핑)](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-responses)을 참조하세요.

JavaScript 해석기에 대한 자세한 내용은 [JavaScript 해석기 개요](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html)를 참조하세요.

결과의 구조는 다음과 같습니다.

```
{
    items = [ ... ],
    nextToken = "a pagination token",
    scannedCount = 10
}
```

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

** `items` **  
DynamoDB 쿼리에서 반환하는 항목이 포함된 목록.

** `nextToken` **  
더 많은 결과가 있을 수 있는 경우 `nextToken`에는 다른 요청에 사용할 수 있는 페이지 매김 토큰이 포함됩니다. 참고로 AWS AppSync는 DynamoDB에서 반환된 페이지 매김 토큰을 암호화하고 난독화합니다. 따라서 테이블 데이터가 호출자에게 실수로 유출되는 일이 없습니다. 페이지 매김 토큰은 여러 해석기 간에 사용할 수 없습니다.

** `scannedCount` **  
필터 표현식(있는 경우)을 적용하기 전에 쿼리 조건 표현식과 일치했던 항목 수

## 예제
<a name="js-id9"></a>

다음 예제는 GraphQL 쿼리 `getPosts(owner: ID!)`를 위한 함수 요청 핸들러입니다.

이 예에서는 테이블의 글로벌 보조 인덱스를 쿼리해 지정한 ID가 소유한 게시물을 모두 반환합니다.

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

export function request(ctx) {
  const { owner } = ctx.args;
  return {
    operation: 'Query',
    query: {
      expression: 'ownerId = :ownerId',
      expressionValues: util.dynamodb.toMapValues({ ':ownerId': owner }),
    },
    index: 'owner-index',
  };
}
```

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

# 스캔
<a name="js-aws-appsync-resolver-reference-dynamodb-scan"></a>

`Scan` 요청을 통해 AWS AppSync DynamoDB 함수에 DynamoDB에 `Scan` 요청하도록 지시하고 다음을 지정할 수 있습니다.
+ 결과를 제외하는 필터
+ 사용할 인덱스
+ 반환할 항목 수
+ 일관된 읽기를 사용할지 여부
+ 페이지 매김 토큰입니다
+ 병렬 스캔

`Scan` 요청 객체는 다음과 같은 구조입니다.

```
type DynamoDBScanRequest = {
  operation: 'Scan';
  index?: string;
  limit?: number;
  consistentRead?: boolean;
  nextToken?: string;
  totalSegments?: number;
  segment?: number;
  filter?: {
    expression: string;
    expressionNames?: { [key: string]: string };
    expressionValues?: { [key: string]: any };
  };
  projection?: {
    expression: string;
    expressionNames?: { [key: string]: string };
  };
};
```

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

## Scan 필드
<a name="js-scan-list"></a>

### Scan 필드 목록
<a name="js-scan-list-col"></a>

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

** `filter` **  
반환되기 전 DynamoDB의 결과를 필터링하는 데 사용할 수 있는 필터. 필터에 대한 자세한 내용은 [필터](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-filter)를 참조하십시오. 이 필드는 선택 사항입니다.

** `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/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-projections)을 참조하세요. 이 필드는 선택 사항입니다.

DynamoDB 스캔에서 반환하는 결과는 자동으로 GraphQL 및 JSON 기본 유형으로 변환되며 컨텍스트 결과(`context.result`)에서 사용할 수 있습니다.

DynamoDB 유형 변환에 대한 자세한 내용은 [유형 시스템(응답 매핑)](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-responses)을 참조하세요.

JavaScript 해석기에 대한 자세한 내용은 [JavaScript 해석기 개요](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html)를 참조하세요.

결과의 구조는 다음과 같습니다.

```
{
    items = [ ... ],
    nextToken = "a pagination token",
    scannedCount = 10
}
```

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

** `items` **  
DynamoDB 스캔에서 반환하는 항목이 포함된 목록

** `nextToken` **  
결과가 더 있을 수 있는 경우 에는 다른 요청에 사용할 수 있는 페이지 매김 토큰이 `nextToken` 포함되어 있습니다. AWS AppSync는 DynamoDB에서 반환된 페이지 매김 토큰을 암호화하고 난독화합니다. 따라서 테이블 데이터가 호출자에게 실수로 유출되는 일이 없습니다. 또한 페이지 매김 토큰은 여러 함수 또는 해석기 간에 사용할 수 없습니다.

** `scannedCount` **  
필터 표현식(있는 경우)을 적용하기 전에 DynamoDB에서 검색한 항목 수.

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

다음 예제는 GraphQL 쿼리 `allPosts`를 위한 함수 요청 핸들러입니다.

이 예에서는 테이블의 항목을 모두 반환합니다.

```
export function request(ctx) {
  return { operation: 'Scan' };
}
```

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

다음 예제는 GraphQL 쿼리 `postsMatching(title: String!)`을 위한 함수 요청 핸들러입니다.

이 예에서는 제목이 `title` 인수로 시작하는 경우 테이블의 모든 항목이 반환됩니다.

```
export function request(ctx) {
  const { title } = ctx.args;
  const filter = { filter: { beginsWith: title } };
  return {
    operation: 'Scan',
    filter: JSON.parse(util.transform.toDynamoDBFilterExpression(filter)),
  };
}
```

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

# 동기화
<a name="js-aws-appsync-resolver-reference-dynamodb-sync"></a>

`Sync` 요청 객체를 사용하면 DynamoDB 테이블에서 모든 결과를 가져온 다음, 마지막 쿼리(델타 업데이트) 이후에 변경된 데이터만 수신할 수 있습니다. `Sync` 요청은 버전이 지정된 DynamoDB 데이터 소스에만 수행할 수 있습니다. 다음을 지정할 수 있습니다.
+ 결과를 제외하는 필터
+ 반환할 항목 수
+ 페이지 매김 토큰
+ 마지막 `Sync` 작업이 시작된 경우

`Sync` 요청 객체는 다음과 같은 구조입니다.

```
type DynamoDBSyncRequest = {
  operation: 'Sync';
  basePartitionKey?: string;
  deltaIndexName?: string;
  limit?: number;
  nextToken?: string;
  lastSync?: number;
  filter?: {
    expression: string;
    expressionNames?: { [key: string]: string };
    expressionValues?: { [key: string]: any };
  };
};
```

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

## Sync 필드
<a name="js-sync-list"></a>

### Sync 필드 목록
<a name="js-sync-list-col"></a>

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

** `filter` **  
반환되기 전 DynamoDB의 결과를 필터링하는 데 사용할 수 있는 필터. 필터에 대한 자세한 내용은 [필터](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-filter)를 참조하십시오. 이 필드는 선택 사항입니다.

** `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 유형 변환에 대한 자세한 내용은 [유형 시스템(응답 매핑)](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-responses)을 참조하세요.

JavaScript 해석기에 대한 자세한 내용은 [JavaScript 해석기 개요](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html)를 참조하세요.

결과의 구조는 다음과 같습니다.

```
{
    items = [ ... ],
    nextToken = "a pagination token",
    scannedCount = 10,
    startedAt = 1550000000000
}
```

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

** `items` **  
동기화에서 반환하는 항목이 포함된 목록.

** `nextToken` **  
결과가 더 있을 수 있는 경우 에는 다른 요청에 사용할 수 있는 페이지 매김 토큰이 `nextToken` 포함되어 있습니다. AWS AppSync는 DynamoDB에서 반환된 페이지 매김 토큰을 암호화하고 난독화합니다. 따라서 테이블 데이터가 호출자에게 실수로 유출되는 일이 없습니다. 또한 페이지 매김 토큰은 여러 함수 또는 해석기 간에 사용할 수 없습니다.

** `scannedCount` **  
필터 표현식(있는 경우)을 적용하기 전에 DynamoDB에서 검색한 항목 수.

** `startedAt` **  
로컬로 저장하고 다른 요청에 `lastSync` 인수로 사용할 수 있는 동기화 작업이 시작된 시간(Epoch 밀리초)입니다. 페이지 매김 토큰이 요청에 포함된 경우, 이 값은 결과의 첫 페이지에 대한 요청에 의해 반환된 값과 동일합니다.

## 예제
<a name="js-id14"></a>

다음 예제는 GraphQL 쿼리 `syncPosts(nextToken: String, lastSync: AWSTimestamp)`을 위한 함수 요청 핸들러입니다.

이 예에서 `lastSync`가 생략된 경우, 기본 테이블의 모든 항목이 반환됩니다. `lastSync`가 제공된 경우 `lastSync` 이후 변경된 델타 동기화 테이블의 항목만 반환됩니다.

```
export function request(ctx) {
  const { nextToken, lastSync } = ctx.args;
  return { operation: 'Sync', limit: 100, nextToken, lastSync };
}
```

# BatchGetItem
<a name="js-aws-appsync-resolver-reference-dynamodb-batch-get-item"></a>

`BatchGetItem` 요청 객체를 사용하면 AWS AppSync DynamoDB 함수에 DynamoDB에 `BatchGetItem` 요청하여 잠재적으로 여러 테이블에서 여러 항목을 검색하도록 지시할 수 있습니다. 이 요청 객체에 대해 다음을 지정해야 합니다.
+ 항목을 가져올 테이블 이름
+ 각 테이블에서 가져올 항목의 키

DynamoDB `BatchGetItem` 한도가 적용되고 **표현식 없음**이 제공될 수 있습니다.

`BatchGetItem` 요청 객체는 다음과 같은 구조입니다.

```
type DynamoDBBatchGetItemRequest = {
  operation: 'BatchGetItem';
  tables: {
    [tableName: string]: {
      keys: { [key: string]: any }[];
      consistentRead?: boolean; 
      projection?: {
        expression: string;
        expressionNames?: { [key: string]: string };
      };
    };
  };
};
```

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

## BatchGetItem 필드
<a name="js-BatchGetItem-list"></a>

### BatchGetItem 필드 목록
<a name="js-BatchGetItem-list-col"></a>

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

** `tables` **  
항목을 가져올 DynamoDB 테이블입니다. 이 값은 테이블 이름이 맵의 키로 지정되는 맵입니다. 테이블이 하나 이상 제공되어야 합니다. 이 `tables` 값은 필수입니다.    
** `keys` **  
검색할 항목의 프라이머리 키를 나타내는 DynamoDB 키 목록입니다. DynamoDB 항목은 테이블 구조에 따라 단일 해시 키 또는 해시 키와 정렬 키를 가질 수 있습니다. '입력된 값'을 지정하는 방법에 대한 자세한 내용은 [유형 시스템(요청 매핑)](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request)을 참조하세요.  
** `consistentRead` **  
*GetItem* 작업을 실행할 때 일관된 읽기를 사용할지 여부. 이 값은 선택 사항으로, 기본값은 *false*입니다.  
**`projection`**  
DynamoDB 작업에서 반환할 속성을 지정하는 데 사용되는 프로젝션입니다. 프로젝션에 대한 자세한 내용은 [프로젝션](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-projections)을 참조하세요. 이 필드는 선택 사항입니다.

기억해야 할 내용:
+ 테이블에서 항목을 가져오지 못하면 해당 테이블의 데이터 블록에 *null* 요소가 나타납니다.
+ 호출 결과는 요청 객체 내에 제공된 순서에 따라 테이블별로 정렬됩니다.
+ `BatchGetItem` 내부의 각 `Get` 명령은 원자성이지만 배치는 부분적으로 처리될 수 있습니다. 오류로 인해 배치가 부분적으로 처리된 경우 처리되지 않은 키는 *unprocessedKeys* 블록 내에 호출 결과의 일부로 반환됩니다.
+  `BatchGetItem`은 100개의 키로 제한됩니다.

다음은 함수 요청 핸들러 예시입니다.

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

export function request(ctx) {
  const { authorId, postId } = ctx.args;
  return {
    operation: 'BatchGetItem',
    tables: {
      authors: [util.dynamodb.toMapValues({ authorId })],
      posts: [util.dynamodb.toMapValues({ authorId, postId })],
    },
  };
}
```

`ctx.result`에서 사용할 수 있는 호출 결과는 다음과 같습니다.

```
{
   "data": {
     "authors": [null],
     "posts": [
        // Was retrieved
        {
          "authorId": "a1",
          "postId": "p2",
          "postTitle": "title",
          "postDescription": "description",
        }
     ]
   },
   "unprocessedKeys": {
     "authors": [
        // This item was not processed due to an error
        {
          "authorId": "a1"
        }
      ],
     "posts": []
   }
}
```

`ctx.error`에는 오류에 대한 세부 정보가 포함됩니다. 함수 요청 객체의 결과에 제공된 키 **data**, **unprocessedKeys** 및 각 테이블 키는 간접 호출 결과에 존재하는 것이 보장됩니다. 삭제된 항목은 **데이터** 블록에 나타납니다. 처리되지 않은 항목은 데이터 블록 내에서 *null*로 표시되고 **unprocessedKeys** 블록 내에 배치됩니다.

# BatchDeleteItem
<a name="js-aws-appsync-resolver-reference-dynamodb-batch-delete-item"></a>

`BatchDeleteItem` 요청 객체를 사용하면 AWS AppSync DynamoDB 함수에 DynamoDB에 `BatchWriteItem` 요청하여 잠재적으로 여러 테이블에서 여러 항목을 삭제하도록 지시할 수 있습니다. 이 요청 객체에 대해 다음을 지정해야 합니다.
+ 항목을 삭제할 테이블 이름
+ 각 테이블에서 삭제할 항목의 키

DynamoDB `BatchWriteItem` 한도가 적용되고 **표현식 없음**이 제공될 수 있습니다.

`BatchDeleteItem` 요청 객체는 다음과 같은 구조입니다.

```
type DynamoDBBatchDeleteItemRequest = {
  operation: 'BatchDeleteItem';
  tables: {
    [tableName: string]: { [key: string]: any }[];
  };
};
```

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

## BatchDeleteItem 필드
<a name="js-BatchDeleteItem-list"></a>

### BatchDeleteItem 필드 목록
<a name="js-BatchDeleteItem-list-col"></a>

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

** `tables` **  
항목을 삭제할 DynamoDB 테이블입니다. 각 테이블은 삭제할 항목의 프라이머리 키를 나타내는 DynamoDB 키 목록입니다. DynamoDB 항목은 테이블 구조에 따라 단일 해시 키 또는 해시 키와 정렬 키를 가질 수 있습니다. '입력된 값'을 지정하는 방법에 대한 자세한 내용은 [유형 시스템(요청 매핑)](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request)을 참조하세요. 테이블이 하나 이상 제공되어야 합니다. `tables` 값이 필요합니다.

기억해야 할 내용:
+ `DeleteItem` 작업과 달리 완전히 삭제된 항목은 응답에서 반환되지 않습니다. 전달된 키만 반환됩니다.
+ 테이블에서 항목을 삭제하지 못하면 해당 테이블의 데이터 블록에 *null* 요소가 나타납니다.
+ 호출 결과는 요청 객체 내에 제공된 순서에 따라 테이블별로 정렬됩니다.
+ `BatchDeleteItem` 내부의 각 `Delete` 명령은 원자성입니다. 그러나 배치는 부분적으로 처리될 수 있습니다. 오류로 인해 배치가 부분적으로 처리된 경우 처리되지 않은 키는 *unprocessedKeys* 블록 내에 호출 결과의 일부로 반환됩니다.
+  `BatchDeleteItem`은 25개의 키로 제한됩니다.
+ 충돌 감지와 함께 사용할 때 이 작업은 지원되지 **않습니다**. 두 가지를 동시에 사용하면 오류가 발생할 수 있습니다.

다음은 함수 요청 핸들러 예시입니다.

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

export function request(ctx) {
  const { authorId, postId } = ctx.args;
  return {
    operation: 'BatchDeleteItem',
    tables: {
      authors: [util.dynamodb.toMapValues({ authorId })],
      posts: [util.dynamodb.toMapValues({ authorId, postId })],
    },
  };
}
```

`ctx.result`에서 사용할 수 있는 호출 결과는 다음과 같습니다.

```
{
   "data": {
     "authors": [null],
     "posts": [
        // Was deleted
        {
          "authorId": "a1",
          "postId": "p2"
        }
     ]
   },
   "unprocessedKeys": {
     "authors": [
        // This key was not processed due to an error
        {
          "authorId": "a1"
        }
      ],
     "posts": []
   }
}
```

`ctx.error`에는 오류에 대한 세부 정보가 포함됩니다. 함수 요청 객체에 제공된 키 **data**, **unprocessedKeys** 및 각 테이블 키는 간접 호출 결과에 존재하는 것이 보장됩니다. 삭제된 항목은 **데이터** 블록에 나타납니다. 처리되지 않은 항목은 데이터 블록 내에서 *null*로 표시되고 **unprocessedKeys** 블록 내에 배치됩니다.

# BatchPutItem
<a name="js-aws-appsync-resolver-reference-dynamodb-batch-put-item"></a>

`BatchPutItem` 요청 객체를 사용하면 AWS AppSync DynamoDB 함수에 DynamoDB에 `BatchWriteItem` 요청하여 잠재적으로 여러 테이블에 여러 항목을 배치하도록 지시할 수 있습니다. 이 요청 객체에 대해 다음을 지정해야 합니다.
+ 항목을 저장할 테이블 이름
+ 각 테이블에 저장할 전체 항목

DynamoDB `BatchWriteItem` 한도가 적용되고 **표현식 없음**이 제공될 수 있습니다.

`BatchPutItem` 요청 객체는 다음과 같은 구조입니다.

```
type DynamoDBBatchPutItemRequest = {
  operation: 'BatchPutItem';
  tables: {
    [tableName: string]: { [key: string]: any}[];
  };
};
```

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

## BatchPutItem 필드
<a name="js-BatchPutItem-list"></a>

### BatchPutItem 필드 목록
<a name="js-BatchPutItem-list-col"></a>

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

** `tables` **  
항목을 넣을 DynamoDB 테이블입니다. 각 테이블 항목은 이 특정 테이블에 삽입할 DynamoDB 항목 목록을 나타냅니다. 테이블이 하나 이상 제공되어야 합니다. 이 값은 필수입니다.

기억해야 할 내용:
+ 성공하면, 완전히 삽입된 항목이 응답에서 반환됩니다.
+ 테이블에 항목이 삽입되지 못하면 해당 테이블의 데이터 블록에 *null* 요소가 표시됩니다.
+ 삽입된 항목은 요청 객체 내에 제공된 순서에 따라 테이블별로 정렬됩니다.
+ `BatchPutItem` 내부의 각 `Put` 명령은 원자성이지만 배치는 부분적으로 처리될 수 있습니다. 오류로 인해 배치가 부분적으로 처리된 경우 처리되지 않은 키는 *unprocessedKeys* 블록 내에 호출 결과의 일부로 반환됩니다.
+  `BatchPutItem`은 25개의 항목으로 제한됩니다.
+ 충돌 감지와 함께 사용할 때 이 작업은 지원되지 **않습니다**. 두 가지를 동시에 사용하면 오류가 발생할 수 있습니다.

다음은 함수 요청 핸들러 예시입니다.

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

export function request(ctx) {
  const { authorId, postId, name, title } = ctx.args;
  return {
    operation: 'BatchPutItem',
    tables: {
      authors: [util.dynamodb.toMapValues({ authorId, name })],
      posts: [util.dynamodb.toMapValues({ authorId, postId, title })],
    },
  };
}
```

`ctx.result`에서 사용할 수 있는 호출 결과는 다음과 같습니다.

```
{
   "data": {
     "authors": [
         null
     ],
     "posts": [
        // Was inserted
        {
          "authorId": "a1",
          "postId": "p2",
          "title": "title"
        }
     ]
   },
   "unprocessedItems": {
     "authors": [
        // This item was not processed due to an error
        {
          "authorId": "a1",
          "name": "a1_name"
        }
      ],
     "posts": []
   }
}
```

`ctx.error`에는 오류에 대한 세부 정보가 포함됩니다. 키 **data**, **unprocessedItems** 및 요청 객체에서 제공된 각 테이블 키는 호출 결과에 표시됩니다. 삽입된 항목은 **데이터** 블록에 나타납니다. 처리되지 않은 항목은 데이터 블록 내에서 *null*로 표시되고 **unprocessedItems** 블록 내에 배치됩니다.

# TransactGetItems
<a name="js-aws-appsync-resolver-reference-dynamodb-transact-get-items"></a>

`TransactGetItems` 요청 객체를 사용하면 AWS AppSync DynamoDB 함수에 DynamoDB에 `TransactGetItems` 요청하여 잠재적으로 여러 테이블에서 여러 항목을 검색하도록 지시할 수 있습니다. 이 요청 객체에 대해 다음을 지정해야 합니다.
+ 항목을 가져올 각 요청 항목의 테이블 이름
+ 각 테이블에서 가져올 각 요청 항목의 키

DynamoDB `TransactGetItems` 한도가 적용되고 **표현식 없음**이 제공될 수 있습니다.

`TransactGetItems` 요청 객체는 다음과 같은 구조입니다.

```
type DynamoDBTransactGetItemsRequest = {
  operation: 'TransactGetItems';
  transactItems: { table: string; key: { [key: string]: any }; projection?: { expression: string; expressionNames?: { [key: string]: string }; }[];
  };
};
```

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

## TransactGetItems 필드
<a name="js-TransactGetItems-list"></a>

### TransactGetItems 필드 목록
<a name="js-TransactGetItems-list-col"></a>

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

** `transactItems` **  
포함할 요청 항목입니다. 이 값은 요청 항목의 배열입니다. 하나 이상의 요청 항목이 제공되어야 합니다. 이 `transactItems` 값은 필수입니다.    
** `table` **  
항목을 가져올 DynamoDB 테이블입니다. 이 값은 테이블 이름의 문자열입니다. 이 `table` 값은 필수입니다.  
** `key` **  
검색할 항목의 프라이머리 키를 나타내는 DynamoDB 키입니다. DynamoDB 항목은 테이블 구조에 따라 단일 해시 키 또는 해시 키와 정렬 키를 가질 수 있습니다. '입력된 값'을 지정하는 방법에 대한 자세한 내용은 [유형 시스템(요청 매핑)](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request)을 참조하세요.  
**`projection`**  
DynamoDB 작업에서 반환할 속성을 지정하는 데 사용되는 프로젝션입니다. 프로젝션에 대한 자세한 내용은 [프로젝션](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-projections)을 참조하세요. 이 필드는 선택 사항입니다.

기억해야 할 내용:
+ 트랜잭션이 성공하면 `items` 블록에서 가져오는 항목의 순서는 요청 항목의 순서와 동일합니다.
+ 트랜잭션은 전부 또는 전무 방식으로 수행됩니다. 요청 항목에 오류가 발생하면 전체 트랜잭션이 수행되지 않고 오류 세부 정보가 반환됩니다.
+ 가져올 수 없는 요청 항목은 오류가 아닙니다. 대신 해당 위치의 *항목* 블록에 *null* 요소가 나타납니다.
+ 트랜잭션의 오류가 *TransactionCanceledException*인 경우 `cancellationReasons` 블록이 채워집니다. `cancellationReasons` 블록 내의 취소 사유 순서는 요청 항목의 순서와 동일합니다.
+  `TransactGetItems`는 100개의 요청 항목으로 제한됩니다.

다음은 함수 요청 핸들러 예시입니다.

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

export function request(ctx) {
  const { authorId, postId } = ctx.args;
  return {
    operation: 'TransactGetItems',
    transactItems: [
      {
        table: 'posts',
        key: util.dynamodb.toMapValues({ postId }),
      },
      {
        table: 'authors',
        key: util.dynamodb.toMapValues({ authorId }),
      },
    ],
  };
}
```

트랜잭션이 성공하고 첫 번째 요청된 항목만 검색되는 경우 `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`에 있습니다.

# TransactWriteItems
<a name="js-aws-appsync-resolver-reference-dynamodb-transact-write-items"></a>

`TransactWriteItems` 요청 객체를 사용하면 AWS AppSync DynamoDB 함수에 DynamoDB에 `TransactWriteItems` 요청하여 잠재적으로 여러 테이블에 여러 항목을 쓰도록 지시할 수 있습니다. 이 요청 객체에 대해 다음을 지정해야 합니다.
+ 각 요청 항목의 대상 테이블 이름
+ 수행할 각 요청 항목의 작업입니다. 지원되는 작업에는 *PutItem*, *UpdateItem*, *DeleteItem*, *ConditionCheck*의 네 가지 유형이 있습니다.
+ 작성할 각 요청 항목의 키

DynamoDB `TransactWriteItems` 제한이 적용됩니다.

`TransactWriteItems` 요청 객체는 다음과 같은 구조입니다.

```
type DynamoDBTransactWriteItemsRequest = {
  operation: 'TransactWriteItems';
  transactItems: TransactItem[];
};
type TransactItem =
  | TransactWritePutItem
  | TransactWriteUpdateItem
  | TransactWriteDeleteItem
  | TransactWriteConditionCheckItem;
type TransactWritePutItem = {
  table: string;
  operation: 'PutItem';
  key: { [key: string]: any };
  attributeValues: { [key: string]: string};
  condition?: TransactConditionCheckExpression;
};
type TransactWriteUpdateItem = {
  table: string;
  operation: 'UpdateItem';
  key: { [key: string]: any };
  update: DynamoDBExpression;
  condition?: TransactConditionCheckExpression;
};
type TransactWriteDeleteItem = {
  table: string;
  operation: 'DeleteItem';
  key: { [key: string]: any };
  condition?: TransactConditionCheckExpression;
};
type TransactWriteConditionCheckItem = {
  table: string;
  operation: 'ConditionCheck';
  key: { [key: string]: any };
  condition?: TransactConditionCheckExpression;
};
type TransactConditionCheckExpression = {
  expression: string;
  expressionNames?: { [key: string]: string};
  expressionValues?: { [key: string]: any};
  returnValuesOnConditionCheckFailure: boolean;
};
```

## TransactWriteItems 필드
<a name="js-TransactWriteItems-list"></a>

### TransactWriteItems 필드 목록
<a name="js-TransactWriteItems-list-col"></a>

**필드는 다음과 같이 정의됩니다.**    
** `operation` **  
수행할 DynamoDB 작업입니다. `TransactWriteItems` DynamoDB 작업을 수행하려면 이 값을 `TransactWriteItems`으로 설정해야 합니다. 이 값은 필수입니다.  
** `transactItems` **  
포함할 요청 항목입니다. 이 값은 요청 항목의 배열입니다. 하나 이상의 요청 항목이 제공되어야 합니다. 이 `transactItems` 값은 필수입니다.  
`PutItem`의 필드는 다음과 같이 정의됩니다.    
** `table` **  
대상 DynamoDB 테이블입니다. 이 값은 테이블 이름의 문자열입니다. 이 `table` 값은 필수입니다.  
** `operation` **  
수행할 DynamoDB 작업입니다. `PutItem` DynamoDB 작업을 수행하려면 이 값을 `PutItem`으로 설정해야 합니다. 이 값은 필수입니다.  
** `key` **  
입력할 항목의 프라이머리 키를 나타내는 DynamoDB 키입니다. DynamoDB 항목은 테이블 구조에 따라 단일 해시 키 또는 해시 키와 정렬 키를 가질 수 있습니다. '입력된 값'을 지정하는 방법에 대한 자세한 내용은 [유형 시스템(요청 매핑)](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request)을 참조하세요. 이 값은 필수입니다.  
** `attributeValues` **  
DynamoDB에 저장할 항목의 나머지 속성. '입력된 값'을 지정하는 방법에 대한 자세한 내용은 [유형 시스템(요청 매핑)](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request)을 참조하세요. 이 필드는 선택 사항입니다.  
** `condition` **  
DynamoDB에 이미 있는 객체의 상태를 기반으로 요청의 성공 여부를 결정하는 조건. 조건을 지정하지 않으면 `PutItem` 요청이 해당 항목에 대한 기존 입력을 덮어씁니다. 조건 검사에 실패할 경우 기존 항목을 다시 가져올지 여부를 지정할 수 있습니다. 트랜잭션 조건에 대한 자세한 내용은 [트랜잭션 조건 표현식](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-transaction-condition-expressions)을 참조하세요. 이 값은 선택 사항입니다.
`UpdateItem`의 필드는 다음과 같이 정의됩니다.    
** `table` **  
업데이트할 DynamoDB 테이블입니다. 이 값은 테이블 이름의 문자열입니다. 이 `table` 값은 필수입니다.  
** `operation` **  
수행할 DynamoDB 작업입니다. `UpdateItem` DynamoDB 작업을 수행하려면 이 값을 `UpdateItem`으로 설정해야 합니다. 이 값은 필수입니다.  
** `key` **  
업데이트할 항목의 프라이머리 키를 나타내는 DynamoDB 키입니다. DynamoDB 항목은 테이블 구조에 따라 단일 해시 키 또는 해시 키와 정렬 키를 가질 수 있습니다. '입력된 값'을 지정하는 방법에 대한 자세한 내용은 [유형 시스템(요청 매핑)](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request)을 참조하세요. 이 값은 필수입니다.  
** `update` **  
`update` 섹션에서는 DynamoDB의 항목 업데이트 방법을 설명하는 업데이트 표현식을 지정합니다. 업데이트 표현식을 작성하는 방법에 대한 자세한 내용은 [DynamoDB UpdateExpressions 문서](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html)를 참조하십시오. 이 섹션은 필수입니다.  
** `condition` **  
DynamoDB에 이미 있는 객체의 상태를 기반으로 요청의 성공 여부를 결정하는 조건. 조건을 지정하지 않으면 `UpdateItem` 요청이 현재 상태와 상관 없이 기존 항목을 업데이트합니다. 조건 검사에 실패할 경우 기존 항목을 다시 가져올지 여부를 지정할 수 있습니다. 트랜잭션 조건에 대한 자세한 내용은 [트랜잭션 조건 표현식](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-transaction-condition-expressions)을 참조하세요. 이 값은 선택 사항입니다.
`DeleteItem`의 필드는 다음과 같이 정의됩니다.    
** `table` **  
항목을 삭제할 DynamoDB 테이블입니다. 이 값은 테이블 이름의 문자열입니다. 이 `table` 값은 필수입니다.  
** `operation` **  
수행할 DynamoDB 작업입니다. `DeleteItem` DynamoDB 작업을 수행하려면 이 값을 `DeleteItem`으로 설정해야 합니다. 이 값은 필수입니다.  
** `key` **  
삭제할 항목의 프라이머리 키를 나타내는 DynamoDB 키입니다. DynamoDB 항목은 테이블 구조에 따라 단일 해시 키 또는 해시 키와 정렬 키를 가질 수 있습니다. '입력된 값'을 지정하는 방법에 대한 자세한 내용은 [유형 시스템(요청 매핑)](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request)을 참조하세요. 이 값은 필수입니다.  
** `condition` **  
DynamoDB에 이미 있는 객체의 상태를 기반으로 요청의 성공 여부를 결정하는 조건. 조건을 지정하지 않으면 `DeleteItem` 요청이 현재 상태와 상관 없이 항목을 삭제합니다. 조건 검사에 실패할 경우 기존 항목을 다시 가져올지 여부를 지정할 수 있습니다. 트랜잭션 조건에 대한 자세한 내용은 [트랜잭션 조건 표현식](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-transaction-condition-expressions)을 참조하세요. 이 값은 선택 사항입니다.
`ConditionCheck`의 필드는 다음과 같이 정의됩니다.    
** `table` **  
조건을 검사할 DynamoDB 테이블입니다. 이 값은 테이블 이름의 문자열입니다. 이 `table` 값은 필수입니다.  
** `operation` **  
수행할 DynamoDB 작업입니다. `ConditionCheck` DynamoDB 작업을 수행하려면 이 값을 `ConditionCheck`으로 설정해야 합니다. 이 값은 필수입니다.  
** `key` **  
조건을 확인할 항목의 프라이머리 키를 나타내는 DynamoDB 키입니다. DynamoDB 항목은 테이블 구조에 따라 단일 해시 키 또는 해시 키와 정렬 키를 가질 수 있습니다. '입력된 값'을 지정하는 방법에 대한 자세한 내용은 [유형 시스템(요청 매핑)](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request)을 참조하세요. 이 값은 필수입니다.  
** `condition` **  
DynamoDB에 이미 있는 객체의 상태를 기반으로 요청의 성공 여부를 결정하는 조건. 조건 검사에 실패할 경우 기존 항목을 다시 가져올지 여부를 지정할 수 있습니다. 트랜잭션 조건에 대한 자세한 내용은 [트랜잭션 조건 표현식](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-transaction-condition-expressions)을 참조하세요. 이 값은 필수입니다.

기억해야 할 내용:
+ 성공할 경우 요청 항목의 키만 응답에 반환됩니다. 키 순서는 요청 항목의 순서와 동일합니다.
+ 트랜잭션은 전부 또는 전무 방식으로 수행됩니다. 요청 항목에 오류가 발생하면 전체 트랜잭션이 수행되지 않고 오류 세부 정보가 반환됩니다.
+ 두 개의 요청 항목이 동일한 항목을 대상으로 할 수 없습니다. 그렇지 않으면 *TransactionCanceledException* 오류가 발생합니다.
+ 트랜잭션의 오류가 *TransactionCanceledException*인 경우 `cancellationReasons` 블록이 채워집니다. 요청 항목의 조건 검사에 실패한 **동시에** `returnValuesOnConditionCheckFailure`를 `false`로 지정하지 않은 경우, 테이블에 있는 항목이 검색되고 `item`에서 `cancellationReasons` 블록의 해당 위치에 저장됩니다.
+  `TransactWriteItems`는 100개의 요청 항목으로 제한됩니다.
+ 충돌 감지와 함께 사용할 때 이 작업은 지원되지 **않습니다**. 두 가지를 동시에 사용하면 오류가 발생할 수 있습니다.

다음은 함수 요청 핸들러 예시입니다.

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

export function request(ctx) {
  const { authorId, postId, title, description, oldTitle, authorName } = ctx.args;
  return {
    operation: 'TransactWriteItems',
    transactItems: [
      {
        table: 'posts',
        operation: 'PutItem',
        key: util.dynamodb.toMapValues({ postId }),
        attributeValues: util.dynamodb.toMapValues({ title, description }),
        condition: util.transform.toDynamoDBConditionExpression({
          title: { eq: oldTitle },
        }),
      },
      {
        table: 'authors',
        operation: 'UpdateItem',
        key: util.dynamodb.toMapValues({ authorId }),
        update: {
          expression: 'SET authorName = :name',
          expressionValues: util.dynamodb.toMapValues({ ':name': authorName }),
        },
      },
    ],
  };
}
```

트랜잭션이 성공하면 `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`에 있습니다.

# 형식 시스템(요청 매핑)
<a name="js-aws-appsync-resolver-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="js-aws-appsync-resolver-reference-dynamodb-typed-values-responses"></a>

DynamoDB로부터 응답을 수신하면 AWS AppSync는 자동으로 응답을 GraphQL 및 JSON 기본 유형으로 변환합니다. DynamoDB의 각 속성은 디코딩되어 응답 핸들러의 컨텍스트에서 반환됩니다.

예를 들어 DynamoDB에서 다음을 반환한 경우:

```
{
    "id" : { "S" : "1234" },
    "name" : { "S" : "Nadia" },
    "age" : { "N" : 25 }
}
```

파이프라인 해석기에서 결과가 반환되면 AWS AppSync는 결과를 다음과 같이 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="js-aws-appsync-resolver-reference-dynamodb-filter"></a>

`Query` 및 `Scan` 작업을 사용하여 DynamoDB에서 객체를 쿼리하는 경우, 결과를 평가해 원하는 값만 반환하는 `filter`를 선택적으로 지정할 수 있습니다.

`Query` 또는 `Scan` 요청의 필터 속성은 다음과 같은 구조를 갖습니다.

```
type DynamoDBExpression = {
  expression: string;
  expressionNames?: { [key: string]: string};
  expressionValues?: { [key: string]: any};
};
```

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

** `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 자리 표시자에 해당하고 값은 입력된 값이어야 합니다. '입력된 값'을 지정하는 방법에 대한 자세한 내용은 [유형 시스템(요청 매핑)](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request)을 참조하세요. 입력된 값은 지정되어 있어야 합니다. 이 필드는 선택 사항으로, `expression`에 사용된 표현식 속성인 value 자리 표시자의 대체 항목으로만 채워져야 합니다.

## 예제
<a name="js-id18"></a>

다음 예제는 요청의 필터 섹션으로, 여기서 DynamoDB에서 가져온 항목은 제목이 `title` 인수로 시작되는 경우에만 반환됩니다.

여기서는 `util.transform.toDynamoDBFilterExpression`을 사용하여 객체에서 필터를 자동으로 생성합니다.

```
const filter = util.transform.toDynamoDBFilterExpression({
  title: { beginsWith: 'far away' },
});

const request = {};
request.filter = JSON.parse(filter);
```

그러면 다음과 같은 필터가 생성됩니다.

```
{
  "filter": {
    "expression": "(begins_with(#title,:title_beginsWith))",
    "expressionNames": { "#title": "title" },
    "expressionValues": {
      ":title_beginsWith": { "S": "far away" }
    }
  }
}
```

# 조건 표현식
<a name="js-aws-appsync-resolver-reference-dynamodb-condition-expressions"></a>

DynamoDB에서 `PutItem`, `UpdateItem` 및 `DeleteItem` DynamoDB 작업을 사용하여 객체를 변경하는 경우, 작업을 수행하기 전에 DynamoDB에 이미 있는 객체의 상태를 기준으로 요청에 성공할지 여부를 제어하는 조건 표현식을 선택적으로 지정할 수 있습니다.

 AWS AppSync DynamoDB 함수를 사용하면 `PutItem`, `UpdateItem`및 `DeleteItem` 요청 객체에 조건 표현식을 지정할 수 있으며, 조건이 실패하고 객체가 업데이트되지 않은 경우 따라야 할 전략도 지정할 수 있습니다.

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

다음 `PutItem` 요청 객체에는 조건식은 포함되어 있지 않습니다. 따라서 키가 같은 항목이 이미 존재하더라도 DynamoDB에 항목을 저장하기 때문에 기존 항목을 덮어 씁니다.

```
import { util } from '@aws-appsync/utils';
export function request(ctx) {
  const { foo, bar, ...values} = ctx.args
  return {
    operation: 'PutItem',
    key: util.dynamodb.toMapValues({foo, bar}),
    attributeValues: util.dynamodb.toMapValues(values),
  };
}
```

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

다음 `PutItem` 객체에는 동일한 키를 가진 항목이 DynamoDB에 *없는* 경우에만 작업을 성공시킬 수 있는 조건 표현식이 있습니다.

```
import { util } from '@aws-appsync/utils';
export function request(ctx) {
  const { foo, bar, ...values} = ctx.args
  return {
    operation: 'PutItem',
    key: util.dynamodb.toMapValues({foo, bar}),
    attributeValues: util.dynamodb.toMapValues(values),
    condition: { expression: "attribute_not_exists(id)" }
  };
}
```

기본적으로 조건 확인에 실패하면 AWS AppSync DynamoDB 함수는 변형에 대한 오류를 제공합니다.

그러나 AWS AppSync DynamoDB 함수는 개발자가 몇 가지 일반적인 엣지 사례를 처리하는 데 도움이 되는 몇 가지 추가 기능을 제공합니다.
+  AWS AppSync DynamoDB 함수가 DynamoDB의 현재 값이 원하는 결과와 일치하는지 확인할 수 있는 경우 작업을 성공한 것처럼 취급합니다.
+ 오류를 반환하는 대신 사용자 지정 Lambda 함수를 호출하도록 함수를 구성하여 AWS AppSync DynamoDB 함수가 오류를 처리하는 방법을 결정할 수 있습니다.

이러한 내용은 [조건 확인 실패 처리](#condition-check) 단원에 자세히 설명되어 있습니다.

DynamoDB 조건 표현식에 대한 자세한 내용은 [DynamoDB ConditionExpressions 문서](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ConditionExpressions.html)를 참조하세요.

## 조건 지정
<a name="js-aws-appsync-resolver-reference-dynamodb-condition-specification"></a>

`PutItem`, `UpdateItem` 및 `DeleteItem` 요청 객체 모두에서 선택적 `condition` 섹션을 지정할 수 있습니다. 이 섹션을 지정하지 않으면 조건 검사가 수행되지 않습니다. 지정한 경우, 해당 조건을 충족해야 작업이 성공합니다.

`condition` 섹션의 구조는 다음과 같습니다.

```
type ConditionCheckExpression = {
  expression: string;
  expressionNames?: { [key: string]: string};
  expressionValues?: { [key: string]: any};
  equalsIgnore?: string[];
  consistentRead?: boolean;
  conditionalCheckFailedHandler?: {
    strategy: 'Custom' | 'Reject';
    lambdaArn?: string;
  };
};
```

조건을 지정하는 필드는 다음과 같습니다.

** `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 자리 표시자에 해당하고 값은 입력된 값이어야 합니다. '입력된 값'을 지정하는 방법에 대한 자세한 내용은 [유형 시스템(요청 매핑)](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request)을 참조하세요. 입력된 값은 지정되어 있어야 합니다. 이 필드는 선택 사항으로, 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`으로 설정한 경우에만 지정해야 합니다. 이 기능을 사용하는 방법에 대한 자세한 내용은 [조건 검사 실패 처리](#condition-check)를 참조하세요.

## 조건 검사 실패 처리
<a name="js-aws-appsync-resolver-reference-dynamodb-condition-handling"></a>

조건 확인에 실패하면 AWS AppSync DynamoDB 함수는 `util.appendError` 유틸리티를 사용하여 변형에 대한 오류와 객체의 현재 값을 전달할 수 있습니다. 그러나 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="js-checking-for-the-desired-result"></a>

조건 확인에 실패하면 AWS AppSync DynamoDB 함수가 `GetItem` DynamoDB 요청을 수행하여 DynamoDB에서 항목의 현재 값을 가져옵니다. 기본적으로 이 해석기는 강력히 일관된 읽기를 사용하지만, `condition` 블록의 `consistentRead` 필드를 사용하여 예상 결과와 비교하도록 구성할 수 있습니다.
+ `PutItem` 작업의 경우 AWS AppSync DynamoDB 함수는 비교`equalsIgnore`에서에 나열된 속성을 제외하고 현재 값을 쓰려고 시도한 값과 비교합니다. 항목이 동일한 경우 해당 작업을 성공한 작업으로 간주하고 DynamoDB에서 가져온 항목을 반환합니다. 그렇지 않으면 구성된 전략을 따릅니다.

  예를 들어, `PutItem` 요청 함수가 다음과 같은 경우:

  ```
  import { util } from '@aws-appsync/utils';
  export function request(ctx) {
    const { id, name, version} = ctx.args
    return {
      operation: 'PutItem',
      key: util.dynamodb.toMapValues({foo, bar}),
      attributeValues: util.dynamodb.toMapValues({ name, version: version+1 }),
      condition: { 
        expression: "version = :expectedVersion",
        expressionValues: util.dynamodb.toMapValues({':expectedVersion': version}),
        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="js-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 }
}
```

그리고 함수 응답 핸들러는 다음과 같습니다.

```
import { util } from '@aws-appsync/utils';
export function response(ctx) {
  const { version, ...values } = ctx.result;
  const result = { ...values, theVersion: version };
  if (ctx.error) {
    if (error) {
      return util.appendError(error.message, error.type, result, null);
    }
  }
  return result
}
```

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="js-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](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-dynamodb.html#aws-appsync-resolver-mapping-template-reference-dynamodb-putitem)을 참조하십시오.

  ```
  {
      "attributeValues": { ... },
      "condition": {
          "equalsIgnore" = [ ... ],
          "consistentRead" = true
      }
  }
  ```

  `UpdateItem`의 경우 `retryMapping` 섹션의 구조는 다음과 같습니다. `update` 섹션에 대한 설명은 [UpdateItem](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-dynamodb.html#aws-appsync-resolver-mapping-template-reference-dynamodb-updateitem)을 참조하십시오.

  ```
  {
      "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="js-aws-appsync-resolver-reference-dynamodb-transaction-condition-expressions"></a>

트랜잭션 조건 표현식은 `TransactWriteItems`에서 네 가지 작업 유형 모두(`PutItem`, `DeleteItem`, `UpdateItem`, `ConditionCheck`)의 요청에 사용할 수 있습니다.

`PutItem`, `DeleteItem`, `UpdateItem`의 경우 트랜잭션 조건 표현식은 선택 사항입니다. `ConditionCheck`의 경우 트랜잭션 조건 표현식이 필수입니다.

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

다음 트랜잭션 `DeleteItem` 함수 요청 핸들러에는 조건 표현식이 없습니다. 따라서 DynamoDB에서 항목을 삭제합니다.

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

export function request(ctx) {
  const { postId } = ctx.args;
  return {
    operation: 'TransactWriteItems',
    transactItems: [
      {
        table: 'posts',
        operation: 'DeleteItem',
        key: util.dynamodb.toMapValues({ postId }),
      }
    ],
  };
}
```

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

다음 트랜잭션 `DeleteItem` 함수 요청 핸들러에는 해당 게시물의 작성자가 특정 이름과 같은 경우에만 작업이 성공할 수 있는 트랜잭션 조건식이 있습니다.

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

export function request(ctx) {
  const { postId, authorName} = ctx.args;
  return {
    operation: 'TransactWriteItems',
    transactItems: [
      {
        table: 'posts',
        operation: 'DeleteItem',
        key: util.dynamodb.toMapValues({ postId }),
        condition: util.transform.toDynamoDBConditionExpression({
          authorName: { eq: authorName },
        }),
      }
    ],
  };
}
```

조건 검사에 실패하면 `TransactionCanceledException`이 발생하고, `ctx.result.cancellationReasons`에 오류 세부 정보가 반환됩니다. 기본적으로, 조건 검사가 실패하게 된 원인인 DynamoDB의 이전 항목이 `ctx.result.cancellationReasons`에 반환됩니다.

## 조건 지정
<a name="js-id24"></a>

`PutItem`, `UpdateItem` 및 `DeleteItem` 요청 객체 모두에서 선택적 `condition` 섹션을 지정할 수 있습니다. 이 섹션을 지정하지 않으면 조건 검사가 수행되지 않습니다. 지정한 경우, 해당 조건을 충족해야 작업이 성공합니다. `ConditionCheck`에는 지정할 `condition` 섹션이 있어야 합니다. 전체 트랜잭션이 성공하려면 조건이 true여야 합니다.

`condition` 섹션의 구조는 다음과 같습니다.

```
type TransactConditionCheckExpression = {
  expression: string;
  expressionNames?: { [key: string]: string };
  expressionValues?: { [key: string]: string };
  returnValuesOnConditionCheckFailure: boolean;
};
```

조건을 지정하는 필드는 다음과 같습니다.

** `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 자리 표시자에 해당하고 값은 입력된 값이어야 합니다. '입력된 값'을 지정하는 방법에 대한 자세한 내용은 [유형 시스템(요청 매핑)](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request)을 참조하세요. 입력된 값은 지정되어 있어야 합니다. 이 필드는 선택 사항으로, expression에 사용된 표현식 속성인 value 자리 표시자의 대체 항목으로만 채워져야 합니다.

** `returnValuesOnConditionCheckFailure` **  
조건 검사에 실패할 경우 DynamoDB의 항목을 다시 가져올지 여부를 지정합니다. 가져온 항목은 `ctx.result.cancellationReasons[<index>].item`에 있습니다. 여기서 `<index>`는 조건 검사에 실패한 요청 항목의 인덱스입니다. 기본값은 true입니다.

# 프로젝션
<a name="js-aws-appsync-resolver-reference-dynamodb-projections"></a>

`GetItem`, `Scan`, `Query`, `BatchGetItem` 및 `TransactGetItems` 작업을 사용하여 DynamoDB에서 객체를 읽을 때 원하는 속성을 식별하는 프로젝션을 선택적으로 지정할 수 있습니다. 프로젝션 속성의 구조는 필터와 비슷하며 다음과 같습니다.

```
type DynamoDBExpression = {
  expression: string;
  expressionNames?: { [key: string]: string}
};
```

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

** `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="js-id22"></a>

다음 예는 DynamoDB에서 `author` 및 `id` 속성만 반환되는 JavaScript 함수의 프로젝션 섹션입니다.

```
projection : {
    expression : "#author, id",
    expressionNames : {
        "#author" : "author"
    }
}
```

**작은 정보**  
[selectionSetList](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference-js.html#aws-appsync-resolver-context-reference-info-js)를 사용하여 GraphQL 요청 설정에 액세스할 수 있습니다. 이 필드를 사용하면 요구 사항에 따라 프로젝션 표현식을 동적으로 프레이밍할 수 있습니다.

**참고**  
`Query` 및 `Scan` 작업과 함께 프로젝션 표현식을 사용하는 경우 `select`의 값은 반드시 `SPECIFIC_ATTRIBUTES`이어야 합니다. 자세한 내용은 [DynamoDB 설명서](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html#DDB-Query-request-Select)를 참조하세요.

# OpenSearch용AWS AppSync JavaScript 해석기 함수 참조
<a name="resolver-reference-elasticsearch-js"></a>

Amazon OpenSearch Service용 AWS AppSync 해석기를 사용하면 GraphQL을 사용하여 계정의 기존 OpenSearch Service 도메인에 데이터를 저장하고 검색할 수 있습니다. 이 해석기는 수신되는 GraphQL 요청을 OpenSearch Service 요청으로 매핑한 다음 OpenSearch Service 응답을 다시 GraphQL로 매핑하도록 하여 작동합니다. 이 섹션에서는 지원되는 OpenSearch Service 작업에 대한 요청 및 응답 핸들러를 설명합니다.

## 요청
<a name="request-js"></a>

대부분의 OpenSearch Service 요청 객체에는 몇 부분만 변경되는 공통 구조가 있습니다. 다음 예제는 문서가 `post` 유형이고 `id`에서 인덱싱되는 OpenSearch Service 도메인에 대해 검색을 실행합니다. 검색 파라미터는 `body` 섹션에 정의되어 있고, 공통 쿼리 절은 대부분 `query` 필드에서 정의합니다. 이 예에서는 문서의 `"Nadia"` 필드에서 `"Bailey"`, `author` 또는 둘 다가 포함된 문서를 검색합니다.

```
export function request(ctx) {
  return {
    operation: 'GET',
    path: '/id/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에서는 두 가지 공통 응답 패턴이 사용됩니다.

 **결과 목록** 

```
export function response(ctx) {
  const entries = [];
  for (const entry of ctx.result.hits.hits) {
    entries.push(entry['_source']);
  }
  return entries;
}
```

 **개별 항목** 

```
export function response(ctx) {
  return ctx.result['_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/type"

"path" : "/indexname/type/_search"
```

요청 핸들러가 평가되면 이 경로는 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**.

‘시애틀’과 일치하는 도시가 포함된 모든 문서를 반환합니다.

```
export function request(ctx) {
  return {
    operation: 'GET',
    path: '/id/post/_search',
    params: {
      headers: {},
      queryString: {},
      body: { from: 0, size: 50, query: { match: { city: 'seattle' } } },
    },
  };
}
```

 **예제 2**.

도시 또는 주가 ‘워싱턴’과 일치하는 모든 문서를 반환합니다.

```
export function request(ctx) {
  return {
    operation: 'GET',
    path: '/id/post/_search',
    params: {
      headers: {},
      queryString: {},
      body: {
        from: 0,
        size: 50,
        query: {
          multi_match: { query: 'washington', fields: ['city', 'state'] },
        },
      },
    },
  };
}
```

## 변수 전달
<a name="passing-variables"></a>

**참고**  
이는 요청 핸들러에만 적용됩니다.

요청 핸들러에서 평가의 일부로 변수를 전달할 수도 있습니다. 예를 들어, 다음과 같은 GraphQL 쿼리가 있다고 가정해 보겠습니다.

```
query {
    searchForState(state: "washington"){
        ...
    }
}
```

함수 요청 핸들러는 다음과 같을 수 있습니다.

```
export function request(ctx) {
  return {
    operation: 'GET',
    path: '/id/post/_search',
    params: {
      headers: {},
      queryString: {},
      body: {
        from: 0,
        size: 50,
        query: {
          multi_match: { query: ctx.args.state, fields: ['city', 'state'] },
        },
      },
    },
  };
}
```

# Lambda용AWS AppSync JavaScript 해석기 함수 참조
<a name="resolver-reference-lambda-js"></a>

 AWS AppSync 함수 및 해석기를 사용하여 계정에 있는 Lambda 함수를 호출할 수 있습니다. 클라이언트에 반환하기 전에 요청 페이로드와 Lambda 함수의 응답을 구성할 수 있습니다. 요청 객체에서 수행할 작업 유형을 지정할 수도 있습니다. 이 단원에서는 지원되는 Lambda 작업에 대한 요청에 대해 설명합니다.

## 요청 객체
<a name="request-object-js"></a>

Lambda 요청 객체는 Lambda 함수와 관련된 필드를 처리합니다.

```
export type LambdaRequest = {
  operation: 'Invoke' | 'BatchInvoke';
  invocationType?: 'RequestResponse' | 'Event';
  payload: unknown;
};
```

다음은 페이로드 데이터가 컨텍스트의 인수와 함께 GraphQL 스키마의 `getPost` 필드인 `invoke` 작업을 사용하는 예제입니다.

```
export function request(ctx) {
  return {
    operation: 'Invoke',
    payload: { field: 'getPost', arguments: ctx.args },
  };
}
```

전체 매핑 문서는 Lambda 함수에 입력으로 전달되므로 앞의 예제는 다음과 같습니다.

```
{
  "operation": "Invoke",
  "payload": {
    "field": "getPost",
    "arguments": {
      "input": {
        "id": "postId1",
      }
    }
  }
}
```

### 연산
<a name="operation-js"></a>

Lambda 데이터 소스를 사용하면 `operation` 필드에서 `Invoke` 및 `BatchInvoke`의 두 가지 작업을 정의할 수 있습니다. `Invoke` 작업을 통해 AWS AppSync는 모든 GraphQL 필드 해석기에 대해 Lambda 함수를 호출하도록 알 수 있습니다.는 현재 GraphQL 필드에 대한 요청을 일괄 처리하도록 AWS AppSync에 `BatchInvoke` 지시합니다. `operation` 필드는 필수 사항입니다.

`Invoke`의 경우 해석된 요청은 Lambda 함수의 입력 페이로드와 일치합니다. 위의 예를 수정해 보겠습니다.

```
export function request(ctx) {
  return {
    operation: 'Invoke',
    payload: { field: 'getPost', arguments: ctx.args },
  };
}
```

해결 후 Lambda 함수로 전달되며 다음과 같을 수 있습니다.

```
{
  "operation": "Invoke",
  "payload": {
    "arguments": {
      "id": "postId1"
    }
  }
}
```

`BatchInvoke`의 경우 배치의 모든 필드 해석기에 요청이 적용됩니다. 간결성을 위해 AWS AppSync는 모든 요청 `payload` 값을 요청 객체와 일치하는 단일 객체 아래의 목록에 병합합니다. 다음 예제 요청 핸들러는 병합을 보여줍니다.

```
export function request(ctx) {
  return {
    operation: 'Invoke',
    payload: ctx,
  };
}
```

이 요청은 평가되어 다음 매핑 문서로 해결됩니다.

```
{
  "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-js"></a>

`payload` 필드는 데이터를 Lambda 함수로 전달하는 데 사용되는 컨테이너입니다. `operation` 필드가 `BatchInvoke`로 설정된 경우 AWS AppSync는 기존 `payload` 값을 목록으로 래핑합니다. `payload` 필드는 선택 사항입니다.

### 간접 호출 유형
<a name="async-invocation-type-js"></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 함수의 입력 페이로드와 일치합니다. 위의 예를 수정해 보겠습니다.

```
export function request(ctx) {
  return {
    operation: 'Invoke',
    invocationType: 'Event',
    payload: { field: 'getPost', arguments: ctx.args },
  };
}
```

해결 후 Lambda 함수로 전달되며 다음과 같을 수 있습니다.

```
{
  "operation": "Invoke",
  "invocationType": "Event",
  "payload": {
    "arguments": {
      "id": "postId1"
    }
  }
}
```

`Event` 호출 유형 필드와 함께 `BatchInvoke` 작업을 사용하는 경우 AWS AppSync는 위에서 언급한 것과 동일한 방식으로 필드 해석기를 병합하고 요청은 값 목록이 `payload`인 비동기 이벤트로 Lambda 함수에 전달됩니다. `Event` 간접 호출 유형 요청의 응답은 응답 핸들러 없이 `null` 값을 생성합니다.

```
{
  "data": {
    "field": null
  }
}
```

캐시 적중이 발생하면 Lambda로 전송되지 않으므로 `Event` 간접 호출 유형 해석기에 대한 해석기 캐싱을 비활성화하는 것이 좋습니다.

## 응답 객체
<a name="response-object-js"></a>

다른 데이터 소스와 마찬가지로 Lambda 함수는 GraphQL 유형으로 변환해야 하는 응답을 AWS AppSync에 전송합니다. Lambda 함수의 결과는 `context` 결과 속성(`context.result`)에 포함됩니다.

Lambda 함수 응답의 모양이 GraphQL 유형의 모양과 일치할 경우 다음 함수 응답 핸들러를 사용하여 응답을 전달할 수 있습니다.

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

응답 객체에 적용되는 필수 필드 또는 모양 제한이 없습니다. 하지만 GraphQL은 강력한 형식이므로 해석된 응답이 필요한 GraphQL 유형과 일치해야 합니다.

## Lambda 함수 일괄 처리 응답
<a name="aws-appsync-resolver-reference-lambda-batched-response-js"></a>

`operation` 필드가 로 설정된 경우`BatchInvoke` AWS AppSync는 Lambda 함수에서 항목 목록을 다시 예상합니다. AWS AppSync가 각 결과를 원래 요청 항목에 다시 매핑하려면 응답 목록의 크기와 순서가 일치해야 합니다. 응답 목록에 `null` 항목이 있어도 유효합니다. `ctx.result`가 적절히 *null*로 설정됩니다.

# EventBridge 데이터 소스에 대한AWS AppSync JavaScript 해석기 함수 참조
<a name="resolver-reference-eventbridge-js"></a>

EventBridge 데이터 소스와 함께 사용되는 AWS AppSync 해석기 함수 요청 및 응답을 사용하면 사용자 지정 이벤트를 Amazon EventBridge 버스로 전송할 수 있습니다.

## 요청
<a name="request-js"></a>

요청 핸들러를 사용하면 여러 사용자 지정 이벤트를 EventBridge 이벤트 버스로 보낼 수 있습니다.

```
export function request(ctx) {
  return {
    "operation" : "PutEvents",
    "events" : [{}]
  }
}
```

EventBridge `PutEvents` 요청에는 다음과 같은 유형 정의가 있습니다.

```
type PutEventsRequest = {
  operation: 'PutEvents'
  events: {
    source: string
    detail: { [key: string]: any }
    detailType: string
    resources?: string[]
    time?: string // RFC3339 Timestamp format
  }[]
}
```

## 응답
<a name="response-js"></a>

`PutEvents` 작업이 성공하면 EventBridge의 응답이 `ctx.result`에 포함됩니다.

```
export function response(ctx) {
  if(ctx.error)
    util.error(ctx.error.message, ctx.error.type, ctx.result)
  else
    return ctx.result
}
```

`InternalExceptions` 또는 `Timeouts`와 같은 `PutEvents` 작업을 수행하는 동안 발생하는 오류는 `ctx.error`에 표시됩니다. EventBridge의 일반적인 오류 목록은 [EventBridge 일반 오류 참조](https://docs.aws.amazon.com/eventbridge/latest/APIReference/CommonErrors.html)를 참조하세요.

`result`에는 다음과 같은 유형 정의가 있습니다.

```
type PutEventsResult = {
  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` 객체에는 다음의 필드가 있습니다.
  + `"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 JavaScript 해석기 함수 참조
<a name="resolver-reference-none-js"></a>

데이터 소스가 *없음*인 AWS AppSync 해석기 함수 요청 및 응답을 사용하면 AWS AppSync 로컬 작업에 대한 요청을 구성할 수 있습니다.

## 요청
<a name="request-js"></a>

요청 핸들러는 단순하며 `payload` 필드를 통해 가능한 많은 컨텍스트 정보를 전달할 수 있습니다.

```
type NONERequest = {
  payload: any;
};
```

다음은 필드 인수가 페이로드에 전달되는 예시입니다.

```
export function request(ctx) {
  return {
    payload: context.args
  };
}
```

`payload` 필드 값은 함수 응답 핸들러로 전달되며 `context.result`에서 사용할 수 있습니다.

## Payload
<a name="payload-js"></a>

`payload` 필드는 모든 데이터를 전달한 다음 함수 응답 핸들러에서 사용할 수 있는 컨테이너입니다.

 `payload` 필드는 선택 사항입니다.

## 응답
<a name="response-js"></a>

데이터 소스가 없으므로 `payload` 필드의 값이 함수 응답 핸들러로 전달되고 `context.result` 속성에서 설정됩니다.

`payload` 필드 값의 모양이 GraphQL 유형의 모양과 정확히 일치하는 경우 다음 응답 핸들러를 사용하여 응답을 전달할 수 있습니다.

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

반환 응답에 적용되는 필수 필드 또는 모양 제한이 없습니다. 하지만 GraphQL은 강력한 형식이므로 해석된 응답이 필요한 GraphQL 유형과 일치해야 합니다.

# HTTP에 대한AWS AppSync JavaScript 해석기 함수 참조
<a name="resolver-reference-http-js"></a>

 AWS AppSync HTTP 해석기 함수를 사용하면 AWS AppSync에서 모든 HTTP 엔드포인트로 요청을 보내고 HTTP 엔드포인트에서 다시 AWS AppSync로 응답을 보낼 수 있습니다. 요청 핸들러를 사용하여 AWS AppSync에 호출할 작업의 특성에 대한 힌트를 제공할 수 있습니다. 이 단원에서는 지원되는 HTTP 해석기에 대한 다양한 구성에 대해 설명합니다.

## 요청
<a name="request-js"></a>

```
type HTTPRequest = {
  method: 'PUT' | 'POST' | 'GET' | 'DELETE' | 'PATCH';
  params?: {
    query?: { [key: string]: any };
    headers?: { [key: string]: string };
    body?: any;
  };
  resourcePath: string;
};
```

다음 코드 조각은 `text/plain` 본문을 포함한 HTTP POST 요청의 예입니다.

```
export function request(ctx) {
  return {
    method: 'POST',
    params: {
      headers: { 'Content-Type': 'text/plain' },
      body: 'this is an example of text body',
    },
    resourcePath: '/',
  };
}
```

## 방법
<a name="method-js"></a>

**참고**  
이는 요청 핸들러에만 적용됩니다.

 AWS AppSync가 HTTP 엔드포인트로 전송하는 HTTP 메서드 또는 동사(GET, POST, PUT, PATCH 또는 DELETE).

```
"method": "PUT"
```

## ResourcePath
<a name="resourcepath-js"></a>

 

**참고**  
이는 요청 핸들러에만 적용됩니다.

액세스하고자 하는 리소스 경로입니다. 리소스 경로는 HTTP 데이터 소스의 엔드포인트와 함께 AWS AppSync 서비스가 요청하는 URL을 형성합니다.

```
"resourcePath": "/v1/users"
```

요청이 평가되면 이 경로는 HTTP 엔드포인트를 포함해 HTTP 요청의 일부로 전송됩니다. 예를 들어, 이전 예제는 다음과 같이 변환될 수 있습니다.

```
PUT <endpoint>/v1/users
```

## 파라미터 필드
<a name="params-field-js"></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-js"></a>

[여기](https://docs.aws.amazon.com/appsync/latest/devguide/tutorial-http-resolvers-js.html)에서 예시를 확인하세요.

# Amazon RDS에 대한AWS AppSync JavaScript 해석기 함수 참조
<a name="resolver-reference-rds-js"></a>

 AWS AppSync RDS 함수 및 해석기를 사용하면 개발자가 RDS 데이터 API를 사용하여 Amazon Aurora 클러스터 데이터베이스에 SQL 쿼리를 보내고 이러한 쿼리의 결과를 다시 가져올 수 있습니다. AWS AppSync의 `rds` 모듈에 `sql`태그가 지정된 템플릿을 사용하거나 `rds` 모듈의 `select`, `update`, 및 `remove`헬퍼 함수를 사용하여 데이터 API로 전송되는 SQL 문을 작성할 수 있습니다. `insert`는 RDS Data Service의 [https://docs.aws.amazon.com//rdsdataservice/latest/APIReference/API_ExecuteStatement.html](https://docs.aws.amazon.com//rdsdataservice/latest/APIReference/API_ExecuteStatement.html) 작업을 AWS AppSync 사용하여 데이터베이스에 대해 SQL 문을 실행합니다.

**주제**
+ [SQL 태그가 지정된 템플릿](#sql-tagged-templates)
+ [문 생성](#creating-statements)
+ [데이터 불러오기](#retrieving-data)
+ [유틸리티 함수](#utility-functions)
+ [SQL Select](#utility-functions-select)
+ [SQL Insert](#utility-functions-insert)
+ [SQL Update](#utility-functions-update)
+ [SQL Delete](#utility-functions-delete)
+ [캐스팅](#casting)

## SQL 태그가 지정된 템플릿
<a name="sql-tagged-templates"></a>

AWS AppSync의 `sql` 태그가 지정된 템플릿을 사용하면 템플릿 표현식을 사용하여 런타임에 동적 값을 수신할 수 있는 정적 문을 생성할 수 있습니다.는 표현식 값에서 변수 맵을 AWS AppSync 빌드하여 Amazon Aurora Serverless Data API로 전송되는 [https://docs.aws.amazon.com//rdsdataservice/latest/APIReference/API_SqlParameter.html](https://docs.aws.amazon.com//rdsdataservice/latest/APIReference/API_SqlParameter.html) 쿼리를 구성합니다. 이 방법을 사용하면 런타임에 전달된 동적 값이 원래 문을 수정할 수 없으며, 이로 인해 의도하지 않은 실행이 발생할 수 있습니다. 모든 동적 값은 파라미터로 전달되며 원래 문을 수정할 수 없으며 데이터베이스에서 실행되지 않습니다. 이렇게 하면 쿼리가 SQL 삽입 공격에 덜 취약해집니다.

**참고**  
모든 경우에 SQL 문을 작성할 때는 입력으로 받는 데이터를 적절하게 처리하기 위한 보안 지침을 따라야 합니다.

**참고**  
`sql` 태그가 지정된 템플릿은 변수 값 전달만 지원합니다. 표현식을 사용하여 열 또는 테이블 이름을 동적으로 지정할 수 없습니다. 그러나 유틸리티 함수를 사용하여 다음 작업을 수행할 수도 있습니다.

다음 예시에서는 런타임 중 GraphQL 쿼리에 동적으로 설정된 `col` 인수 값을 기반으로 필터링하는 쿼리를 만듭니다. 해당 값은 태그 표현식을 사용해서만 문에 추가할 수 있습니다.

```
import { sql, createMySQLStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {
  const query = sql`
SELECT * FROM table 
WHERE column = ${ctx.args.col}`
  ;
  return createMySQLStatement(query);
}
```

변수 맵을 통해 모든 동적 값을 전달함으로써 데이터베이스 엔진을 사용하여 값을 안전하게 처리하고 삭제합니다.

## 문 생성
<a name="creating-statements"></a>

함수 및 해석기는 MySQL 및 PostgreSQL 데이터베이스와 상호 작용할 수 있습니다. 문을 작성할 때는 각각 `createMySQLStatement` 및 `createPgStatement`를 사용합니다. 예를 들어, `createMySQLStatement`는 MySQL 쿼리를 생성할 수 있습니다. 이러한 함수는 두 개까지의 문을 허용하므로 요청이 결과를 즉시 검색해야 할 때 유용합니다. MySQL으로 다음을 할 수 있습니다.

```
import { sql, createMySQLStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const { id, text } = ctx.args;
    const s1 = sql`insert into Post(id, text) values(${id}, ${text})`;
    const s2 = sql`select * from Post where id = ${id}`;
    return createMySQLStatement(s1, s2);
}
```

**참고**  
`createPgStatement` 및 `createMySQLStatement`는 `sql` 태그가 지정된 템플릿으로 작성된 문을 이스케이프 처리하거나 인용하지 않습니다.

## 데이터 불러오기
<a name="retrieving-data"></a>

실행된 SQL 문의 결과는 `context.result` 객체의 응답 핸들러에서 확인할 수 있습니다. 결과는 `ExecuteStatement` 작업의 [응답 요소](https://docs.aws.amazon.com//rdsdataservice/latest/APIReference/API_ExecuteStatement.html#API_ExecuteStatement_ResponseElements)가 포함된 JSON 문자열입니다. 파싱 시 결과는 다음 형태를 가집니다.

```
type SQLStatementResults = {
    sqlStatementResults: {
        records: any[];
        columnMetadata: any[];
        numberOfRecordsUpdated: number;
        generatedFields?: any[]
    }[]
}
```

반환된 행을 나타내는 JSON 객체 목록으로 `toJsonObject` 유틸리티를 사용하여 결과를 변환할 수 있습니다. 예제:

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

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

단, `toJsonObject`는 문 결과 배열을 반환합니다. 문 하나를 제공한 경우 배열 길이는 `1`입니다. 문 두 개를 제공한 경우 배열 길이는 `2`입니다. 배열의 각 결과에는 `0` 이상의 행이 포함됩니다. 결과 값이 유효하지 않거나 예상치 못한 경우 `toJsonObject`는 `null`을 반환합니다.

## 유틸리티 함수
<a name="utility-functions"></a>

 AWS AppSync RDS 모듈의 유틸리티 헬퍼를 사용하여 데이터베이스와 상호 작용할 수 있습니다.

### SQL Select
<a name="utility-functions-select"></a>

`select` 유틸리티는 관계형 데이터베이스를 쿼리하기 위한 `SELECT` 문을 생성합니다.

**기본 사용**

기본 형식에서 쿼리하려는 테이블을 지정할 수 있습니다.

```
import { select, createPgStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {

    // Generates statement: 
    // "SELECT * FROM "persons"
    return createPgStatement(select({table: 'persons'}));
}
```

테이블 식별자에 스키마를 지정할 수도 있습니다.

```
import { select, createPgStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {

    // Generates statement:
    // SELECT * FROM "private"."persons"
    return createPgStatement(select({table: 'private.persons'}));
}
```

**열 지정**

`columns` 속성을 사용하여 열을 지정할 수 있습니다. 값으로 설정되지 않은 경우 기본값은 `*`입니다.

```
export function request(ctx) {

    // Generates statement:
    // SELECT "id", "name"
    // FROM "persons"
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name']
    }));
}
```

열 테이블도 지정할 수 있습니다.

```
export function request(ctx) {

    // Generates statement: 
    // SELECT "id", "persons"."name"
    // FROM "persons"
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'persons.name']
    }));
}
```

**제한 및 오프셋**

쿼리에 `limit` 및 `offset`을 적용할 수 있습니다.

```
export function request(ctx) {

    // Generates statement: 
    // SELECT "id", "name"
    // FROM "persons"
    // LIMIT :limit
    // OFFSET :offset
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name'],
        limit: 10,
        offset: 40
    }));
}
```

**순서 기준**

`orderBy` 속성을 기준으로 결과를 정렬할 수 있습니다. 열을 지정하는 객체 배열과 선택적 `dir` 속성을 제공하십시오.

```
export function request(ctx) {

    // Generates statement: 
    // SELECT "id", "name" FROM "persons"
    // ORDER BY "name", "id" DESC
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name'],
        orderBy: [{column: 'name'}, {column: 'id', dir: 'DESC'}]
    }));
}
```

**필터**

특수 조건 객체를 사용하여 필터를 구축할 수 있습니다.

```
export function request(ctx) {

    // Generates statement:
    // SELECT "id", "name"
    // FROM "persons"
    // WHERE "name" = :NAME
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name'],
        where: {name: {eq: 'Stephane'}}
    }));
}
```

필터를 결합할 수도 있습니다.

```
export function request(ctx) {

    // Generates statement:
    // SELECT "id", "name"
    // FROM "persons"
    // WHERE "name" = :NAME and "id" > :ID
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name'],
        where: {name: {eq: 'Stephane'}, id: {gt: 10}}
    }));
}
```

`OR` 문을 작성할 수 있습니다.

```
export function request(ctx) {

    // Generates statement:
    // SELECT "id", "name"
    // FROM "persons"
    // WHERE "name" = :NAME OR "id" > :ID
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name'],
        where: { or: [
            { name: { eq: 'Stephane'} },
            { id: { gt: 10 } }
        ]}
    }));
}
```

`not`으로 조건을 무효화할 수도 있습니다.

```
export function request(ctx) {

    // Generates statement:
    // SELECT "id", "name"
    // FROM "persons"
    // WHERE NOT ("name" = :NAME AND "id" > :ID)
    return createPgStatement(select({
        table: 'persons',
        columns: ['id', 'name'],
        where: { not: [
            { name: { eq: 'Stephane'} },
            { id: { gt: 10 } }
        ]}
    }));
}
```

다음 작업을 사용하여 값을 비교할 수도 있습니다.


| 
| 
| 연산자 | 설명 | 가능한 값 유형 | 
| --- |--- |--- |
| eq | Equal | number, string, boolean | 
| ne | Not equal | number, string, boolean | 
| le | Less than or equal | number, string | 
| lt | Less than | number, string | 
| ge | Greater than or equal | number, string | 
| gt | Greater than | number, string | 
| contains | Like | string | 
| notContains | Not like | string | 
| beginsWith | Starts with prefix | string | 
| between | Between two values | number, string | 
| attributeExists | The attribute is not null | number, string, boolean | 
| size | checks the length of the element | string | 

### SQL Insert
<a name="utility-functions-insert"></a>

이 `insert` 유틸리티는 `INSERT` 작업과 함께 데이터베이스에 단일 행 항목을 삽입하는 간단한 방법을 제공합니다.

**단일 항목 삽입**

항목을 삽입하려면 테이블을 지정한 다음 값 객체를 전달하십시오. 객체 키는 테이블 열에 매핑됩니다. 열 이름은 자동으로 이스케이프 처리되고 변수 맵을 사용하여 값이 데이터베이스로 전송됩니다.

```
import { insert, createMySQLStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const { input: values } = ctx.args;
    const insertStatement = insert({ table: 'persons', values });
    
    // Generates statement:
    // INSERT INTO `persons`(`name`)
    // VALUES(:NAME)
    return createMySQLStatement(insertStatement)
}
```

**MySQL 사용 사례**

`select`가 뒤따르는 `insert`를 결합하여 삽입된 행을 검색할 수 있습니다.

```
import { insert, select, createMySQLStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const { input: values } = ctx.args;
    const insertStatement = insert({  table: 'persons', values });
    const selectStatement = select({
        table: 'persons',
        columns: '*',
        where: { id: { eq: values.id } },
        limit: 1,
    });
    
    // Generates statement:
    // INSERT INTO `persons`(`name`)
    // VALUES(:NAME)
    // and
    // SELECT *
    // FROM `persons`
    // WHERE `id` = :ID
    return createMySQLStatement(insertStatement, selectStatement)
}
```

**Postgres 사용 사례**

Postgres를 사용하면 삽입한 행에서 데이터를 가져오는 데 [https://www.postgresql.org/docs/current/dml-returning.html](https://www.postgresql.org/docs/current/dml-returning.html)을 사용할 수 있습니다. `*` 또는 열 이름 배열을 받아들입니다.

```
import { insert, createPgStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const { input: values } = ctx.args;
    const insertStatement = insert({
        table: 'persons',
        values,
        returning: '*'
    });

    // Generates statement:
    // INSERT INTO "persons"("name")
    // VALUES(:NAME)
    // RETURNING *
    return createPgStatement(insertStatement)
}
```

### SQL Update
<a name="utility-functions-update"></a>

`update` 유틸리티를 사용하여 기존 행을 업데이트할 수 있습니다. 조건 객체를 사용하여 조건을 충족하는 모든 행의 지정된 열에 변경 내용을 적용할 수 있습니다. 예를 들어 이러한 변형을 만들 수 있는 스키마가 있다고 가정해 보겠습니다. 해당 `2000` 연도부터 인식(`known_since`)하게 된 경우에만 `Person`의`name`을 `3`의 `id` 값으로 업데이트하려고 합니다.

```
mutation Update {
    updatePerson(
        input: {id: 3, name: "Jon"},
        condition: {known_since: {ge: "2000"}}
    ) {
    id
    name
  }
}
```

업데이트 해석기는 다음과 같이 생겼습니다.

```
import { update, createPgStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const { input: { id, ...values }, condition } = ctx.args;
    const where = {
        ...condition,
        id: { eq: id },
    };
    const updateStatement = update({
        table: 'persons',
        values,
        where,
        returning: ['id', 'name'],
    });

    // Generates statement:
    // UPDATE "persons"
    // SET "name" = :NAME, "birthday" = :BDAY, "country" = :COUNTRY
    // WHERE "id" = :ID
    // RETURNING "id", "name"
    return createPgStatement(updateStatement)
}
```

조건에 검사를 추가하여 `3`와 동등한 프라이머리 키 `id`를 가진 행만 업데이트되도록 할 수 있습니다. 마찬가지로 Postgres `inserts`의 경우 수정된 데이터를 반환하는 데 `returning`을 사용할 수 있습니다.

### SQL Delete
<a name="utility-functions-delete"></a>

`remove` 유틸리티를 사용하여 기존 행을 제거할 수 있습니다. 조건을 충족하는 모든 행에서 조건 객체를 사용할 수 있습니다. 참고로 `delete`는 JavaScript에서 예약된 키워드입니다. 대신 `remove`를 사용해야 합니다.

```
import { remove, createPgStatement } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const { input: { id }, condition } = ctx.args;
    const where = { ...condition, id: { eq: id } };
    const deleteStatement = remove({
        table: 'persons',
        where,
        returning: ['id', 'name'],
    });

    // Generates statement:
    // DELETE "persons"
    // WHERE "id" = :ID
    // RETURNING "id", "name"
    return createPgStatement(updateStatement)
}
```

## 캐스팅
<a name="casting"></a>

올바른 객체 유형을 더 구체적으로 지정하여 문에 사용하려는 경우가 있을 수 있습니다. 제공된 유형 힌트를 사용하여 파라미터 유형을 지정할 수 있습니다.는 데이터 API와 [동일한 유형 힌트](https://docs.aws.amazon.com//rdsdataservice/latest/APIReference/API_SqlParameter.html#rdsdtataservice-Type-SqlParameter-typeHint)를 AWS AppSync 지원합니다. 모듈의 `typeHint` 함수를 사용하여 파라미터를 캐스팅할 AWS AppSync `rds` 수 있습니다.

다음 예시에서는 JSON 객체로 캐스팅된 값으로 배열을 보낼 수 있습니다. `->` 연산자를 사용하여 JSON 배열의 `index` `2`에서 요소를 검색합니다.

```
import { sql, createPgStatement, toJsonObject, typeHint } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const arr = ctx.args.list_of_ids
    const statement = sql`select ${typeHint.JSON(arr)}->2 as value`
    return createPgStatement(statement)
}

export function response(ctx) {
    return toJsonObject(ctx.result)[0][0].value
}
```

캐스팅은 `DATE`, `TIME` 및 `TIMESTAMP` 등을 처리하고 비교할 때도 유용합니다.

```
import { select, createPgStatement, typeHint } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const when = ctx.args.when
    const statement = select({
        table: 'persons',
        where: { createdAt : { gt: typeHint.DATETIME(when) } }
    })
    return createPgStatement(statement)
}
```

다음에서는 현재 날짜와 시간을 보낼 수 있는 방법을 보여줍니다.

```
import { sql, createPgStatement, typeHint } from '@aws-appsync/utils/rds';

export function request(ctx) {
    const now = util.time.nowFormatted('YYYY-MM-dd HH:mm:ss')
    return createPgStatement(sql`select ${typeHint.TIMESTAMP(now)}`)
}
```

**사용 가능한 유형 힌트**
+ `typeHint.DATE` – 해당 파라미터는 `DATE` 유형의 객체로 데이터베이스에 전송됩니다. 승인된 형식은 `YYYY-MM-DD`입니다.
+ `typeHint.DECIMAL` – 해당 파라미터는 `DECIMAL` 유형의 객체로 데이터베이스에 전송됩니다.
+ `typeHint.JSON` – 해당 파라미터는 `JSON` 유형의 객체로 데이터베이스에 전송됩니다.
+ `typeHint.TIME` – 해당 문자열 파라미터 값은 `TIME` 유형의 객체로 데이터베이스에 전송됩니다. 승인된 형식은 `HH:MM:SS[.FFF]`입니다.
+ `typeHint.TIMESTAMP` – 해당 문자열 파라미터 값은 `TIMESTAMP` 유형의 객체로 데이터베이스에 전송됩니다. 승인된 형식은 `YYYY-MM-DD HH:MM:SS[.FFF]`입니다.
+ `typeHint.UUID` – 해당 문자열 파라미터 값은 `UUID` 유형의 객체로 데이터베이스에 전송됩니다.

# Amazon Bedrock 런타임에 대한AWS AppSync JavaScript 해석기 및 함수 참조
<a name="resolver-reference-bedrock-js"></a>

 AWS AppSync 함수와 해석기를 사용하여의 Amazon Bedrock에서 모델을 호출할 수 있습니다 AWS 계정. 클라이언트에 반환하기 전에 요청 페이로드와 모델 간접 호출의 응답을 구성할 수 있습니다. Amazon Bedrock 런타임의 `InvokeModel` API 또는 `Converse` API를 사용할 수 있습니다. 이 섹션에서는 지원되는 Amazon Bedrock 작업에 대한 요청에 대해 설명합니다.

**참고**  
AWS AppSync 는 10초 이내에 완료되는 동기 호출만 지원합니다. Amazon Bedrock의 스트림 APIs 호출할 수 없습니다.는 AWS AppSync API와 동일한 리전에서 파운데이션 모델 및 [추론 프로파일](https://docs.aws.amazon.com/bedrock/latest/userguide/inference-profiles.html) 호출 AWS AppSync 만 지원합니다.

## 요청 객체
<a name="request_object"></a>

`InvokeModel` 요청 객체를 사용하면 Amazon Bedrock의 `InvokeModel` API와 상호 작용할 수 있습니다.

```
type BedrockInvokeModelRequest = {
  operation: 'InvokeModel';
  modelId: string;
  body: any;
  guardrailIdentifier?: string;
  guardrailVersion?: string;
  guardrailTrace?: string;
}
```

`Converse` 요청 객체를 사용하면 Amazon Bedrock의 `Converse` API와 상호 작용할 수 있습니다.

```
type BedrockConverseRequest = {
  operation: 'Converse';
  modelId: string;
  messages: BedrockMessage[];
  additionalModelRequestFields?: any;
  additionalModelResponseFieldPaths?: string[];
  guardrailConfig?: BedrockGuardrailConfig;
  inferenceConfig?: BedrockInferenceConfig;
  promptVariables?: { [key: string]: BedrockPromptVariableValues }[];
  system?: BedrockSystemContent[];
  toolConfig?: BedrockToolConfig;
}
```

자세한 내용은 이 주제의 [유형 참조](#type-reference-bedrock) 섹션 후반부를 참조하세요.

함수 및 해석기에서 요청 객체를 직접 빌드하거나 @aws-appsync/utils/ai의 헬퍼 함수를 사용하여 요청을 생성할 수 있습니다. 요청에서 모델 ID(modelId)를 지정할 때 모델 ID 또는 모델 ARN을 사용할 수 있습니다.

다음 예제에서는 `invokeModel` 함수를 사용하여 Amazon Titan Text G1 - Lite(amazon.titan-text-lite-v1)를 사용하여 텍스트를 요약합니다. 구성된 가드레일은 프롬프트 흐름에서 원치 않는 콘텐츠를 식별하고 차단하거나 필터링하는 데 사용됩니다. *Amazon Bedrock 사용 설명서*에서 [Amazon Bedrock 가드레일](https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails.html)에 대해 자세히 알아보세요.

**중요**  
사용자는 애플리케이션 개발을 보호하고 프롬프트 인젝션과 같은 취약성을 방지할 책임이 있습니다. 자세한 내용은 *Amazon Bedrock 사용 설명서*의 [프롬프트 인젝션 보안](https://docs.aws.amazon.com/bedrock/latest/userguide/prompt-injection.html) 섹션을 참조하세요.

```
import { invokeModel } from '@aws-appsync/utils/ai'
export function request(ctx) {
  return invokeModel({
    modelId: 'amazon.titan-text-lite-v1',
    guardrailIdentifier: "zabcd12345678",
    guardrailVersion: "1",
    body: { inputText: `Summarize this text in less than 100 words. : \n<text>${ctx.stash.text ?? ctx.env.DEFAULT_TEXT}</text>` },
  })
}

export function response(ctx) {
  return ctx.result.results[0].outputText
}
```

다음 예제에서는 교차 리전 추론 프로파일(us.anthropic.claude-3-5-haiku-20241022-v1:0)과 함께 `converse` 함수를 사용합니다. Amazon Bedrock의 [추론 프로파일에 대한 Amazon Bedrock의 전제 조건](https://docs.aws.amazon.com/bedrock/latest/userguide/inference-profiles-prereq.html)에 대한 자세한 내용은 *Amazon Bedrock 사용 설명서*를 참조하세요.

**주의 사항**: 사용자는 애플리케이션 개발을 보호하고 프롬프트 인젝션과 같은 취약성을 방지할 책임이 있습니다.

```
import { converse } from '@aws-appsync/utils/ai'

export function request(ctx) {
  return converse({
    modelId: 'us.anthropic.claude-3-5-haiku-20241022-v1:0',
    system: [
      {
        text: `
You are a database assistant that provides SQL queries to retrieve data based on a natural language request. 
${ctx.args.explain ? 'Explain your answer' : 'Do not explain your answer'}.
Assume a database with the following tables and columns exists:

Customers:  
- customer_id (INT, PRIMARY KEY)  
- first_name (VARCHAR)  
- last_name (VARCHAR)  
- email (VARCHAR)  
- phone (VARCHAR)  
- address (VARCHAR)  
- city (VARCHAR)  
- state (VARCHAR)  
- zip_code (VARCHAR)  
  
Products:  
- product_id (INT, PRIMARY KEY)  
- product_name (VARCHAR)  
- description (TEXT)  
- category (VARCHAR)  
- price (DECIMAL)  
- stock_quantity (INT)  

Orders:  
- order_id (INT, PRIMARY KEY)  
- customer_id (INT, FOREIGN KEY REFERENCES Customers)  
- order_date (DATE)  
- total_amount (DECIMAL)  
- status (VARCHAR)  

Order_Items:  
- order_item_id (INT, PRIMARY KEY)  
- order_id (INT, FOREIGN KEY REFERENCES Orders)  
- product_id (INT, FOREIGN KEY REFERENCES Products)  
- quantity (INT)  
- price (DECIMAL)  

Reviews:  
- review_id (INT, PRIMARY KEY)  
- product_id (INT, FOREIGN KEY REFERENCES Products)  
- customer_id (INT, FOREIGN KEY REFERENCES Customers)  
- rating (INT)  
- comment (TEXT)  
- review_date (DATE)`,
      },
    ],
    messages: [
      {
        role: 'user',
        content: [{ text: `<request>${ctx.args.text}:</request>` }],
      },
    ],
  })
}

export function response(ctx) {
  return ctx.result.output.message.content[0].text
}
```

다음 예제에서는 `converse`를 사용하여 구조화된 응답을 생성합니다. DB 스키마 참조에 환경 변수를 사용하고 공격을 방지하는 데 도움이 되도록 가드레일을 구성합니다.

```
import { converse } from '@aws-appsync/utils/ai'

export function request(ctx) {
  return generateObject({
    modelId: ctx.env.HAIKU3_5, // keep the model in an env variable
    prompt: ctx.args.query,
    shape: objectType(
      {
        sql: stringType('the sql query to execute as a javascript template string.'),
        parameters: objectType({}, 'the placeholder parameters for the query, if any.'),
      },
      'the sql query to execute along with the place holder parameters',
    ),
    system: [
      {
        text: `
You are a database assistant that provides SQL queries to retrieve data based on a natural language request. 

Assume a database with the following tables and columns exists:

${ctx.env.DB_SCHEMA_CUSTOMERS}
${ctx.env.DB_SCHEMA_ORDERS}
${ctx.env.DB_SCHEMA_ORDER_ITEMS}
${ctx.env.DB_SCHEMA_PRODUCTS}
${ctx.env.DB_SCHEMA_REVIEWS}`,
      },
    ],
    guardrailConfig: { guardrailIdentifier: 'iabc12345678', guardrailVersion: 'DRAFT' },
  })
}

export function response(ctx) {
  return toolReponse(ctx.result)
}

function generateObject(input) {
  const { modelId, prompt, shape, ...options } = input
  return converse({
    modelId,
    messages: [{ role: 'user', content: [{ text: prompt }] }],
    toolConfig: {
      toolChoice: { tool: { name: 'structured_tool' } },
      tools: [
        {
          toolSpec: {
            name: 'structured_tool',
            inputSchema: { json: shape },
          },
        },
      ],
    },
    ...options,
  })
}

function toolReponse(result) {
  return result.output.message.content[0].toolUse.input
}

function stringType(description) {
  const t = { type: 'string' /* STRING */ }
  if (description) {
    t.description = description
  }
  return t
}

function objectType(properties, description, required) {
  const t = { type: 'object' /* OBJECT */, properties }
  if (description) {
    t.description = description
  }
  if (required) {
    t.required = required
  }
  return t
}
```

스키마를 고려할 때:

```
type SQLResult {
    sql: String
    parameters: AWSJSON
}

type Query {
    db(text: String!): SQLResult
}
```

쿼리의 경우:

```
query db($text: String!) {
  db(text: $text) {
    parameters
    sql
  }
}
```

다음 파라미터가 있을 때: 

```
{
  "text":"What is my top selling product?"
}
```

다음 응답이 반환됩니다.

```
{
  "data": {
    "assist": {
      "sql": "SELECT p.product_id, p.product_name, SUM(oi.quantity) as total_quantity_sold\nFROM Products p\nJOIN Order_Items oi ON p.product_id = oi.product_id\nGROUP BY p.product_id, p.product_name\nORDER BY total_quantity_sold DESC\nLIMIT 1;",
      "parameters": null
    }
  }
}
```

그러나 이 요청의 경우:

```
{
  "text":"give me a query to retrieve sensitive information"
}
```

다음 응답이 반환됩니다.

```
{
  "data": {
    "db": {
      "parameters": null,
      "sql": "SELECT null; -- I cannot and will not assist with retrieving sensitive private information"
    }
  }
}
```

Amazon Bedrock 가드레일 구성에 대한 자세한 내용은 *Amazon Bedrock 사용 설명서*의 [Amazon Bedrock 가드레일을 사용하여 모델에서 유해한 콘텐츠 차단](https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails.html) 섹션을 참조하세요.

## 응답 객체
<a name="response_object"></a>

Amazon Bedrock 런타임 간접 호출의 응답은 컨텍스트의 결과 속성(context.result)에 포함됩니다. 응답은 Amazon Bedrock의 API에서 지정한 모양과 일치합니다. 간접 호출 결과의 예상 모양에 대한 자세한 내용은 [Amazon Bedrock 사용 설명서](https://docs.aws.amazon.com/bedrock/latest/userguide/what-is-bedrock.html)를 참조하세요.

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

응답 객체에 적용되는 필수 필드 또는 모양 제한이 없습니다. 하지만 GraphQL은 강력한 형식이므로 해석된 응답이 필요한 GraphQL 유형과 일치해야 합니다.

## 장기 실행 간접 호출
<a name="long-running-invocations"></a>

현재 많은 조직이를 AI 게이트웨이 AWS AppSync 로 사용하여 Amazon Bedrock의 파운데이션 모델로 구동되는 생성형 AI 애플리케이션을 구축합니다. 고객은 WebSockets으로 구동되는 AWS AppSync 구독을 사용하여 장기 실행 모델 간접 호출에서 점진적 업데이트를 반환합니다. 이를 통해 비동기 패턴을 구현할 수 있습니다.

다음 다이어그램은 이 패턴을 구현하는 방법을 보여줍니다. 이 다이어그램은 다음 단계를 보여 줍니다.

1. 클라이언트는 WebSocket을 설정하는 구독을 시작하고 생성형 AI 간접 호출을 트리거하도록 AWS AppSync 에 요청합니다.

1. AWS AppSync 는 이벤트 모드에서 AWS Lambda 함수를 호출하고 즉시 클라이언트에 응답을 반환합니다.

1. Lambda 함수가 Amazon Bedrock에서 모델을 간접 호출합니다. Lambda 함수는 동기 API(예: `InvokeModel`) 또는 스트림 API(예: `InvokeModelWithResponseStream`)를 사용하여 점진적 업데이트를 가져올 수 있습니다.

1. 업데이트가 수신되거나 호출이 완료되면 Lambda 함수는 변형을 통해 API에 업데이트를 전송하여 구독을 AWS AppSync 트리거합니다.

1. 구독 이벤트는 WebSocket을 통해 클라이언트가 실시간으로 전송하고 수신합니다.

![\[AWS AppSync 구독을 사용하여 Amazon Bedrock 모델의 업데이트를 반환하는 워크플로를 보여주는 다이어그램입니다.\]](http://docs.aws.amazon.com/ko_kr/appsync/latest/devguide/images/bedrock-workflow.png)


## 유형 참조
<a name="type-reference-bedrock"></a>

```
export type BedrockMessage = {
  role: 'user' | 'assistant' | string;
  content: BedrockMessageContent[];
};

export type BedrockMessageContent =
  | { text: string }
  | { guardContent: BedrockGuardContent }
  | { toolResult: BedrockToolResult }
  | { toolUse: BedrockToolUse };

export type BedrockGuardContent = {
  text: BedrockGuardContentText;
};

export type BedrockGuardContentText = {
  text: string;
  qualifiers?: ('grounding_source' | 'query' | 'guard_content' | string)[];
};

export type BedrockToolResult = {
  content: BedrockToolResultContent[];
  toolUseId: string;
  status?: string;
};

export type BedrockToolResultContent = { json: any } | { text: string };

export type BedrockToolUse = {
  input: any;
  name: string;
  toolUseId: string;
};

export type ConversePayload = {
  modelId: string;
  body: any;
  guardrailIdentifier?: string;
  guardrailVersion?: string;
  guardrailTrace?: string;
};

export type BedrockGuardrailConfig = {
  guardrailIdentifier: string;
  guardrailVersion: string;
  trace: string;
};

export type BedrockInferenceConfig = {
  maxTokens?: number;
  temperature?: number;
  stopSequences?: string[];
  topP?: number;
};

export type BedrockPromptVariableValues = {
  text: string;
};

export type BedrockToolConfig = {
  tools: BedrockTool[];
  toolChoice?: BedrockToolChoice;
};

export type BedrockTool = {
  toolSpec: BedrockToolSpec;
};

export type BedrockToolSpec = {
  name: string;
  description?: string;
  inputSchema: BedrockInputSchema;
};

export type BedrockInputSchema = {
  json: any;
};

export type BedrockToolChoice =
  | { tool: BedrockSpecificToolChoice }
  | { auto: any }
  | { any: any };

export type BedrockSpecificToolChoice = {
  name: string;
};

export type BedrockSystemContent =
  | { guardContent: BedrockGuardContent }
  | { text: string };

export type BedrockConverseOutput = {
  message?: BedrockMessage;
};

export type BedrockConverseMetrics = {
  latencyMs: number;
};

export type BedrockTokenUsage = {
  inputTokens: number;
  outputTokens: number;
  totalTokens: number;
};

export type BedrockConverseTrace = {
  guardrail?: BedrockGuardrailTraceAsssessment;
};

export type BedrockGuardrailTraceAsssessment = {
  inputAssessment?: { [key: string]: BedrockGuardrailAssessment };
  modelOutput?: string[];
  outputAssessments?: { [key: string]: BedrockGuardrailAssessment };
};

export type BedrockGuardrailAssessment = {
  contentPolicy?: BedrockGuardrailContentPolicyAssessment;
  contextualGroundingPolicy?: BedrockGuardrailContextualGroundingPolicyAssessment;
  invocationMetrics?: BedrockGuardrailInvocationMetrics;
  sensitiveInformationPolicy?: BedrockGuardrailSensitiveInformationPolicyAssessment;
  topicPolicy?: BedrockGuardrailTopicPolicyAssessment;
  wordPolicy?: BedrockGuardrailWordPolicyAssessment;
};

export type BedrockGuardrailContentPolicyAssessment = {
  filters: BedrockGuardrailContentFilter[];
};

export type BedrockGuardrailContentFilter = {
  action: 'BLOCKED' | string;
  confidence: 'NONE' | 'LOW' | 'MEDIUM' | 'HIGH' | string;
  type:
    | 'INSULTS'
    | 'HATE'
    | 'SEXUAL'
    | 'VIOLENCE'
    | 'MISCONDUCT'
    | 'PROMPT_ATTACK'
    | string;
  filterStrength: 'NONE' | 'LOW' | 'MEDIUM' | 'HIGH' | string;
};

export type BedrockGuardrailContextualGroundingPolicyAssessment = {
  filters: BedrockGuardrailContextualGroundingFilter;
};

export type BedrockGuardrailContextualGroundingFilter = {
  action: 'BLOCKED' | 'NONE' | string;
  score: number;
  threshold: number;
  type: 'GROUNDING' | 'RELEVANCE' | string;
};

export type BedrockGuardrailInvocationMetrics = {
  guardrailCoverage?: BedrockGuardrailCoverage;
  guardrailProcessingLatency?: number;
  usage?: BedrockGuardrailUsage;
};

export type BedrockGuardrailCoverage = {
  textCharacters?: BedrockGuardrailTextCharactersCoverage;
};

export type BedrockGuardrailTextCharactersCoverage = {
  guarded?: number;
  total?: number;
};

export type BedrockGuardrailUsage = {
  contentPolicyUnits: number;
  contextualGroundingPolicyUnits: number;
  sensitiveInformationPolicyFreeUnits: number;
  sensitiveInformationPolicyUnits: number;
  topicPolicyUnits: number;
  wordPolicyUnits: number;
};

export type BedrockGuardrailSensitiveInformationPolicyAssessment = {
  piiEntities: BedrockGuardrailPiiEntityFilter[];
  regexes: BedrockGuardrailRegexFilter[];
};

export type BedrockGuardrailPiiEntityFilter = {
  action: 'BLOCKED' | 'ANONYMIZED' | string;
  match: string;
  type:
    | 'ADDRESS'
    | 'AGE'
    | 'AWS_ACCESS_KEY'
    | 'AWS_SECRET_KEY'
    | 'CA_HEALTH_NUMBER'
    | 'CA_SOCIAL_INSURANCE_NUMBER'
    | 'CREDIT_DEBIT_CARD_CVV'
    | 'CREDIT_DEBIT_CARD_EXPIRY'
    | 'CREDIT_DEBIT_CARD_NUMBER'
    | 'DRIVER_ID'
    | 'EMAIL'
    | 'INTERNATIONAL_BANK_ACCOUNT_NUMBER'
    | 'IP_ADDRESS'
    | 'LICENSE_PLATE'
    | 'MAC_ADDRESS'
    | 'NAME'
    | 'PASSWORD'
    | 'PHONE'
    | 'PIN'
    | 'SWIFT_CODE'
    | 'UK_NATIONAL_HEALTH_SERVICE_NUMBER'
    | 'UK_NATIONAL_INSURANCE_NUMBER'
    | 'UK_UNIQUE_TAXPAYER_REFERENCE_NUMBER'
    | 'URL'
    | 'USERNAME'
    | 'US_BANK_ACCOUNT_NUMBER'
    | 'US_BANK_ROUTING_NUMBER'
    | 'US_INDIVIDUAL_TAX_IDENTIFICATION_NUMBER'
    | 'US_PASSPORT_NUMBER'
    | 'US_SOCIAL_SECURITY_NUMBER'
    | 'VEHICLE_IDENTIFICATION_NUMBER'
    | string;
};

export type BedrockGuardrailRegexFilter = {
  action: 'BLOCKED' | 'ANONYMIZED' | string;
  match?: string;
  name?: string;
  regex?: string;
};

export type BedrockGuardrailTopicPolicyAssessment = {
  topics: BedrockGuardrailTopic[];
};

export type BedrockGuardrailTopic = {
  action: 'BLOCKED' | string;
  name: string;
  type: 'DENY' | string;
};

export type BedrockGuardrailWordPolicyAssessment = {
  customWords: BedrockGuardrailCustomWord[];
  managedWordLists: BedrockGuardrailManagedWord[];
};

export type BedrockGuardrailCustomWord = {
  action: 'BLOCKED' | string;
  match: string;
};

export type BedrockGuardrailManagedWord = {
  action: 'BLOCKED' | string;
  match: string;
  type: 'PROFANITY' | string;
};
```