

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

# AWS AppSync에서 해석기 구성
<a name="resolver-config-overview"></a>

이전 섹션에서는 GraphQL 스키마와 데이터 소스를 만든 다음 AWS AppSync 서비스에서 함께 연결하는 방법을 배웠습니다. 스키마에서 쿼리 및 뮤테이션에 하나 이상의 필드(작업)를 설정했을 수 있습니다. 스키마는 작업이 데이터 소스에서 요청하는 데이터 종류를 설명했지만, 해당 작업이 데이터에 대해 어떻게 동작하는지는 구현하지 못했습니다.

작업의 동작은 항상 해석기에서 구현되며, 해석기는 작업을 수행하는 필드에 연결됩니다. 해석기의 일반적인 작동 방식에 대한 자세한 내용은 [해석기](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-components.html) 페이지를 참조하세요.

AWS AppSync에서 해석기는 해석기가 실행되는 환경인 런타임에 연결되어 있습니다. 런타임에 따라 해석기를 작성할 언어가 결정됩니다. 현재 지원되는 런타임은 APPSYNC\$1JS(JavaScript)와 Apache Velocity Template Language(VTL)입니다.

해석기를 구현할 때는 다음과 같은 일반적인 구조를 따릅니다.
+ **단계 이전**: 클라이언트가 요청을 보내면 사용 중인 스키마 필드(일반적으로 쿼리, 뮤테이션, 구독)의 해석기에 요청 데이터가 전달됩니다. 해석기는 데이터가 해석기를 통해 이동하기 전에 일부 사전 처리 작업을 수행할 수 있는 사전 단계 핸들러를 사용하여 요청 데이터 처리를 시작합니다.
+ **함수:** 사전 단계가 실행되면 요청이 함수 목록으로 전달됩니다. 목록의 첫 번째 함수는 데이터 원본에 대해 실행됩니다. 함수는 자체 요청 및 응답 핸들러를 포함하는 해석기 코드의 하위 집합입니다. 요청 핸들러는 요청 데이터를 가져와 데이터 소스에 대해 작업을 수행합니다. 응답 핸들러는 데이터 소스의 응답을 다시 목록으로 전달하기 전에 해당 데이터 소스의 응답을 처리합니다. 함수가 두 개 이상인 경우 요청 데이터는 목록의 다음 함수로 전송되어 실행됩니다. 목록에 있는 함수는 개발자가 정의한 순서대로 순차적으로 실행됩니다. 모든 함수가 실행되면 최종 결과가 사후 단계로 전달됩니다.
+ **단계 이후**: 이후 단계는 GraphQL 응답으로 전달하기 전에 최종 함수의 응답에 대한 몇 가지 최종 작업을 수행할 수 있는 핸들러 함수입니다.

이 흐름은 파이프라인 해석기의 예입니다. 파이프라인 해석기는 두 런타임 모두에서 지원됩니다. 하지만 여기서는 파이프라인 해석기가 수행할 수 있는 작업에 대한 간단한 설명입니다. 또한 가능한 해석기 구성을 하나만 설명합니다. 지원되는 해석기 구성에 대한 자세한 내용은 APPSYNC\$1JS의 경우 [JavaScript 해석기 개요](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html)를, 또는 VTL의 경우 [해석기 매핑 템플릿 개요](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-overview.html)를 참조하세요.

보시다시피 해석기는 모듈식입니다. 해석기의 구성 요소가 제대로 작동하려면 다른 구성 요소에서 실행 상태를 들여다볼 수 있어야 합니다. [해석기](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-components.html) 섹션에서 해석기의 각 구성 요소는 인수 집합(`args`, `context` 등)으로 실행 상태에 대한 중요한 정보를 전달할 수 있다는 것을 확인했습니다. AWS AppSync에서는 이 작업을 `context`에서 엄격하게 처리합니다. 확인 중인 필드에 대한 정보를 담는 컨테이너입니다. 여기에는 전달되는 인수, 결과, 권한 부여 데이터, 헤더 데이터 등 모든 것이 포함될 수 있습니다. 컨텍스트에 대한 자세한 내용은 APPSYNC\$1JS의 경우 [해석기 컨텍스트 객체 참조](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference-js.html)를, 또는 VTL의 경우 [해석기 매핑 템플릿 컨텍스트 참조](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference.html)를 참조하세요.

컨텍스트는 해석기를 구현하는 데 사용할 수 있는 유일한 도구가 아닙니다. AWS AppSync는 값 생성, 오류 처리, 구문 분석, 변환 등을 위한 광범위한 유틸리티를 지원합니다. APPSYNC\$1JS의 경우 [여기](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-util-reference-js.html)에서, 또는 VTL의 경우 [여기](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-util-reference.html)에서 유틸리티 목록을 볼 수 있습니다.

다음 섹션에서는 GraphQL API에서 해석기를 구성하는 방법을 알아봅니다.

**Topics**
+ [기본 쿼리 생성(JavaScript)](configuring-resolvers-js.md)
+ [기본 쿼리 생성(VTL)](configuring-resolvers.md)

# 기본 쿼리 생성(JavaScript)
<a name="configuring-resolvers-js"></a>

GraphQL 해석기는 형식 스키마의 필드를 데이터 원본에 연결합니다. 해석기는 요청을 이행하는 메커니즘입니다.

 AWS AppSync의 해석기는 JavaScript를 사용하여 GraphQL 표현식을 데이터 소스가 사용할 수 있는 형식으로 변환합니다. 또는 [Apache Velocity Template Language(VTL)](https://velocity.apache.org/engine/2.0/vtl-reference.html)로 작성된 매핑 템플릿을 사용하여 GraphQL 식을 데이터 원본이 사용할 수 있는 형식으로 변환할 수 있습니다.

이 섹션에서는 JavaScript를 사용하여 해석기를 구성하는 방법을 설명합니다. [해석기 자습서(JavaScript)](https://docs.aws.amazon.com/appsync/latest/devguide/tutorials-js.html) 섹션에서는 JavaScript를 사용하여 해석기를 구현하는 방법에 대한 심화된 자습서를 제공합니다. [해석기 참조(JavaScript)](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html) 섹션에서는 JavaScript 해석기와 함께 사용할 수 있는 유틸리티 작업에 대한 설명을 제공합니다.

앞서 언급한 자습서를 사용하기 전에 이 안내서를 확인하는 것이 좋습니다.

이 섹션에서는 쿼리와 변형을 위한 해석기를 만들고 구성하는 방법을 살펴보겠습니다.

**참고**  
이 안내서에서는 스키마를 만들었으며 쿼리 또는 변형이 하나 이상 있다고 가정합니다. 구독(실시간 데이터)을 찾고 있다면 [이](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-real-time-data.html) 안내서를 참조하세요.

이 섹션에서는 아래 스키마를 사용하는 예제와 함께 해석기 구성을 위한 몇 가지 일반적인 단계를 제공합니다.

```
// schema.graphql file

input CreatePostInput {
  title: String
  date: AWSDateTime
}

type Post {
  id: ID!
  title: String
  date: AWSDateTime
}

type Mutation {
  createPost(input: CreatePostInput!): Post
}

type Query {
  getPost: [Post]
}
```

## 기본 쿼리 해석기 생성
<a name="create-basic-query-resolver-js"></a>

이 섹션에서는 기본 쿼리 해석기를 생성하는 방법을 보여 줍니다.

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

1. 에 로그인 AWS Management Console 하고 [AppSync 콘솔](https://console.aws.amazon.com/appsync/)을 엽니다.

   1. **API 대시보드**에서 GraphQL API를 선택합니다.

   1. **사이드바**에서 **스키마**를 선택합니다.

1. 스키마와 데이터 원본의 세부 정보를 입력합니다. 자세한 내용은 [스키마 설계](https://docs.aws.amazon.com/appsync/latest/devguide/designing-your-schema.html) 및 [데이터 원본 연결](https://docs.aws.amazon.com/appsync/latest/devguide/attaching-a-data-source.html) 섹션을 참조하세요.

1. **스키마** 편집기 옆에는 **해석기**라는 창이 있습니다. 이 상자에는 **스키마** 창에 정의된 형식 및 필드 목록이 있습니다. 필드에 해석기를 연결할 수 있습니다. 주로 필드 작업에 해석기를 연결하게 될 것입니다. 이 섹션에서는 간단한 쿼리 구성을 살펴보겠습니다. **쿼리** 유형에서 쿼리 필드 옆에 있는 **연결**을 선택합니다.

1. **해석기 연결** 페이지의 **해석기 유형**에서 파이프라인 또는 단위 해석기 중에서 선택할 수 있습니다. 이러한 유형에 대한 자세한 내용은 [해석기](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-components.html)를 참조하세요. 이 안내서에서는 `pipeline resolvers`를 활용합니다.
**작은 정보**  
파이프라인 해석기를 생성하면 데이터 원본이 파이프라인 함수에 연결됩니다. 함수는 파이프라인 해석기를 생성한 후에 생성되므로 이 페이지에는 설정을 위한 옵션이 없습니다. 단위 해석기를 사용하는 경우 데이터 원본이 해석기에 직접 연결되므로 이 페이지에서 설정하게 됩니다.

   **해석기 런타임**의 경우 `APPSYNC_JS`를 선택하여 JavaScript 런타임을 활성화하세요.

1. 이 API에 [캐싱](https://docs.aws.amazon.com/appsync/latest/devguide/enabling-caching.html)을 활성화할 수 있습니다. 그러나 지금은 이 기능을 끄는 것이 좋습니다. **생성(Create)**을 선택합니다.

1. **해석기 편집** 페이지에는 해석기 핸들러 및 응답(사전 및 사후 단계)에 대한 로직을 구현할 수 있게 해주는 **해석기 코드**라는 코드 편집기가 있습니다. 자세한 내용은 [JavaScript 해석기 개요](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html)를 참조하세요.
**참고**  
이 예에서는 요청을 비워 두고 [컨텍스트](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference-js.html)의 마지막 데이터 원본 결과를 반환하도록 응답을 설정해 보겠습니다.  

   ```
   import {util} from '@aws-appsync/utils';
   
   export function request(ctx) {
       return {};
   }
   
   export function response(ctx) {
       return ctx.prev.result;
   }
   ```

   이 섹션 아래에는 **함수**라는 테이블이 있습니다. 함수를 사용하면 여러 해석기에서 재사용할 수 있는 코드를 구현할 수 있습니다. 코드를 계속 다시 작성하거나 복사하는 대신, 소스 코드를 함수로 저장하여 필요할 때마다 해석기에 추가되도록 할 수 있습니다.

   함수는 파이프라인 작업 목록의 대부분을 구성합니다. 해석기에서 여러 함수를 사용하는 경우 함수 순서를 설정하면 해당 순서대로 순차적으로 실행됩니다. 이러한 함수는 요청 함수가 실행된 후와 응답 함수가 시작되기 전에 실행됩니다.

   새 함수를 추가하려면 **함수**에서 **함수 추가**를 선택한 다음 **새 함수 생성**을 선택합니다. 또는 선택할 수 있는 **함수 생성** 버튼이 표시될 수도 있습니다.

   1. 데이터 원본을 선택합니다. 이 항목은 해석기가 작동하는 데이터 원본이 됩니다.
**참고**  
이 예제에서는 `id`로 `Post` 객체를 검색하는 `getPost`에 대한 해석기를 연결합니다. 이 스키마에 대한 DynamoDB 테이블을 이미 설정했다고 가정해 보겠습니다. 파티션 키는 `id`로 설정되어 있고 비어 있습니다.

   1. `Function name`을 입력합니다.

   1. **함수 코드**에서 함수의 동작을 구현해야 합니다. 헷갈릴 수도 있지만 각 함수에는 고유한 로컬 요청 및 응답 핸들러가 있습니다. 요청이 실행되면 요청을 처리하기 위한 데이터 원본 간접 호출이 수행되고, 응답 핸들러가 데이터 원본 응답을 처리합니다. 결과는 [컨텍스트](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference-js.html) 객체에 저장됩니다. 이후에는 목록의 다음 함수가 실행되거나 마지막 함수인 경우 사후 단계 응답 핸들러로 전달됩니다.
**참고**  
이 예제에서는 데이터 원본에서 `Post` 객체 목록을 가져오는 `getPost`에 해석기를 연결합니다. 요청 함수는 테이블에서 데이터를 요청하고, 테이블은 컨텍스트(ctx)에 응답을 전달한 다음, 응답은 컨텍스트에 결과를 반환합니다. AWS AppSync의 강도는 다른 AWS 서비스와의 상호 연결성에 있습니다. DynamoDB를 사용하고 있기 때문에 이와 같은 작업을 단순화할 수 있는 [일련의 작업](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html)이 있습니다. 다른 데이터 원본 유형에 대한 몇 가지 보일러플레이트 예제도 있습니다.  
코드는 다음과 같습니다.  

      ```
      import { util } from '@aws-appsync/utils';
      
      /**
       * Performs a scan on the dynamodb data source
       */
      export function request(ctx) {
        return { operation: 'Scan' };
      }
      
      /**
       * return a list of scanned post items
       */
      export function response(ctx) {
        return ctx.result.items;
      }
      ```
이 단계에서는 두 가지 함수를 추가했습니다.  
`request`: 요청 핸들러는 데이터 원본에 대해 검색 작업을 수행합니다. 인수에는 컨텍스트 객체(`ctx`) 또는 특정 작업을 수행하는 모든 해석기에 사용할 수 있는 일부 데이터가 포함됩니다. 예를 들어 권한 부여 데이터, 해석 중인 필드 이름 등이 포함될 수 있습니다. 반환 문은 [https://docs.aws.amazon.com//appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-scan](https://docs.aws.amazon.com//appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-scan) 작업을 수행합니다(예시는 [여기](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Scan.html)를 참조). DynamoDB로 작업 중이므로 해당 서비스의 일부 작업을 사용할 수 있습니다. 스캔은 테이블 내 모든 항목에 대한 기본 가져오기를 수행합니다. 이 작업의 결과는 응답 핸들러로 전달되기 전에 컨텍스트 객체에 `result` 컨테이너로 저장됩니다. `request`는 파이프라인에서 응답보다 먼저 실행됩니다.
`response`: `request`의 출력을 반환하는 응답 핸들러입니다. 인수는 업데이트된 컨텍스트 객체이고, 반환 문은 `ctx.prev.result`입니다. 이 시점에서는 이 값에 익숙하지 않을 수 있습니다. `ctx`는 컨텍스트 객체를 나타냅니다. `prev`는 파이프라인에서의 이전 작업을 나타내며, 여기에서는 `request`였습니다. `result`에는 파이프라인을 통과하는 해석기의 결과가 포함됩니다. 종합해 보면 `ctx.prev.result`는 마지막으로 수행된 작업, 즉 요청 핸들러의 결과를 반환합니다.

   1. 완료했으면 **생성**을 선택합니다.

1. 해석기 화면으로 돌아가서 **함수** 아래에서 **함수 추가** 드롭다운을 선택하고 함수를 함수 목록에 추가합니다.

1. **저장**을 선택하여 해석기를 업데이트합니다.

------
#### [ CLI ]

**함수를 추가하는 방법**
+ `[create-function](https://docs.aws.amazon.com/cli/latest/reference/appsync/create-function.html)` 명령을 사용하여 파이프라인 해석기용 함수를 생성합니다.

  이 특정 명령에 대해 몇 가지 파라미터를 입력해야 합니다.

  1. API의 `api-id`.

  1.  AWS AppSync 콘솔에 있는 함수`name`의 입니다.

  1. `data-source-name` 또는 함수가 사용할 데이터 원본의 이름. 이미 생성되어 AWS AppSync 서비스에 있는 GraphQL API에 연결되어 있어야 합니다.

  1. `runtime` 또는 함수의 환경 및 언어. JavaScript의 경우 이름은 `APPSYNC_JS`, 런타임은 `1.0.0`이어야 합니다.

  1. `code` 또는 함수의 요청 및 응답 핸들러. 수동으로 입력할 수도 있지만 .txt 파일(또는 유사한 형식)에 추가한 다음 인수로 전달하는 것이 훨씬 쉽습니다.
**참고**  
쿼리 코드는 인수로 전달되는 파일에 있습니다.  

     ```
     import { util } from '@aws-appsync/utils';
     
     /**
      * Performs a scan on the dynamodb data source
      */
     export function request(ctx) {
       return { operation: 'Scan' };
     }
     
     /**
      * return a list of scanned post items
      */
     export function response(ctx) {
       return ctx.result.items;
     }
     ```

  예를 들어 명령은 다음과 같을 수 있습니다.

  ```
  aws appsync create-function \
  --api-id abcdefghijklmnopqrstuvwxyz \
  --name get_posts_func_1 \
  --data-source-name table-for-posts \
  --runtime name=APPSYNC_JS,runtimeVersion=1.0.0 \
  --code file://~/path/to/file/{filename}.{fileType}
  ```

  CLI에서 출력이 반환됩니다. 다음은 그 예입니다.

  ```
  {
      "functionConfiguration": {
          "functionId": "ejglgvmcabdn7lx75ref4qeig4",
          "functionArn": "arn:aws:appsync:us-west-2:107289374856:apis/abcdefghijklmnopqrstuvwxyz/functions/ejglgvmcabdn7lx75ref4qeig4",
          "name": "get_posts_func_1",
          "dataSourceName": "table-for-posts",
          "maxBatchSize": 0,
          "runtime": {
              "name": "APPSYNC_JS",
              "runtimeVersion": "1.0.0"
          },
          "code": "Code output goes here"
      }
  }
  ```
**참고**  
함수를 해석기에 연결하는 데 사용되므로 `functionId`를 어딘가에 기록해 두어야 합니다.

**해석기 생성**
+ `[create-resolver](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-resolver.html)` 명령을 실행하여 `Query`에 대한 파이프라인 함수를 생성합니다.

  이 특정 명령에 대해 몇 가지 파라미터를 입력해야 합니다.

  1. API의 `api-id`.

  1. `type-name` 또는 스키마의 특수 객체 유형(쿼리, 변형, 구독).

  1. `field-name` 또는 해석기를 연결하려는 특수 객체 유형 내의 필드 작업.

  1. 단위 또는 파이프라인 해석기를 지정하는 `kind`. 파이프라인 함수를 활성화하려면 이 값을 `PIPELINE`으로 설정합니다.

  1. `pipeline-config` 또는 해석기에 연결할 함수. 함수의 `functionId` 값을 알고 있어야 합니다. 목록 순서가 중요합니다.

  1. `runtime`으로, 여기에서는 `APPSYNC_JS`(자바스크립트)였습니다. `runtimeVersion`은 현재 `1.0.0`입니다.

  1. `code`로, 사전 및 사후 단계 핸들러를 포함합니다.
**참고**  
쿼리 코드는 인수로 전달되는 파일에 있습니다.  

     ```
     import { util } from '@aws-appsync/utils';
     
     /**
      * Sends a request to `put` an item in the DynamoDB data source
      */
     export function request(ctx) {
       const { id, ...values } = ctx.args;
       return {
         operation: 'PutItem',
         key: util.dynamodb.toMapValues({ id }),
         attributeValues: util.dynamodb.toMapValues(values),
       };
     }
     
     /**
      * returns the result of the `put` operation
      */
     export function response(ctx) {
       return ctx.result;
     }
     ```

  예를 들어 명령은 다음과 같을 수 있습니다.

  ```
  aws appsync create-resolver \
  --api-id abcdefghijklmnopqrstuvwxyz \
  --type-name Query \
  --field-name getPost \
  --kind PIPELINE \
  --pipeline-config functions=ejglgvmcabdn7lx75ref4qeig4 \
  --runtime name=APPSYNC_JS,runtimeVersion=1.0.0 \
  --code file:///path/to/file/{filename}.{fileType}
  ```

  CLI에서 출력이 반환됩니다. 다음은 그 예입니다.

  ```
  {
      "resolver": {
          "typeName": "Mutation",
          "fieldName": "getPost",
          "resolverArn": "arn:aws:appsync:us-west-2:107289374856:apis/abcdefghijklmnopqrstuvwxyz/types/Mutation/resolvers/getPost",
          "kind": "PIPELINE",
          "pipelineConfig": {
              "functions": [
                  "ejglgvmcabdn7lx75ref4qeig4"
              ]
          },
          "maxBatchSize": 0,
          "runtime": {
              "name": "APPSYNC_JS",
              "runtimeVersion": "1.0.0"
          },
          "code": "Code output goes here"
      }
  }
  ```

------
#### [ CDK ]

**작은 정보**  
CDK를 사용하기 전에 CDK의 [공식 설명서](https://docs.aws.amazon.com/cdk/v2/guide/home.html)와 [CDK 참조](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync-readme.html)를 검토 AWS AppSync하는 것이 좋습니다.  
아래 나열된 단계는 특정 리소스를 추가하는 데 사용되는 스니펫의 일반적인 예시만 보여줍니다. 프로덕션 코드에서는 이 예시가 올바르게 작동하는 솔루션이 **아닙니다**. 또한 이미 작동하는 앱을 가지고 있는 것으로 가정합니다.

기본 앱에는 다음 항목이 필요합니다.

1. 서비스 가져오기 지시문

1. 스키마 코드

1. 데이터 원본 생성기

1. 함수 코드

1. 해석기 코드

[스키마 설계](https://docs.aws.amazon.com/appsync/latest/devguide/designing-your-schema.html) 및 [데이터 원본 연결](https://docs.aws.amazon.com/appsync/latest/devguide/attaching-a-data-source.html) 섹션을 통해 스택 파일에 다음과 같은 형식의 가져오기 지시문이 포함된다는 것을 알 수 있습니다.

```
import * as x from 'x'; # import wildcard as the 'x' keyword from 'x-service'
import {a, b, ...} from 'c'; # import {specific constructs} from 'c-service'
```

**참고**  
이전 단원에서는 AWS AppSync 구문을 가져오는 방법만 설명했습니다. 실제 코드에서는 앱을 실행하는 것만으로도 더 많은 서비스를 가져와야 합니다. 이 예제에서는 매우 간단한 CDK 앱을 생성하려는 경우 최소한 DynamoDB 테이블인 데이터 소스와 함께 AWS AppSync 서비스를 가져옵니다. 또한 앱을 배포하기 위해 몇 가지 추가 구성을 가져와야 했습니다.  

```
import * as cdk from 'aws-cdk-lib';
import * as appsync from 'aws-cdk-lib/aws-appsync';
import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';
import { Construct } from 'constructs';
```
각 내용을 요약하면 다음과 같습니다.  
`import * as cdk from 'aws-cdk-lib';`: 이렇게 하면 CDK 앱 및 스택과 같은 구성을 정의할 수 있습니다. 여기에는 메타데이터 조작과 같은 애플리케이션에 유용한 유틸리티 함수도 포함되어 있습니다. 이 가져오기 지시문에 익숙하지만 여기에서 cdk 코어 라이브러리가 사용되지 않는 이유가 궁금하다면 [마이그레이션](https://docs.aws.amazon.com/cdk/v2/guide/migrating-v2.html) 페이지를 참조하세요.
`import * as appsync from 'aws-cdk-lib/aws-appsync';`: [AWS AppSync 서비스](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync-readme.html)를 가져옵니다.
`import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';`: [DynamoDB 서비스](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_dynamodb-readme.html)를 가져옵니다.
`import { Construct } from 'constructs';`: 루트 [구성](https://docs.aws.amazon.com/cdk/v2/guide/constructs.html)을 정의하는 데 필요합니다.

가져오기 유형은 호출하는 서비스에 따라 달라집니다. 예를 보려면 CDK 설명서를 살펴보세요. 페이지 상단의 스키마는 CDK 앱의 파일로, `.graphql` 파일과는 별개입니다. 스택 파일에서 다음 형식을 사용하여 새 GraphQL과 연결할 수 있습니다.

```
const add_api = new appsync.GraphqlApi(this, 'graphQL-example', {
  name: 'my-first-api',
  schema: appsync.SchemaFile.fromAsset(path.join(__dirname, 'schema.graphql')),
});
```

**참고**  
범위 `add_api`에서는 `appsync.GraphqlApi(scope: Construct, id: string , props: GraphqlApiProps)` 뒤에 오는 `new` 키워드를 사용하여 새로운 GraphQL API를 추가합니다. 범위는 `this`, CFN id는 `graphQL-example`이며, 속성은 `my-first-api`(콘솔의 API 이름) 및 `schema.graphql`(스키마 파일의 절대 경로) 입니다.

데이터 원본을 추가하려면 먼저 데이터 원본을 스택에 추가해야 합니다. 그런 다음 소스별 메서드를 사용하여 GraphQL API와 연결해야 합니다. 해석기 함수를 만들면 연결이 이루어집니다. 그 동안 `dynamodb.Table`을 사용하여 DynamoDB 테이블을 생성하는 예제를 살펴보겠습니다.

```
const add_ddb_table = new dynamodb.Table(this, 'posts-table', {
  partitionKey: {
    name: 'id',
    type: dynamodb.AttributeType.STRING,
  },
});
```

**참고**  
예제에서 이 방법을 사용한다면 CFN ID가 `posts-table`이고 파티션 키가 `id (S)`인 새로운 DynamoDB 테이블을 추가하게 됩니다.

다음으로 스택 파일에 해석기를 구현해야 합니다. 다음은 DynamoDB 테이블의 모든 항목을 스캔하는 간단한 쿼리의 예입니다.

```
const add_func = new appsync.AppsyncFunction(this, 'func-get-posts', {
  name: 'get_posts_func_1',
  add_api,
  dataSource: add_api.addDynamoDbDataSource('table-for-posts', add_ddb_table),
  code: appsync.Code.fromInline(`
      export function request(ctx) {
        return { operation: 'Scan' };
      }

      export function response(ctx) {
        return ctx.result.items;
      }
  `),
  runtime: appsync.FunctionRuntime.JS_1_0_0,
});

new appsync.Resolver(this, 'pipeline-resolver-get-posts', {
  add_api,
  typeName: 'Query',
  fieldName: 'getPost',
  code: appsync.Code.fromInline(`
      export function request(ctx) {
        return {};
      }

      export function response(ctx) {
        return ctx.prev.result;
      }
 `),
  runtime: appsync.FunctionRuntime.JS_1_0_0,
  pipelineConfig: [add_func],
});
```

**참고**  
먼저 `add_func`라는 함수를 만들었습니다. 이 생성 순서는 다소 직관적이지 않은 것처럼 보일 수 있지만, 해석기 자체를 만들기 전에 파이프라인 해석기에 함수를 만들어야 합니다. 함수는 다음과 같은 형식을 따릅니다.  

```
AppsyncFunction(scope: Construct, id: string, props: AppsyncFunctionProps)
```
범위는 `this`, CFN id는 `func-get-posts`였으며, 속성에는 실제 함수 세부 정보가 포함되어 있습니다. 속성 안에는 다음이 포함되었습니다.  
 AWS AppSync 콘솔에 있을 함수`name`의 입니다(`get_posts_func_1`).
앞서 만든 GraphQL API(`add_api`).
데이터 원본. 데이터 원본을 GraphQL API 값에 연결한 다음 함수에 연결하는 지점입니다. 생성한 테이블(`add_ddb_table`)을 가져와서 `GraphqlApi` 메서드([https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.GraphqlApi.html#addwbrdynamowbrdbwbrdatawbrsourceid-table-options](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.GraphqlApi.html#addwbrdynamowbrdbwbrdatawbrsourceid-table-options)) 중 하나를 사용하여 GraphQL API(`add_api`)에 연결합니다. ID 값(`table-for-posts`)은 AWS AppSync 콘솔에 있는 데이터 원본의 이름입니다. 소스별 메서드 목록은 다음 페이지를 참조하세요.  
[ DynamoDbDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.DynamoDbDataSource.html) 
 [ EventBridgeDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.EventBridgeDataSource.html) 
 [ HttpDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.HttpDataSource.html) 
 [ LambdaDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.LambdaDataSource.html) 
 [ NoneDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.NoneDataSource.html) 
 [ OpenSearchDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.OpenSearchDataSource.html) 
 [ RdsDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.RdsDataSource.html) 
코드에는 간단한 스캔 및 반환인 함수의 요청 및 응답 핸들러가 포함되어 있습니다.
런타임은 APPSYNC\$1JS 런타임 버전 1.0.0을 사용하도록 지정합니다. 참고로 이 버전은 현재 APPSYNC\$1JS에서 사용할 수 있는 유일한 버전입니다.
다음으로 함수를 파이프라인 해석기에 연결해야 합니다. 다음과 같은 형식을 사용하여 해석기를 생성했습니다.  

```
Resolver(scope: Construct, id: string, props: ResolverProps)
```
범위는 `this`, CFN id는 `pipeline-resolver-get-posts`였으며, 속성에는 실제 함수 세부 정보가 포함되어 있습니다. 속성 안에는 다음이 포함되었습니다.  
앞서 만든 GraphQL API(`add_api`).
특수 객체 유형 이름. 쿼리 작업이므로 `Query` 값을 추가하기만 하면 됩니다.
필드 이름(`getPost`)은 `Query` 유형 아래의 스키마에 있는 필드 이름입니다.
코드에는 사전 및 사후 핸들러가 포함되어 있습니다. 이 예제는 함수가 작업을 수행한 후 컨텍스트에 있었던 모든 결과를 반환합니다.
런타임은 APPSYNC\$1JS 런타임 버전 1.0.0을 사용하도록 지정합니다. 참고로 이 버전은 현재 APPSYNC\$1JS에서 사용할 수 있는 유일한 버전입니다.
파이프라인 구성에는 생성한 함수(`add_func`)에 대한 참조가 포함되어 있습니다.

------

이 예제에서 발생한 일을 요약하기 위해 요청 및 응답 핸들러를 구현한 AWS AppSync 함수를 보았습니다. 함수는 데이터 원본과의 상호 작용을 담당했습니다. 요청 핸들러가 DynamoDB 데이터 소스에 대해 수행할 `Scan` 작업에 대해 AWS AppSync지시하는 작업을에 보냈습니다. 응답 핸들러는 항목의 목록(`ctx.result.items`)을 반환했습니다. 그런 다음 항목 목록이 `Post` GraphQL 유형에 자동으로 매핑되었습니다.

## 기본 변형 해석기 생성
<a name="creating-basic-mutation-resolvers-js"></a>

이 섹션에서는 기본 변형 해석기를 생성하는 방법을 보여 줍니다.

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

1. 에 로그인 AWS Management Console 하고 [AppSync 콘솔](https://console.aws.amazon.com/appsync/)을 엽니다.

   1. **API 대시보드**에서 GraphQL API를 선택합니다.

   1. **사이드바**에서 **스키마**를 선택합니다.

1. **해석기** 섹션 및 **변형** 유형에서 필드 옆에 있는 **연결**을 선택합니다.
**참고**  
이 예제에서는 테이블에 `Post` 객체를 추가하는 `createPost`에 대한 해석기를 연결합니다. 마지막 섹션과 동일한 DynamoDB 테이블을 사용한다고 가정해 보겠습니다. 파티션 키는 `id`로 설정되어 있고 비어 있습니다.

1. **해석기 연결** 페이지의 **해석기 유형**에서 `pipeline resolvers`를 선택합니다. 참고로 해석기에 대한 추가 정보는 [여기](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-components.html)에서 확인할 수 있습니다. **해석기 런타임**의 경우 `APPSYNC_JS`를 선택하여 JavaScript 런타임을 활성화하세요.

1. 이 API에 [캐싱](https://docs.aws.amazon.com/appsync/latest/devguide/enabling-caching.html)을 활성화할 수 있습니다. 그러나 지금은 이 기능을 끄는 것이 좋습니다. **생성(Create)**을 선택합니다.

1. **함수 추가**를 선택한 다음 **새 함수 생성**을 선택합니다. 또는 선택할 수 있는 **함수 생성** 버튼이 표시될 수도 있습니다.

   1. 데이터 원본을 선택합니다. 변형을 사용하여 조작할 데이터가 들어 있는 원본이어야 합니다.

   1. `Function name`을 입력합니다.

   1. **함수 코드**에서 함수의 동작을 구현해야 합니다. 이는 변형이므로 요청은 간접적으로 호출된 데이터 원본에서 일부 상태 변경 작업을 수행하는 것이 이상적입니다. 결과는 응답 함수에 의해 처리됩니다.
**참고**  
`createPost`는 파라미터를 데이터로 사용하여 테이블에 새 `Post`를 추가하거나 '퍼팅'합니다. 다음과 같이 추가할 수 있습니다.  

      ```
      import { util } from '@aws-appsync/utils';
      
      /**
       * Sends a request to `put` an item in the DynamoDB data source
       */
      export function request(ctx) {
        return {
          operation: 'PutItem',
          key: util.dynamodb.toMapValues({id: util.autoId()}),
          attributeValues: util.dynamodb.toMapValues(ctx.args.input),
        };
      }
      
      /**
       * returns the result of the `put` operation
       */
      export function response(ctx) {
        return ctx.result;
      }
      ```
이 단계에서 `request` 및 `response` 함수도 추가했습니다.  
`request`: 요청 핸들러는 컨텍스트를 인수로 받아들입니다. 요청 핸들러 반환 문은 내장된 DynamoDB 작업인 [https://docs.aws.amazon.com//appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-putitem](https://docs.aws.amazon.com//appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-putitem) 명령을 수행합니다(예시는 [여기](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/getting-started-step-2.html) 또는 [여기](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/WorkingWithItems.html#WorkingWithItems.WritingData) 참조). `PutItem` 명령은 파티션 `key` 값(`util.autoid()`에서 자동으로 생성됨)과 컨텍스트 인수 입력의 `attributes`(요청 시 전달할 값)를 가져와 DynamoDB 테이블에 `Post` 객체를 추가합니다. `key`는 `id`이고 `attributes`는 `date` 및 `title` 필드 인수입니다. 둘 다 DynamoDB 테이블에서 작동하도록 [https://docs.aws.amazon.com//appsync/latest/devguide/dynamodb-helpers-in-util-dynamodb-js.html#utility-helpers-in-toMap-js](https://docs.aws.amazon.com//appsync/latest/devguide/dynamodb-helpers-in-util-dynamodb-js.html#utility-helpers-in-toMap-js) 도우미를 통해 미리 형식이 지정되어 있습니다.
`response`: 응답은 업데이트된 컨텍스트를 수락하고 요청 핸들러의 결과를 반환합니다.

   1. 완료했으면 **생성**을 선택합니다.

1. 해석기 화면으로 돌아가서 **함수** 아래에서 **함수 추가** 드롭다운을 선택하고 함수를 함수 목록에 추가합니다.

1. **저장**을 선택하여 해석기를 업데이트합니다.

------
#### [ CLI ]

**함수를 추가하는 방법**
+ `[create-function](https://docs.aws.amazon.com/cli/latest/reference/appsync/create-function.html)` 명령을 사용하여 파이프라인 해석기용 함수를 생성합니다.

  이 특정 명령에 대해 몇 가지 파라미터를 입력해야 합니다.

  1. API의 `api-id`.

  1.  AWS AppSync 콘솔에 있는 함수`name`의 입니다.

  1. `data-source-name` 또는 함수가 사용할 데이터 원본의 이름. 이미 생성되어 AWS AppSync 서비스에 있는 GraphQL API에 연결되어 있어야 합니다.

  1. `runtime` 또는 함수의 환경 및 언어. JavaScript의 경우 이름은 `APPSYNC_JS`, 런타임은 `1.0.0`이어야 합니다.

  1. `code` 또는 함수의 요청 및 응답 핸들러. 수동으로 입력할 수도 있지만 .txt 파일(또는 유사한 형식)에 추가한 다음 인수로 전달하는 것이 훨씬 쉽습니다.
**참고**  
쿼리 코드는 인수로 전달되는 파일에 있습니다.  

     ```
     import { util } from '@aws-appsync/utils';
     
     /**
      * Sends a request to `put` an item in the DynamoDB data source
      */
     export function request(ctx) {
       return {
         operation: 'PutItem',
         key: util.dynamodb.toMapValues({id: util.autoId()}),
         attributeValues: util.dynamodb.toMapValues(ctx.args.input),
       };
     }
     
     /**
      * returns the result of the `put` operation
      */
     export function response(ctx) {
       return ctx.result;
     }
     ```

  예를 들어 명령은 다음과 같을 수 있습니다.

  ```
  aws appsync create-function \
  --api-id abcdefghijklmnopqrstuvwxyz \
  --name add_posts_func_1 \
  --data-source-name table-for-posts \
  --runtime name=APPSYNC_JS,runtimeVersion=1.0.0 \
  --code file:///path/to/file/{filename}.{fileType}
  ```

  CLI에서 출력이 반환됩니다. 다음은 그 예입니다.

  ```
  {
      "functionConfiguration": {
          "functionId": "vulcmbfcxffiram63psb4dduoa",
          "functionArn": "arn:aws:appsync:us-west-2:107289374856:apis/abcdefghijklmnopqrstuvwxyz/functions/vulcmbfcxffiram63psb4dduoa",
          "name": "add_posts_func_1",
          "dataSourceName": "table-for-posts",
          "maxBatchSize": 0,
          "runtime": {
              "name": "APPSYNC_JS",
              "runtimeVersion": "1.0.0"
          },
          "code": "Code output foes here"
      }
  }
  ```
**참고**  
함수를 해석기에 연결하는 데 사용되므로 `functionId`를 어딘가에 기록해 두어야 합니다.

**해석기 생성**
+ `[create-resolver](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-resolver.html)` 명령을 실행하여 `Mutation`에 대한 파이프라인 함수를 생성합니다.

  이 특정 명령에 대해 몇 가지 파라미터를 입력해야 합니다.

  1. API의 `api-id`.

  1. `type-name` 또는 스키마의 특수 객체 유형(쿼리, 변형, 구독).

  1. `field-name` 또는 해석기를 연결하려는 특수 객체 유형 내의 필드 작업.

  1. 단위 또는 파이프라인 해석기를 지정하는 `kind`. 파이프라인 함수를 활성화하려면 이 값을 `PIPELINE`으로 설정합니다.

  1. `pipeline-config` 또는 해석기에 연결할 함수. 함수의 `functionId` 값을 알고 있어야 합니다. 목록 순서가 중요합니다.

  1. `runtime`으로, 여기에서는 `APPSYNC_JS`(자바스크립트)였습니다. `runtimeVersion`은 현재 `1.0.0`입니다.

  1. `code`로, 사전 및 사후 단계를 포함합니다.
**참고**  
쿼리 코드는 인수로 전달되는 파일에 있습니다.  

     ```
     import { util } from '@aws-appsync/utils';
     
     /**
      * Sends a request to `put` an item in the DynamoDB data source
      */
     export function request(ctx) {
       const { id, ...values } = ctx.args;
       return {
         operation: 'PutItem',
         key: util.dynamodb.toMapValues({ id }),
         attributeValues: util.dynamodb.toMapValues(values),
       };
     }
     
     /**
      * returns the result of the `put` operation
      */
     export function response(ctx) {
       return ctx.result;
     }
     ```

  예를 들어 명령은 다음과 같을 수 있습니다.

  ```
  aws appsync create-resolver \
  --api-id abcdefghijklmnopqrstuvwxyz \
  --type-name Mutation \
  --field-name createPost \
  --kind PIPELINE \
  --pipeline-config functions=vulcmbfcxffiram63psb4dduoa \
  --runtime name=APPSYNC_JS,runtimeVersion=1.0.0 \
  --code file:///path/to/file/{filename}.{fileType}
  ```

  CLI에서 출력이 반환됩니다. 다음은 그 예입니다.

  ```
  {
      "resolver": {
          "typeName": "Mutation",
          "fieldName": "createPost",
          "resolverArn": "arn:aws:appsync:us-west-2:107289374856:apis/abcdefghijklmnopqrstuvwxyz/types/Mutation/resolvers/createPost",
          "kind": "PIPELINE",
          "pipelineConfig": {
              "functions": [
                  "vulcmbfcxffiram63psb4dduoa"
              ]
          },
          "maxBatchSize": 0,
          "runtime": {
              "name": "APPSYNC_JS",
              "runtimeVersion": "1.0.0"
          },
          "code": "Code output goes here"
      }
  }
  ```

------
#### [ CDK ]

**작은 정보**  
CDK를 사용하기 전에 CDK의 [공식 설명서](https://docs.aws.amazon.com/cdk/v2/guide/home.html)와 [CDK 참조](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync-readme.html)를 검토 AWS AppSync하는 것이 좋습니다.  
아래 나열된 단계는 특정 리소스를 추가하는 데 사용되는 스니펫의 일반적인 예시만 보여줍니다. 프로덕션 코드에서는 이 예시가 올바르게 작동하는 솔루션이 **아닙니다**. 또한 이미 작동하는 앱을 가지고 있는 것으로 가정합니다.
+ 변형을 만들려면 같은 프로젝트에 참여하고 있다고 가정하고 쿼리처럼 스택 파일에 추가하면 됩니다. 테이블에 새 `Post`를 추가하는 변형에 대한 수정된 함수와 해석기는 다음과 같습니다.

  ```
  const add_func_2 = new appsync.AppsyncFunction(this, 'func-add-post', {
    name: 'add_posts_func_1',
    add_api,
    dataSource: add_api.addDynamoDbDataSource('table-for-posts-2', add_ddb_table),
        code: appsync.Code.fromInline(`
            export function request(ctx) {
              return {
                operation: 'PutItem',
                key: util.dynamodb.toMapValues({id: util.autoId()}),
                attributeValues: util.dynamodb.toMapValues(ctx.args.input),
              };
            }
  
            export function response(ctx) {
              return ctx.result;
            }
        `), 
    runtime: appsync.FunctionRuntime.JS_1_0_0,
  });
  
  new appsync.Resolver(this, 'pipeline-resolver-create-posts', {
    add_api,
    typeName: 'Mutation',
    fieldName: 'createPost',
        code: appsync.Code.fromInline(`
            export function request(ctx) {
              return {};
            }
  
            export function response(ctx) {
              return ctx.prev.result;
            }
        `),
    runtime: appsync.FunctionRuntime.JS_1_0_0,
    pipelineConfig: [add_func_2],
  });
  ```
**참고**  
이 변형과 쿼리는 구조가 비슷하므로 변형을 만들기 위해 변경한 내용만 설명하겠습니다.  
테이블에 `Posts`를 추가한다는 사실을 반영하기 위해 함수에서 CFN id를 `func-add-post`로 변경하고 이름을 `add_posts_func_1`로 변경했습니다. 데이터 소스에서는 `addDynamoDbDataSource` 메서드에 필요하기 `table-for-posts-2` 때문에 AWS AppSync 콘솔의 테이블(`add_ddb_table`)에 로 새 연결을 만들었습니다. 이 새 연결은 이전에 생성한 것과 동일한 테이블을 계속 사용하고 있지만 이제 AWS AppSync 콘솔에 두 개의 연결이 있습니다. 하나는 쿼리용`table-for-posts`이고 다른 하나는 변형용입니다`table-for-posts-2`. `id` 값을 자동으로 생성하고 나머지 필드에 대해 클라이언트의 입력을 수락하여 `Post`를 추가하도록 코드가 변경되었습니다.  
테이블에 `Posts`를 추가한다는 사실을 반영하기 위해 해석기에서 id 값을 `pipeline-resolver-create-posts`로 변경했습니다. 스키마에 변형를 반영하기 위해 유형 이름은 `Mutation`으로, 이름은 `createPost`로 변경되었습니다. 파이프라인 구성이 새 변형 함수 `add_func_2`로 설정되었습니다.

------

이 예제에서 일어나는 일을 요약하기 위해는 `createPost` 필드에 정의된 인수를 GraphQL 스키마에서 DynamoDB 작업으로 AWS AppSync 자동 변환합니다. 이 예제에서는 `util.autoId()` 도우미를 사용하여 자동으로 생성되는 `id`의 키를 사용하여 DynamoDB에 레코드를 저장합니다. AWS AppSync 콘솔 또는 기타에서 수행된 요청의 컨텍스트 인수(`ctx.args.input`)에 전달하는 다른 모든 필드는 테이블의 속성으로 저장됩니다. 키와 특성 모두 `util.dynamodb.toMapValues(values)` 도우미를 사용하여 호환되는 DynamoDB 형식에 자동으로 매핑됩니다.

AWS AppSync 는 해석기 편집을 위한 테스트 및 디버그 워크플로도 지원합니다. 모의 `context` 객체를 사용하여 간접 호출 전에 템플릿의 변환된 값을 확인할 수 있습니다. 선택적으로 쿼리를 실행할 때 대화식으로 데이터 원본에 대한 전체 요청을 볼 수 있습니다. 자세한 내용은 [해석기 테스트 및 디버깅(JavaScript)](https://docs.aws.amazon.com/appsync/latest/devguide/test-debug-resolvers-js.html) 및 [모니터링 및 로깅](https://docs.aws.amazon.com/appsync/latest/devguide/monitoring.html#aws-appsync-monitoring)을 참조하세요.

## 고급 해석기
<a name="advanced-resolvers-js"></a>

[스키마 설계](designing-your-schema.md#aws-appsync-designing-your-schema)의 선택적 페이지 매김 섹션을 따르는 경우에도 페이지 매김을 사용하려면 요청에 해석기를 추가해야 합니다. 이 예제에서는 한 번에 요청된 항목 중 일부만 반환하도록 `getPosts`라는 쿼리 페이지 매김을 사용했습니다. 해당 필드의 해석기 코드는 다음과 같을 수 있습니다.

```
/**
 * Performs a scan on the dynamodb data source
 */
export function request(ctx) {
  const { limit = 20, nextToken } = ctx.args;
  return { operation: 'Scan', limit, nextToken };
}

/**
 * @returns the result of the `put` operation
 */
export function response(ctx) {
  const { items: posts = [], nextToken } = ctx.result;
  return { posts, nextToken };
}
```

요청에서는 요청의 컨텍스트를 전달합니다. `limit`은 *20*으로, 첫 번째 쿼리에서 최대 20개의 `Posts`를 반환합니다. `nextToken` 커서는 데이터 원본의 첫 번째 `Post` 항목에 고정됩니다. 이러한 값은 인수로 전달됩니다. 그런 다음 요청은 첫 번째 `Post`부터 시작하여 스캔 제한 횟수까지 스캔을 수행합니다. 데이터 원본은 결과를 컨텍스트에 저장하고, 이 결과는 응답에 전달됩니다. 응답은 검색된 `Posts`를 반환한 다음 `nextToken`을 한도 바로 뒤의 `Post` 항목으로 설정합니다. 정확히 동일한 작업을 수행하지만 첫 번째 쿼리 직후의 오프셋부터 시작하도록 다음 요청이 전송됩니다. 이러한 종류의 요청은 병렬로 수행되지 않고 순차적으로 수행된다는 점에 유의하세요.

# AWS AppSync에서 해석기 테스트 및 디버깅(JavaScript)
<a name="test-debug-resolvers-js"></a>

AWS AppSync는 데이터 소스에 대해 GraphQL 필드에서 해석기를 실행합니다. 파이프라인 해석기로 작업할 때 함수는 데이터 소스와 상호 작용합니다. [JavaScript 해석기 개요](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html) 설명된 대로 함수는 JavaScript로 작성되고 `APPSYNC_JS` 런타임에서 실행되는 요청 및 응답 핸들러를 사용하여 데이터 소스와 통신합니다. 이를 통해 데이터 소스와 통신하기 전과 후에 사용자 지정 로직 및 조건을 제공할 수 있습니다.

개발자가 이러한 해석기를 작성, 테스트 및 디버깅할 수 있도록 AWS AppSync 콘솔은 모의 데이터가 포함된 GraphQL 요청 및 응답을 개별 필드 해석기로 생성하는 도구도 제공합니다. 또한 AWS AppSync 콘솔에서 쿼리, 변형 및 구독을 수행하고 Amazon CloudWatch의 전체 요청에 대한 자세한 로그 스트림을 볼 수 있습니다. 여기에는 데이터 소스의 결과가 포함됩니다.

## 모의 데이터를 사용하여 테스트
<a name="testing-with-mock-data-js"></a>

GraphQL 해석기가 호출되는 경우 이 해석기에는 요청에 대한 관련 정보를 포함하는 `context` 객체가 들어 있습니다. 여기에는 클라이언트의 인수, 자격 증명 정보 및 상위 GraphQL 필드의 데이터가 포함됩니다. 또한 데이터 소스의 결과를 저장하며, 이러한 결과는 응답 핸들러에서 사용할 수 있습니다. 이 구조와 프로그래밍 시 사용할 수 있는 도우미 유틸리티에 대한 자세한 내용은 [해석기 컨텍스트 객체 참조](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference-js.html) 단원을 참조하세요.

해석기 함수를 작성하거나 편집할 때 *mock* 또는 *test context* 객체를 콘솔 편집기로 전달할 수 있습니다. 이렇게 하면 데이터 원본에 대해 실행하지 않고도 요청과 응답 핸들러가 어떻게 평가되는지 알아볼 수 있습니다. 예를 들면 테스트 `firstname: Shaggy` 인수를 전달하고 템플릿 코드에서 `ctx.args.firstname`을 사용하면 이 인수가 어떻게 평가되는지 볼 수 있습니다. 또한 `util.autoId()` 또는 `util.time.nowISO8601()` 같은 유틸리티 도우미의 평가도 테스트할 수 있습니다.

### 해석기 테스트
<a name="test-a-resolver-js"></a>

이 예제에서는 AWS AppSync 콘솔을 사용하여 해석기를 테스트합니다.

1. 에 로그인 AWS Management Console 하고 [AppSync 콘솔](https://console.aws.amazon.com/appsync/)을 엽니다.

   1. **API 대시보드**에서 GraphQL API를 선택합니다.

   1. **사이드바**에서 **함수**를 선택합니다.

1. 기존 함수를 선택합니다.

1. **함수 업데이트** 페이지 상단에서 **테스트 컨텍스트 선택**을 선택한 다음 **새 컨텍스트 생성**을 선택합니다.

1. 샘플 컨텍스트 객체를 선택하거나 아래 **테스트 컨텍스트 구성** 창에서 JSON을 수동으로 채웁니다.

1. **텍스트 컨텍스트 이름**을 입력합니다.

1. **저장** 버튼을 선택합니다.

1. 이 모의 컨텍스트 객체를 사용하여 해석기를 평가하려면 **테스트 실행**을 선택합니다.

보다 실용적인 예로, 객체에 대한 자동 ID 생성을 사용하고 이를 Amazon DynamoDB에 저장하는 `Dog`의 GraphQL 유형을 저장하는 앱이 있다고 가정해 보겠습니다. 또한 GraphQL 뮤테이션의 인수에서 일부 값을 작성하고 특정 사용자만 응답을 볼 수 있도록 허용하려고 합니다. 다음 코드 조각은 스키마의 모양을 보여줍니다.

```
type Dog {
  breed: String
  color: String
}

type Mutation {
  addDog(firstname: String, age: Int): Dog
}
```

 AWS AppSync 함수를 작성하여 `addDog` 해석기에 추가하여 변형을 처리할 수 있습니다. AWS AppSync 함수를 테스트하려면 다음 예제와 같이 컨텍스트 객체를 채울 수 있습니다. 다음 객체에는 `name` 및 `age` 클라이언트의 인수와 `identity` 객체에 채워진 `username`이 있습니다.

```
{
    "arguments" : {
        "firstname": "Shaggy",
        "age": 4
    },
    "source" : {},
    "result" : {
        "breed" : "Miniature Schnauzer",
        "color" : "black_grey"
    },
    "identity": {
        "sub" : "uuid",
        "issuer" : " https://cognito-idp.{region}.amazonaws.com/{userPoolId}",
        "username" : "Nadia",
        "claims" : { },
        "sourceIp" :[  "x.x.x.x" ],
        "defaultAuthStrategy" : "ALLOW"
    }
}
```

다음 코드를 사용하여 AWS AppSync 함수를 테스트할 수 있습니다.

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

export function request(ctx) {
  return {
    operation: 'PutItem',
    key: util.dynamodb.toMapValues({ id: util.autoId() }),
    attributeValues: util.dynamodb.toMapValues(ctx.args),
  };
}

export function response(ctx) {
  if (ctx.identity.username === 'Nadia') {
    console.log("This request is allowed")
    return ctx.result;
  }
  util.unauthorized();
}
```

평가된 요청 및 응답 핸들러에는 테스트 컨텍스트 객체의 데이터와 `util.autoId()`에서 생성된 값이 포함됩니다. 또한, `username`을 `Nadia` 이외의 값으로 변경해야 했다면 권한 부여 확인이 실패하므로 결과가 반환되지 않습니다. 세분화된 액세스 제어에 대한 자세한 내용은 [권한 부여 사용 사례](security-authorization-use-cases.md#aws-appsync-security-authorization-use-cases) 단원을 참조하세요.

### AWS AppSync의 APIs를 사용하여 요청 및 응답 핸들러 테스트
<a name="testing-with-appsync-api-js"></a>

`EvaluateCode` API 명령어를 사용하여 모의 데이터로 코드를 원격 테스트할 수 있습니다. 명령어를 시작하려면 정책에 `appsync:evaluateMappingCode` 권한을 추가했는지 확인하세요. 예제:

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

****  

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

------

[AWS CLI](https://aws.amazon.com/cli/) 또는 [AWS SDK](https://aws.amazon.com/tools/)를 사용하여 명령을 활용할 수 있습니다. 예를 들어 이전 섹션의 `Dog` 스키마와 해당 AWS AppSync 함수 요청 및 응답 핸들러를 살펴보겠습니다. 로컬 스테이션에서 CLI를 사용하여 코드를 `code.js`라는 파일에 저장한 다음 `context` 객체를 `context.json`이라는 파일에 저장합니다. 쉘에서 다음 명령을 실행합니다.

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

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

```
{
    "evaluationResult": "{\"breed\":\"Miniature Schnauzer\",\"color\":\"black_grey\"}",
    "logs": [
        "INFO - code.js:13:5: \"This request is allowed\""
    ]
}
```

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

```
{
  "breed": "Miniature Schnauzer",
  "color": "black_grey"
}
```

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

## 라이브 쿼리 디버깅
<a name="debugging-a-live-query-js"></a>

프로덕션 애플리케이션을 디버깅하기 위한 end-to-end 테스트 및 로깅을 대체할 수 없습니다. AWS AppSync를 사용하면 Amazon CloudWatch를 사용하여 오류와 전체 요청 세부 정보를 로깅할 수 있습니다. 또한 AWS AppSync 콘솔을 사용하여 각 요청에 대한 GraphQL 쿼리, 변형 및 구독과 라이브 스트림 로그 데이터를 테스트하고 쿼리 편집기로 다시 전송하여 실시간으로 디버깅할 수 있습니다. 구독의 경우 로그는 연결-시간 정보를 표시합니다.

이를 수행하려면 [모니터링 및 로깅](monitoring.md#aws-appsync-monitoring)에 설명된 대로 Amazon CloudWatch 로그를 미리 활성화해야 합니다. 그런 다음 AWS AppSync 콘솔에서 **쿼리** 탭을 선택한 다음 유효한 GraphQL 쿼리를 입력합니다. 오른쪽 하단 섹션에서 **로그** 창을 클릭하고 드래그하여 로그 보기를 엽니다. 페이지 맨 위에 있는 ‘재생’ 화살표 아이콘을 선택하여 GraphQL 쿼리를 실행합니다. 몇 분 후 작업에 대한 전체 요청 및 응답 로그가 이 섹션으로 스트리밍되어 사용자가 콘솔에서 볼 수 있습니다.

# AWS AppSync(JavaScript)에서 파이프라인 해석기 구성 및 사용
<a name="pipeline-resolvers-js"></a>

AWS AppSync는 GraphQL 필드에서 해석기를 실행합니다. 경우에 따라 애플리케이션 사용 시 단일 GraphQL 필드를 해석하기 위해 여러 작업을 실행해야 합니다. 이제, 파이프라인 해석기를 사용해 개발자는 함수라고 하는 작업을 작성하고 순서대로 실행할 수 있습니다. 파이프라인 해석기는 예를 들어, 필드에 필요한 데이터를 가져오기 전에 권한 부여를 확인해야 하는 애플리케이션에 유용합니다.

JavaScript 파이프라인 해석기의 아키텍처에 대한 자세한 내용은 [JavaScript 해석기 개요](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html#anatomy-of-a-pipeline-resolver-js)를 참조하세요.

## 1단계: 파이프라인 해석기 생성
<a name="create-a-pipeline-resolver-js"></a>

 AWS AppSync 콘솔에서 **스키마** 페이지로 이동합니다.

다음 스키마를 저장합니다.

```
schema {
    query: Query
    mutation: Mutation
}

type Mutation {
    signUp(input: Signup): User
}

type Query {
    getUser(id: ID!): User
}

input Signup {
    username: String!
    email: String!
}

type User {
    id: ID!
    username: String
    email: AWSEmail
}
```

**변형** 유형의 **signUp** 필드에 파이프라인 해석기를 연결하겠습니다. 오른쪽에 있는 **변형** 유형에서 `signUp` 변형 필드 옆에 있는 **연결**을 선택합니다. 해석기를 `pipeline resolver`로 설정하고 `APPSYNC_JS` 런타임을 설정한 다음 해석기를 생성합니다.

파이프라인 해석기는 사용자를 등록해 먼저 입력된 이메일 주소를 확인한 다음 사용자를 시스템에 저장합니다. 이메일 검증을 **validateEmail** 함수 내에 캡슐화하고 사용자를 **saveUser** 함수 내에 저장할 것입니다. **validateEmail** 함수가 먼저 실행되고, 이메일이 유효한 경우 **saveUser** 함수가 실행됩니다.

다음과 같이 실행 흐름이 진행됩니다.

1. Mutation.signUp 해석기 요청 핸들러

1. validateEmail 함수

1. saveUser 함수

1. Mutation.signUp 해석기 응답 핸들러

API의 다른 해석기 내에서 **validateEmail** 함수를 다시 사용할 것입니다. GraphQL 필드 간에 변경되기 때문에 `ctx.args`에는 액세스하지 않도록 하겠습니다. 대신 `ctx.stash`를 사용해 `signUp(input: Signup)` 입력 필드 인수의 이메일 속성을 저장할 수 있습니다.

요청 및 응답 함수를 바꿔서 해석기 코드를 업데이트하세요.

```
export function request(ctx) {
    ctx.stash.email = ctx.args.input.email
    return {};
}

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

**생성** 또는 **저장**을 선택하여 해석기를 업데이트합니다.

## 2단계: 함수 생성
<a name="create-a-function-js"></a>

파이프라인 해석기 페이지의 **함수** 섹션에서 **함수 추가**를 클릭하고 **새 함수 생성**을 클릭합니다. 해석기 페이지를 거치지 않고 함수를 생성할 수도 있습니다. 이렇게 하려면 AWS AppSync 콘솔에서 **함수** 페이지로 이동합니다. **함수 생성** 버튼을 선택합니다. 이메일이 유효하고 특정 도메인에서 전송되는지 확인하는 함수를 생성합니다. 이메일이 유효하지 않으면 함수에서 오류가 발생합니다. 이메일이 유효할 경우 제공된 입력을 전달합니다.

**없음** 유형의 데이터 원본을 생성했는지 확인합니다. **데이터 원본 이름** 목록에서 이 데이터 원본을 선택합니다. **함수 이름**에 `validateEmail`을 입력합니다. **함수 코드** 영역에서 다음 스니펫으로 모든 내용을 덮어씁니다.

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

export function request(ctx) {
  const { email } = ctx.stash;
  const valid = util.matches(
    '^[a-zA-Z0-9_.+-]+@(?:(?:[a-zA-Z0-9-]+\.)?[a-zA-Z]+\.)?(myvaliddomain)\.com',
    email
  );
  if (!valid) {
    util.error(`"${email}" is not a valid email.`);
  }

  return { payload: { email } };
}

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

입력 내용을 검토한 다음 **생성**을 선택합니다. 방금 **validateEmail** 함수를 생성했습니다. 이 단계를 반복하여 다음 코드로 **saveUser** 함수를 생성합니다(단순화를 위해 **없음** 데이터 원본을 사용하고 함수가 실행된 후 사용자가 시스템에 저장된 것으로 가장함).

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

export function request(ctx) {
  return ctx.prev.result;
}

export function response(ctx) {
  ctx.result.id = util.autoId();
  return ctx.result;
}
```

방금 **saveUser** 함수를 생성했습니다.

## 3단계: 파이프라인 해석기에 함수 추가
<a name="adding-a-function-to-a-pipeline-resolver-js"></a>

파이프라인 해석기에 방금 생성한 함수가 자동으로 추가되어야 합니다. 그렇지 않거나 **함수** 페이지를 통해 함수를 생성한 경우, `signUp` 해석기 페이지에서 **함수 추가**를 다시 클릭하여 연결할 수 있습니다. 해석기에 **validateEmail** 및 **saveUser** 함수를 모두 추가합니다. **validateEmail** 함수는 **saveUser** 함수 앞에 배치해야 합니다. 함수를 더 추가할 때 **위로 이동** 및 **아래로 이동** 옵션을 사용해 함수 실행 순서를 다시 정리할 수 있습니다. 변경 사항을 검토한 후 **저장**을 선택합니다.

## 4단계: 쿼리 실행
<a name="running-a-query-js"></a>

 AWS AppSync 콘솔에서 **쿼리** 페이지로 이동합니다. 탐색기에서 변형을 사용하고 있는지 확인합니다. 그렇지 않다면 드롭다운 목록에서 `Mutation`을 선택한 다음 `+`를 선택합니다. 다음 쿼리를 입력합니다.

```
mutation {
  signUp(input: {email: "nadia@myvaliddomain.com", username: "nadia"}) {
    id
    username
  }
}
```

다음과 유사하게 반환되어야 합니다.

```
{
  "data": {
    "signUp": {
      "id": "256b6cc2-4694-46f4-a55e-8cb14cc5d7fc",
      "username": "nadia"
    }
  }
}
```

파이프라인 해석기를 사용하여 성공적으로 사용자를 등록했고, 입력한 이메일을 검증했습니다.

# 기본 쿼리 생성(VTL)
<a name="configuring-resolvers"></a>

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

GraphQL 해석기는 형식 스키마의 필드를 데이터 원본에 연결합니다. 해석기는 요청이 이행되는 메커니즘입니다. AWS AppSync는 코드를 작성할 필요 없이 스키마에서 해석기를 자동으로 생성 및 연결하거나 기존 테이블에서 스키마를 생성하고 해석기를 연결할 수 있습니다.

 AWS AppSync의 해석기는 JavaScript를 사용하여 GraphQL 표현식을 데이터 소스가 사용할 수 있는 형식으로 변환합니다. 또는 [Apache Velocity Template Language(VTL)](https://velocity.apache.org/engine/2.0/vtl-reference.html)로 작성된 매핑 템플릿을 사용하여 GraphQL 식을 데이터 원본이 사용할 수 있는 형식으로 변환할 수 있습니다.

이 섹션에서는 VTL을 사용하여 해석기를 구성하는 방법을 보여 줍니다. 해석기 작성을 위한 입문용 자습서 스타일 프로그래밍 가이드는 [해석기 매핑 템플릿 프로그래밍 가이드](resolver-mapping-template-reference-programming-guide.md#aws-appsync-resolver-mapping-template-reference-programming-guide)에서 찾을 수 있으며 프로그래밍 시 사용할 수 있는 도우미 유틸리티는 [해석기 매핑 템플릿 컨텍스트 참조](resolver-context-reference.md#aws-appsync-resolver-mapping-template-context-reference)에서 찾을 수 있습니다. AWS AppSync에는 처음부터 편집하거나 작성할 때 사용할 수 있는 테스트 및 디버그 흐름도 내장되어 있습니다. 자세한 내용은 [해석기 테스트 및 디버깅](test-debug-resolvers.md#aws-appsync-test-debug-resolvers)을 참조하세요.

앞서 언급한 자습서를 사용하기 전에 이 안내서를 확인하는 것이 좋습니다.

이 섹션에서는 해석기를 생성하고, 변형에 대해 해석기를 추가하고, 고급 구성을 사용하는 방법을 알아봅니다.

## 첫 번째 해석기 생성
<a name="create-your-first-resolver"></a>

이전 섹션의 예제에 따라 첫 번째 단계는 `Query` 유형에 맞는 해석기를 만드는 것입니다.

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

1. 에 로그인 AWS Management Console 하고 [AppSync 콘솔](https://console.aws.amazon.com/appsync/)을 엽니다.

   1. **API 대시보드**에서 GraphQL API를 선택합니다.

   1. **사이드바**에서 **스키마**를 선택합니다.

1. 페이지 오른쪽에 **해석기**라는 창이 있습니다. 이 상자에는 페이지 왼쪽의 **스키마** 창에 정의된 유형 및 필드 목록이 있습니다. 필드에 해석기를 연결할 수 있습니다. 예를 들어 **쿼리** 유형에서 `getTodos` 필드 옆에 있는 **첨부**를 선택합니다.

1. **해석기 생성** 페이지에서 [데이터 원본 연결](https://docs.aws.amazon.com/appsync/latest/devguide/attaching-a-data-source.html) 안내서에서 만든 데이터 원본을 선택합니다. **매핑 템플릿 구성** 창에서 오른쪽의 드롭다운 목록을 사용하여 일반 요청 및 응답 매핑 템플릿을 모두 선택하거나 직접 작성할 수 있습니다.
**참고**  
요청 매핑 템플릿과 응답 매핑 템플릿의 쌍을 이루는 것을 단위 해석기라고 합니다. 단위 해석기는 일반적으로 기계적 작업을 수행하는 것이 목적이므로 데이터 원본 수가 적은 단일 작업에만 사용하는 것이 좋습니다. 더 복잡한 작업의 경우 여러 데이터 원본에서 순차적으로 여러 작업을 실행할 수 있는 파이프라인 해석기를 사용하는 것이 좋습니다.  
요청과 응답 매핑 템플릿의 차이점에 대한 자세한 정보는 [단위 해석기](https://docs.aws.amazon.com//appsync/latest/devguide/resolver-mapping-template-reference-overview.html#unit-resolvers)를 참조하세요.  
파이프라인 해석기 사용에 대한 자세한 내용은 [파이프라인 해석기](pipeline-resolvers.md#aws-appsync-pipeline-resolvers)를 참조하세요.

1. 일반적인 사용 사례의 경우 AWS AppSync 콘솔에는 데이터 소스에서 항목(예: 모든 항목 쿼리, 개별 조회 등)을 가져오는 데 사용할 수 있는 템플릿이 내장되어 있습니다. 예를 들어 `getTodos`에 페이지 매김이 없는 [스키마 설계](designing-your-schema.md#aws-appsync-designing-your-schema)의 간단한 스키마 버전에서 항목을 나열하기 위한 요청 매핑 템플릿은 다음과 같습니다.

   ```
   {
       "version" : "2017-02-28",
       "operation" : "Scan"
   }
   ```

1. 요청과 동반되는 응답 매핑 템플릿은 항상 필요합니다. 콘솔은 다음과 같은 목록에 대한 패스스루 값과 함께 기본값을 제공합니다.

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

   이 예제에서 항목의 목록에 대한 `context` 객체(별칭 `$ctx`)는 `$context.result.items` 양식을 갖습니다. GraphQL 작업이 단일 항목을 반환하는 경우가 됩니다`$context.result`. AWS AppSync는 이전에 나열된 함수와 같은 일반적인 작업에 대한 헬퍼 `$util.toJson` 함수를 제공하여 응답의 형식을 올바르게 지정합니다. 전체 함수 목록은 [해석기 매핑 템플릿 유틸리티 참조](resolver-util-reference.md#aws-appsync-resolver-mapping-template-util-reference)를 참조하세요.

1. **해석기 저장** 을 선택합니다.

------
#### [ API ]

1. [https://docs.aws.amazon.com/appsync/latest/APIReference/API_CreateResolver.html](https://docs.aws.amazon.com/appsync/latest/APIReference/API_CreateResolver.html) API를 호출하여 해석기 객체를 생성합니다.

1. [https://docs.aws.amazon.com/appsync/latest/APIReference/API_UpdateResolver.html](https://docs.aws.amazon.com/appsync/latest/APIReference/API_UpdateResolver.html) API를 호출하여 해석기의 필드를 수정할 수 있습니다.

------
#### [ CLI ]

1. [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-resolver.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-resolver.html) 명령을 실행하여 해석기를 생성합니다.

   이 특정 명령에 대해 6개의 파라미터를 입력해야 합니다.

   1. API의 `api-id`.

   1. 스키마에서 수정하려는 유형의 `type-name`. 콘솔 예제에서는 `Query`였습니다.

   1. 유형에서 수정하려는 필드의 `field-name`. 콘솔 예제에서는 `getTodos`였습니다.

   1. [데이터 원본 연결](https://docs.aws.amazon.com/appsync/latest/devguide/attaching-a-data-source.html) 안내서에서 만든 데이터 원본의 `data-source-name`.

   1. 요청의 본문인 `request-mapping-template`. 콘솔 예제에서는 다음과 같았습니다.

      ```
      {
          "version" : "2017-02-28",
          "operation" : "Scan"
      }
      ```

   1. 응답의 본문인 `response-mapping-template`. 콘솔 예제에서는 다음과 같았습니다.

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

   예를 들어 명령은 다음과 같을 수 있습니다.

   ```
   aws appsync create-resolver --api-id abcdefghijklmnopqrstuvwxyz --type-name Query --field-name getTodos --data-source-name TodoTable --request-mapping-template "{ "version" : "2017-02-28", "operation" : "Scan", }" --response-mapping-template ""$"util.toJson("$"ctx.result.items)"
   ```

   CLI에서 출력이 반환됩니다. 다음은 그 예입니다.

   ```
   {
       "resolver": {
           "kind": "UNIT",
           "dataSourceName": "TodoTable",
           "requestMappingTemplate": "{ version : 2017-02-28, operation : Scan, }",
           "resolverArn": "arn:aws:appsync:us-west-2:107289374856:apis/abcdefghijklmnopqrstuvwxyz/types/Query/resolvers/getTodos",
           "typeName": "Query",
           "fieldName": "getTodos",
           "responseMappingTemplate": "$util.toJson($ctx.result.items)"
       }
   }
   ```

1. 해석기의 필드 또는 매핑 템플릿을 수정하려면 [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/update-resolver.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/update-resolver.html) 명령을 실행합니다.

   `api-id` 파라미터를 제외하고 `create-resolver` 명령에 사용된 파라미터는 `update-resolver` 명령의 새 값으로 덮어써집니다.

------

## 변형에 대한 해석기 추가
<a name="adding-a-resolver-for-mutations"></a>

다음 단계는 `Mutation` 유형에 맞는 해석기를 생성하는 것입니다.

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

1. 에 로그인 AWS Management Console 하고 [AppSync 콘솔](https://console.aws.amazon.com/appsync/)을 엽니다.

   1. **API 대시보드**에서 GraphQL API를 선택합니다.

   1. **사이드바**에서 **스키마**를 선택합니다.

1. **변형** 유형에서 `addTodo` 필드 옆에 있는 **연결**을 선택합니다.

1. **해석기 생성** 페이지에서 [데이터 원본 연결](https://docs.aws.amazon.com/appsync/latest/devguide/attaching-a-data-source.html) 안내서에서 만든 데이터 원본을 선택합니다.

1. DynamoDB에 새 항목을 추가하는 경우 요청 템플릿이 변형이므로 **매핑 템플릿 구성** 창에서 요청 템플릿을 수정해야 합니다. 다음 요청 매핑 템플릿을 사용합니다.

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

1. AWS AppSync는 `addTodo` 필드에 정의된 인수를 GraphQL 스키마에서 DynamoDB 작업으로 자동 변환합니다. 이전 예에서는 변형 인수에서 전달된 `id`의 키를 `$ctx.args.id`로 사용하여 DynamoDB에 레코드를 저장합니다. 전달하는 다른 모든 필드는 `$util.dynamodb.toMapValuesJson($ctx.args)`을 사용하여 DynamoDB 특성에 자동으로 매핑됩니다.

   이 해석기의 경우 다음 응답 매핑 템플릿을 사용합니다.

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

   AWS AppSync는 해석기 편집을 위한 테스트 및 디버그 워크플로도 지원합니다. 모의 `context` 객체를 사용하여 호출 전에 템플릿의 변환된 값을 확인할 수 있습니다. 선택적으로 쿼리를 실행할 때 대화식으로 데이터 원본에 대한 전체 요청 실행을 볼 수 있습니다. 자세한 내용은 [해석기 테스트 및 디버깅](test-debug-resolvers.md#aws-appsync-test-debug-resolvers) 및 [모니터링 및 로깅](monitoring.md#aws-appsync-monitoring)을 참조하세요.

1. **해석기 저장** 을 선택합니다.

------
#### [ API ]

[첫 번째 해석기 생성](https://docs.aws.amazon.com/appsync/latest/devguide/configuring-resolvers.html#create-your-first-resolver) 섹션의 명령과 이 섹션의 파라미터 세부 정보를 활용하여 API로 이 작업을 수행할 수도 있습니다.

------
#### [ CLI ]

[첫 번째 해석기 생성](https://docs.aws.amazon.com/appsync/latest/devguide/configuring-resolvers.html#create-your-first-resolver) 섹션의 명령과 이 섹션의 파라미터 세부 정보를 활용하여 CLI에서 이 작업을 수행할 수도 있습니다.

------

이 시점에서 고급 해석기를 사용하지 않는 경우 [API 사용](using-your-api.md#aws-appsync-using-your-api)에서 설명하는 것과 같이 GraphQL API 사용을 시작할 수 있습니다.

## 고급 해석기
<a name="advanced-resolvers"></a>

고급 섹션을 따르고 있으며, [스키마 설계](designing-your-schema.md#aws-appsync-designing-your-schema)의 샘플 스키마를 빌드하여 페이지 지정 스캔을 수행하는 경우 `getTodos` 필드에 대한 다음 요청 템플릿을 대신 사용합니다.

```
{
    "version" : "2017-02-28",
    "operation" : "Scan",
    "limit": $util.defaultIfNull(${ctx.args.limit}, 20),
    "nextToken": $util.toJson($util.defaultIfNullOrBlank($ctx.args.nextToken, null))
}
```

이러한 페이지 매김 사용 사례의 경우 응답 매핑에는 *커서*가 포함되어 있고(따라서 클라이언트가 다음에 시작할 페이지를 알 수 있음) 결과 집합이 포함되어 있어야 하기 때문에 응답 매핑은 단순한 패스스루 이상입니다. 매핑 템플릿은 다음과 같습니다.

```
{
    "todos": $util.toJson($context.result.items),
    "nextToken": $util.toJson($context.result.nextToken)
}
```

이전 응답 매핑 템플릿의 필드가 `TodoConnection` 형식에 정의된 필드와 일치해야 합니다.

`Comments` 테이블이 있고 `Todo` 형식에 대한 주석 필드를 해석하는 관계의 경우(`[Comment]`의 형식 반환) 두 번째 테이블을 기준으로 쿼리를 실행하는 매핑 템플릿을 사용할 수 있습니다. 이를 수행하려면 [데이터 원본 연결](attaching-a-data-source.md#aws-appsync-getting-started-build-a-schema-from-scratch)에서 설명하는 것과 같이 `Comments` 테이블에 대한 데이터 원본이 이미 생성되어야 합니다.

**참고**  
두 번째 테이블을 기준으로 쿼리 작업을 사용하는 것은 설명을 돕기 위한 목적일 뿐입니다. 대신 DynamoDB에 대해 다른 작업을 사용할 수 있습니다. 또한 관계는 GraphQL 스키마에 의해 제어되므로 AWS Lambda 또는 Amazon OpenSearch Service와 같은 다른 데이터 소스에서 데이터를 가져올 수 있습니다.

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

1. 에 로그인 AWS Management Console 하고 [AppSync 콘솔](https://console.aws.amazon.com/appsync/)을 엽니다.

   1. **API 대시보드**에서 GraphQL API를 선택합니다.

   1. **사이드바**에서 **스키마**를 선택합니다.

1. **Todo** 유형에서 `comments` 필드 옆에 있는 **연결**을 선택합니다.

1. **해석기 생성** 페이지에서 **주석** 테이블 데이터 원본을 선택합니다. 빠른 시작 안내서에서 **주석** 테이블의 기본 이름은 `AppSyncCommentTable`이지만, 지정한 이름에 따라 달라질 수 있습니다.

1. 요청 매핑 템플릿에 다음 스니펫을 추가합니다.

   ```
   {
       "version": "2017-02-28",
       "operation": "Query",
       "index": "todoid-index",
       "query": {
           "expression": "todoid = :todoid",
           "expressionValues": {
               ":todoid": {
                   "S": $util.toJson($context.source.id)
               }
           }
       }
   }
   ```

1. `context.source`는 해석 중인 현재 필드의 상위 객체를 참조합니다. 이 예제에서 `source.id`는 개별 `Todo` 객체를 참조하고, 이는 쿼리 표현식에 사용됩니다.

   다음과 같이 패스스루 응답 매핑 템플릿을 사용할 수 있습니다.

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

1. **해석기 저장** 을 선택합니다.

1. 마지막으로 콘솔의 **스키마** 페이지로 돌아가서 `addComment` 필드에 해석기를 연결하고, `Comments` 테이블에 대한 데이터 원본을 지정합니다. 이 경우의 요청 매핑 템플릿은 인수로서 주석 처리된 특정 `todoid`가 포함된 단순한 `PutItem`이지만, `$utils.autoId()` 유틸리티를 사용하여 다음과 같이 주석에 대한 고유한 정렬 키를 생성할 수 있습니다.

   ```
   {
       "version": "2017-02-28",
       "operation": "PutItem",
       "key": {
           "todoid": { "S": $util.toJson($context.arguments.todoid) },
           "commentid": { "S": "$util.autoId()" }
       },
       "attributeValues" : $util.dynamodb.toMapValuesJson($ctx.args)
   }
   ```

   다음과 같이 패스스루 응답 템플릿을 사용합니다.

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

------
#### [ API ]

[첫 번째 해석기 생성](https://docs.aws.amazon.com/appsync/latest/devguide/configuring-resolvers.html#create-your-first-resolver) 섹션의 명령과 이 섹션의 파라미터 세부 정보를 활용하여 API로 이 작업을 수행할 수도 있습니다.

------
#### [ CLI ]

[첫 번째 해석기 생성](https://docs.aws.amazon.com/appsync/latest/devguide/configuring-resolvers.html#create-your-first-resolver) 섹션의 명령과 이 섹션의 파라미터 세부 정보를 활용하여 CLI에서 이 작업을 수행할 수도 있습니다.

------

# 직접 Lambda 해석기(VTL)를 사용하여 VTL 매핑 템플릿 비활성화
<a name="direct-lambda-reference"></a>

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

직접 Lambda 해석기를 사용하면 AWS Lambda 데이터 소스를 사용할 때 VTL 매핑 템플릿 사용을 피할 수 있습니다. AWS AppSync는 Lambda 함수에 대한 기본 페이로드와 Lambda 함수의 응답에서 GraphQL 유형으로의 기본 변환을 제공할 수 있습니다. 요청 템플릿, 응답 템플릿을 제공하도록 선택할 수 있습니다. 그렇지 않으면 AWS AppSync가 이에 따라 처리하지 않습니다.

 AWS AppSync가 제공하는 기본 요청 페이로드 및 응답 변환에 대한 자세한 내용은 [Direct Lambda 해석기 참조](resolver-mapping-template-reference-lambda.md#direct-lambda-resolvers)를 참조하세요. AWS Lambda 데이터 소스 설정 및 IAM 신뢰 정책 설정에 대한 자세한 내용은 [데이터 소스 연결을 참조하세요](attaching-a-data-source.md).

## 직접 Lambda 해석기 구성
<a name="direct-lambda-reference-resolvers"></a>

다음 섹션에서는 Lambda 데이터 원본을 연결하고 Lambda 해석기를 필드에 추가하는 방법을 보여 줍니다.

### Lambda 데이터 원본 추가
<a name="direct-lambda-datasource"></a>

직접 Lambda 해석기를 활성화하려면 먼저 Lambda 데이터 원본을 추가해야 합니다.

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

1. 에 로그인 AWS Management Console 하고 [AppSync 콘솔](https://console.aws.amazon.com/appsync/)을 엽니다.

   1. **API 대시보드**에서 GraphQL API를 선택합니다.

   1. **사이드바**에서 **데이터 원본**을 선택합니다.

1. **데이터 원본 생성**을 선택합니다.

   1. **데이터 원본 이름**에 데이터 원본의 이름(예: **myFunction**)을 입력합니다.

   1. **데이터 원본 유형**에 **AWS Lambda 함수**를 선택합니다.

   1. **리전**에서 적절한 리전을 선택합니다.

   1. **함수 ARN**에는 드롭다운 목록에서 Lambda 함수를 선택합니다. 함수 이름을 검색하거나 사용하려는 함수의 ARN을 직접 입력할 수 있습니다.

   1. 새 IAM 역할을 만들거나(권장) `lambda:invokeFunction` IAM 권한이 있는 기존 역할을 선택합니다. 기존 역할에는 [데이터 원본 연결](attaching-a-data-source.md) 섹션에 설명된 대로 신뢰 정책이 필요합니다.

      다음은 리소스에서 작업을 수행하는 데 필요한 권한을 가진 IAM 정책의 예입니다.

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

****  

      ```
      { 
           "Version":"2012-10-17",		 	 	  
           "Statement": [ 
               { 
                   "Effect": "Allow", 
                   "Action": [ "lambda:invokeFunction" ], 
                   "Resource": [ 
                       "arn:aws:lambda:us-west-2:123456789012:function:myFunction", 
                       "arn:aws:lambda:us-west-2:123456789012:function:myFunction:*" 
                   ] 
               } 
           ] 
       }
      ```

------

1. **생성** 버튼을 선택합니다.

------
#### [ CLI ]

1. [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-data-source.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-data-source.html) 명령을 실행하여 데이터 원본 객체를 생성합니다.

   이 특정 명령에 대해 4개의 파라미터를 입력해야 합니다.

   1. API의 `api-id`.

   1. 데이터 원본의 `name`. 콘솔 예시에서는 **데이터 원본 이름**입니다.

   1. 데이터 원본의 `type`. 콘솔 예시에서는 **AWS Lambda 함수**입니다.

   1. `lambda-config`(콘솔 예시에서는 **함수 ARN**).
**참고**  
필수로 구성해야 하지만 일반적으로 CLI 구성 값으로 기본 설정되는 `Region`과 같은 다른 파라미터도 있습니다.

   예를 들어 명령은 다음과 같을 수 있습니다.

   ```
   aws appsync create-data-source --api-id abcdefghijklmnopqrstuvwxyz --name myFunction --type AWS_LAMBDA --lambda-config lambdaFunctionArn=arn:aws:lambda:us-west-2:102847592837:function:appsync-lambda-example
   ```

   CLI에서 출력이 반환됩니다. 다음은 그 예입니다.

   ```
   {
       "dataSource": {
           "dataSourceArn": "arn:aws:appsync:us-west-2:102847592837:apis/abcdefghijklmnopqrstuvwxyz/datasources/myFunction",
           "type": "AWS_LAMBDA",
           "name": "myFunction",
           "lambdaConfig": {
               "lambdaFunctionArn": "arn:aws:lambda:us-west-2:102847592837:function:appsync-lambda-example"
           }
       }
   }
   ```

1. 데이터 원본의 특성을 수정하려면 [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/update-data-source.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/update-data-source.html) 명령을 실행합니다.

   `api-id` 파라미터를 제외하고 `create-data-source` 명령에 사용된 파라미터는 `update-data-source` 명령의 새 값으로 덮어써집니다.

------

### 직접 Lambda 해석기 활성화
<a name="direct-lambda-enable-templates"></a>

Lambda 데이터 소스를 생성하고 AWS AppSync가 함수를 호출할 수 있도록 적절한 IAM 역할을 설정한 후 해석기 또는 파이프라인 함수에 연결할 수 있습니다.

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

1. 에 로그인 AWS Management Console 하고 [AppSync 콘솔](https://console.aws.amazon.com/appsync/)을 엽니다.

   1. **API 대시보드**에서 GraphQL API를 선택합니다.

   1. **사이드바**에서 **스키마**를 선택합니다.

1. **해석기** 창에서 필드 또는 작업을 선택한 다음 **연결** 버튼을 선택합니다.

1. **새 해석기 생성** 페이지의 드롭다운 목록에서 Lambda 함수를 선택합니다.

1. 직접 Lambda 해석기를 활용하려면 **매핑 템플릿 구성** 섹션에서 요청 및 응답 매핑 템플릿이 비활성화되었는지 확인하세요.

1. **해석기 저장** 버튼을 선택합니다.

------
#### [ CLI ]
+ [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-resolver.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-resolver.html) 명령을 실행하여 해석기를 생성합니다.

  이 특정 명령에 대해 6개의 파라미터를 입력해야 합니다.

  1. API의 `api-id`.

  1. 스키마에 있는 형식의 `type-name`.

  1. 스키마에 있는 필드의 `field-name`.

  1. `data-source-name` 또는 Lambda 함수의 이름.

  1. 요청의 본문인 `request-mapping-template`. 콘솔 예시에서는 이 파라미터가 비활성화되어 있었습니다.

     ```
     " "
     ```

  1. 응답의 본문인 `response-mapping-template`. 콘솔 예시에서는 이 파라미터도 비활성화되어 있었습니다.

     ```
     " "
     ```

  예를 들어 명령은 다음과 같을 수 있습니다.

  ```
  aws appsync create-resolver --api-id abcdefghijklmnopqrstuvwxyz --type-name Subscription --field-name onCreateTodo --data-source-name LambdaTest --request-mapping-template " " --response-mapping-template " "
  ```

  CLI에서 출력이 반환됩니다. 다음은 그 예입니다.

  ```
  {
      "resolver": {
          "resolverArn": "arn:aws:appsync:us-west-2:102847592837:apis/abcdefghijklmnopqrstuvwxyz/types/Subscription/resolvers/onCreateTodo",
          "typeName": "Subscription",
          "kind": "UNIT",
          "fieldName": "onCreateTodo",
          "dataSourceName": "LambdaTest"
      }
  }
  ```

------

매핑 템플릿을 비활성화하면 몇 가지 추가 동작이 AWS AppSync에서 발생합니다.
+ 매핑 템플릿을 비활성화하면 [Direct Lambda 해석기 참조](resolver-mapping-template-reference-lambda.md#direct-lambda-resolvers)에 지정된 기본 데이터 변환을 수락 AWS AppSync 한다는 신호를에 보냅니다.
+ 요청 매핑 템플릿을 비활성화하면 Lambda 데이터 원본이 전체 [컨텍스트](resolver-context-reference.md) 객체로 구성된 페이로드를 수신합니다.
+ 응답 매핑 템플릿을 비활성화하면 요청 매핑 템플릿의 버전 또는 요청 매핑 템플릿이 비활성화되었는지 여부에 따라 Lambda 간접 호출의 결과가 번역됩니다.

# AWS AppSync(VTL)에서 해석기 테스트 및 디버깅
<a name="test-debug-resolvers"></a>

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

AWS AppSync는 데이터 소스에 대해 GraphQL 필드에서 해석기를 실행합니다. [해석기 매핑 템플릿 개요](resolver-mapping-template-reference-overview.md#aws-appsync-resolver-mapping-template-reference-overview)에서 설명한 바와 같이, 해석기는 템플릿 언어를 사용하여 데이터 소스와 통신합니다. 이를 통해 데이터 소스와 통신하기 전과 후에 동작을 사용자 지정하고 로직 및 조건을 적용할 수 있습니다. 해석기 작성을 설명하는 소개 자습서 스타일의 프로그래밍 가이드는 [해석기 매핑 템플릿 프로그래밍 가이드](resolver-mapping-template-reference-programming-guide.md#aws-appsync-resolver-mapping-template-reference-programming-guide)를 참조하세요.

개발자가 이러한 해석기를 작성, 테스트 및 디버깅할 수 있도록 AWS AppSync 콘솔은 모의 데이터가 포함된 GraphQL 요청 및 응답을 개별 필드 해석기로 생성하는 도구도 제공합니다. 또한 AWS AppSync 콘솔에서 쿼리, 변형 및 구독을 수행하고 전체 요청에 대한 Amazon CloudWatch의 세부 로그 스트림을 볼 수 있습니다. 여기에는 데이터 원본의 결과가 포함됩니다.

## 모의 데이터를 사용하여 테스트
<a name="testing-with-mock-data"></a>

GraphQL 해석기가 호출되는 경우 이 해석기에는 요청에 대한 정보를 포함하는 `context` 객체가 들어 있습니다. 여기에는 클라이언트의 인수, 자격 증명 정보 및 상위 GraphQL 필드의 데이터가 포함됩니다. 또한 데이터 소스의 결과가 포함되며, 이러한 결과는 응답 템플릿에서 사용할 수 있습니다. 이 구조와 프로그래밍 시 사용할 수 있는 도우미 유틸리티에 대한 자세한 내용은 [해석기 매핑 템플릿 컨텍스트 참조](resolver-context-reference.md#aws-appsync-resolver-mapping-template-context-reference) 단원을 참조하세요.

해석기를 작성하거나 편집할 때 *mock* 또는 *test context* 객체를 콘솔 편집기로 전달할 수 있습니다. 이렇게 하면 데이터 원본에 대해 실행하지 않고도 요청과 응답 템플릿이 어떻게 평가되는지 알아볼 수 있습니다. 예를 들면 테스트 `firstname: Shaggy` 인수를 전달하고 템플릿 코드에서 `$ctx.args.firstname`을 사용하면 이 인수가 어떻게 평가되는지 볼 수 있습니다. 또한 `$util.autoId()` 또는 `util.time.nowISO8601()` 같은 유틸리티 도우미의 평가도 테스트할 수 있습니다.

### 해석기 테스트
<a name="test-a-resolver"></a>

이 예제에서는 AWS AppSync 콘솔을 사용하여 해석기를 테스트합니다.

1. 에 로그인 AWS Management Console 하고 [AppSync 콘솔](https://console.aws.amazon.com/appsync/)을 엽니다.

   1. **API 대시보드**에서 GraphQL API를 선택합니다.

   1. **사이드바**에서 **스키마**를 선택합니다.

1. 아직 추가하지 않았다면 유형 아래 및 필드 옆에서 **첨부**를 선택하여 해석기를 추가합니다.

   완전한 해석기를 빌드하는 방법에 대한 자세한 내용은 [해석기 구성](https://docs.aws.amazon.com/appsync/latest/devguide/configuring-resolvers.html)을 참조하세요.

   그렇지 않으면 필드에 이미 있는 해석기를 선택합니다.

1. **해석기 편집** 페이지 상단에서 **테스트 컨텍스트 선택**을 선택한 다음 **새 컨텍스트 생성**을 선택합니다.

1. 샘플 컨텍스트 객체를 선택하거나 아래 **실행 컨텍스트** 창에서 JSON을 수동으로 채웁니다.

1. **텍스트 컨텍스트 이름**에 입력합니다.

1. **저장** 버튼을 선택합니다.

1. **해석기 편집** 페이지 상단에서 **테스트 실행**을 선택합니다.

보다 실용적인 예로, 객체에 대한 자동 ID 생성을 사용하고 이를 Amazon DynamoDB에 저장하는 `Dog`의 GraphQL 유형을 저장하는 앱이 있다고 가정해 보겠습니다. 또한 GraphQL 변형의 인수에서 일부 값을 작성하고 특정 사용자만 응답을 볼 수 있도록 허용하려고 합니다. 스키마의 모양은 다음과 같을 수 있습니다.

```
type Dog {
  breed: String
  color: String
}

type Mutation {
  addDog(firstname: String, age: Int): Dog
}
```

`addDog` 뮤테이션의 해석기를 추가할 경우 다음의 예와 같이 컨텍스트 객체를 채울 수 있습니다. 다음 객체에는 `name` 및 `age` 클라이언트의 인수와 `identity` 객체에 채워진 `username`이 있습니다.

```
{
    "arguments" : {
        "firstname": "Shaggy",
        "age": 4
    },
    "source" : {},
    "result" : {
        "breed" : "Miniature Schnauzer",
        "color" : "black_grey"
    },
    "identity": {
        "sub" : "uuid",
        "issuer" : " https://cognito-idp.{region}.amazonaws.com/{userPoolId}",
        "username" : "Nadia",
        "claims" : { },
        "sourceIp" :[  "x.x.x.x" ],
        "defaultAuthStrategy" : "ALLOW"
    }
}
```

다음 요청과 응답 매핑 템플릿을 사용하여 이것을 테스트할 수 있습니다.

 **요청 템플릿** 

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

 **응답 템플릿** 

```
#if ($context.identity.username == "Nadia")
  $util.toJson($ctx.result)
#else
  $util.unauthorized()
#end
```

평가된 템플릿에는 테스트 컨텍스트 객체의 데이터와 `$util.autoId()`에서 생성된 값이 포함됩니다. 또한, `username`을 `Nadia` 이외의 값으로 변경해야 했다면 권한 부여 확인이 실패하므로 결과가 반환되지 않습니다. 세분화된 액세스 제어에 대한 자세한 내용은 [권한 부여 사용 사례](security-authorization-use-cases.md#aws-appsync-security-authorization-use-cases) 단원을 참조하세요.

### AWS AppSync의 APIs를 사용하여 매핑 템플릿 테스트
<a name="testing-with-appsync-api"></a>

`EvaluateMappingTemplate` API 명령어를 사용하여 모의 데이터로 매핑 템플릿을 원격 테스트할 수 있습니다. 명령어를 시작하려면 정책에 `appsync:evaluateMappingTemplate` 권한을 추가했는지 확인하세요. 예제:

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

****  

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

------

[AWS CLI](https://aws.amazon.com/cli/) 또는 [AWS SDK](https://aws.amazon.com/tools/)를 사용하여 명령을 활용할 수 있습니다. 예를 들어 이전 섹션의 `Dog` 스키마와 해당 요청/응답 매핑 템플릿을 가져옵니다. 로컬 스테이션에서 CLI를 사용하여 요청 템플릿을 `request.vtl`라는 파일에 저장한 다음 `context` 객체를 `context.json`이라는 파일에 저장합니다. 쉘에서 다음 명령을 실행합니다.

```
aws appsync evaluate-mapping-template --template file://request.vtl --context file://context.json
```

이 명령은 다음 응답을 반환합니다.

```
{
  "evaluationResult": "{\n    \"version\" : \"2017-02-28\",\n    \"operation\" : \"PutItem\",\n    \"key\" : {\n        \"id\" : { \"S\" : \"afcb4c85-49f8-40de-8f2b-248949176456\" }\n    },\n    \"attributeValues\" : {\"firstname\":{\"S\":\"Shaggy\"},\"age\":{\"N\":4}}\n}\n"
}
```

`evaluationResult`에는 제공된 `context`를 사용하여 제공된 템플릿을 테스트한 결과가 포함되어 있습니다. AWS SDKs. 다음은 AWS SDK for JavaScript V2를 사용하는 예제입니다.

```
const AWS = require('aws-sdk')
const client = new AWS.AppSync({ region: 'us-east-2' })

const template = fs.readFileSync('./request.vtl', 'utf8')
const context = fs.readFileSync('./context.json', 'utf8')

client
  .evaluateMappingTemplate({ template, context })
  .promise()
  .then((data) => console.log(data))
```

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' })

test('request correctly calls DynamoDB', async () => {
  const template = fs.readFileSync('./request.vtl', 'utf8')
  const context = fs.readFileSync('./context.json', 'utf8')
  const contextJSON = JSON.parse(context)
  
  const response = await client.evaluateMappingTemplate({ template, context }).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 total
Time: 1.511 s, estimated 2 s
```

## 라이브 쿼리 디버깅
<a name="debugging-a-live-query"></a>

프로덕션 애플리케이션을 디버깅하기 위한 end-to-end 테스트 및 로깅을 대체할 수 없습니다. AWS AppSync를 사용하면 Amazon CloudWatch를 사용하여 오류와 전체 요청 세부 정보를 로깅할 수 있습니다. 또한 AWS AppSync 콘솔을 사용하여 각 요청에 대한 GraphQL 쿼리, 변형 및 구독과 라이브 스트림 로그 데이터를 테스트하고 쿼리 편집기로 다시 전송하여 실시간으로 디버깅할 수 있습니다. 구독의 경우 로그는 연결-시간 정보를 표시합니다.

이를 수행하려면 [모니터링 및 로깅](monitoring.md#aws-appsync-monitoring)에 설명된 대로 Amazon CloudWatch 로그를 미리 활성화해야 합니다. 그런 다음 AWS AppSync 콘솔에서 **쿼리** 탭을 선택한 다음 유효한 GraphQL 쿼리를 입력합니다. 오른쪽 하단 섹션에서 **로그** 창을 클릭하고 드래그하여 로그 보기를 엽니다. 페이지 맨 위에 있는 ‘재생’ 화살표 아이콘을 선택하여 GraphQL 쿼리를 실행합니다. 몇 분 후 작업에 대한 전체 요청 및 응답 로그가 이 섹션으로 스트리밍되어 사용자가 콘솔에서 볼 수 있습니다.

# AWS AppSync(VTL)에서 파이프라인 해석기 구성 및 사용
<a name="pipeline-resolvers"></a>

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

AWS AppSync는 GraphQL 필드에서 해석기를 실행합니다. 경우에 따라 애플리케이션 사용 시 단일 GraphQL 필드를 해석하기 위해 여러 작업을 실행해야 합니다. 이제, 파이프라인 해석기를 사용해 개발자는 함수라고 하는 작업을 작성하고 순서대로 실행할 수 있습니다. 파이프라인 해석기는 예를 들어, 필드에 필요한 데이터를 가져오기 전에 권한 부여를 확인해야 하는 애플리케이션에 유용합니다.

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

## 1단계: 파이프라인 해석기 생성
<a name="create-a-pipeline-resolver"></a>

 AWS AppSync 콘솔에서 **스키마** 페이지로 이동합니다.

다음 스키마를 저장합니다.

```
schema {
    query: Query
    mutation: Mutation
}

type Mutation {
    signUp(input: Signup): User
}

type Query {
    getUser(id: ID!): User
}

input Signup {
    username: String!
    email: String!
}

type User {
    id: ID!
    username: String
    email: AWSEmail
}
```

**변형** 유형의 **signUp** 필드에 파이프라인 해석기를 연결하겠습니다. 오른쪽에 있는 **변형** 유형에서 `signUp` 변형 필드 옆에 있는 **연결**을 선택합니다. 해석기 생성 페이지에서 **작업**을 클릭한 다음 **런타임 업데이트**를 클릭합니다. `Pipeline Resolver`를 선택하고 `VTL`을 선택한 다음 **업데이트**를 선택합니다. 이 페이지에는 **사전 매핑 템플릿** 텍스트 영역, **함수** 섹션 및 **사후 매핑 템플릿** 텍스트 영역, 이렇게 3가지 섹션이 있어야 합니다.

파이프라인 해석기는 사용자를 등록해 먼저 입력된 이메일 주소를 확인한 다음 사용자를 시스템에 저장합니다. 이메일 검증을 **validateEmail** 함수 내에 캡슐화하고 사용자를 **saveUser** 함수 내에 저장할 것입니다. **validateEmail** 함수가 먼저 실행되고, 이메일이 유효한 경우 **saveUser** 함수가 실행됩니다.

다음과 같이 실행 흐름이 진행됩니다.

1. Mutation.signUp 해석기 요청 매핑 템플릿

1. validateEmail 함수

1. saveUser 함수

1. Mutation.signUp 해석기 응답 매핑 템플릿

API의 다른 해석기 내에서 **validateEmail** 함수를 다시 사용할 것입니다. GraphQL 필드 간에 변경되기 때문에 `$ctx.args`에는 액세스하지 않도록 하겠습니다. 대신 `$ctx.stash`를 사용해 `signUp(input: Signup)` 입력 필드 인수의 이메일 속성을 저장할 수 있습니다.

**사전** 매핑 템플릿:

```
## store email input field into a generic email key
$util.qr($ctx.stash.put("email", $ctx.args.input.email))
{}
```

콘솔은 사용할 기본 패스스루 **사후** 매핑 템플릿을 제공합니다.

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

**생성** 또는 **저장**을 선택하여 해석기를 업데이트합니다.

## 2단계: 함수 생성
<a name="create-a-function"></a>

파이프라인 해석기 페이지의 **함수** 섹션에서 **함수 추가**를 클릭하고 **새 함수 생성**을 클릭합니다. 해석기 페이지를 거치지 않고 함수를 생성할 수도 있습니다. 이렇게 하려면 AWS AppSync 콘솔에서 **함수** 페이지로 이동합니다. **함수 생성** 버튼을 선택합니다. 이메일이 유효하고 특정 도메인에서 전송되는지 확인하는 함수를 생성합니다. 이메일이 유효하지 않으면 함수에서 오류가 발생합니다. 이메일이 유효할 경우 제공된 입력을 전달합니다.

새 함수 페이지에서 **작업**을 선택한 다음 **런타임 업데이트**를 선택합니다. `VTL`을 선택하고 **업데이트**를 선택합니다. **없음** 유형의 데이터 원본을 생성했는지 확인합니다. **데이터 원본 이름** 목록에서 이 데이터 원본을 선택합니다. **함수 이름**에 `validateEmail`을 입력합니다. **함수 코드** 영역에서 다음 스니펫으로 모든 내용을 덮어씁니다.

```
#set($valid = $util.matches("^[a-zA-Z0-9_.+-]+@(?:(?:[a-zA-Z0-9-]+\.)?[a-zA-Z]+\.)?(myvaliddomain)\.com", $ctx.stash.email))
#if (!$valid)
    $util.error("$ctx.stash.email is not a valid email.")
#end
{
    "payload": { "email": $util.toJson(${ctx.stash.email}) }
}
```

이 내용을 응답 매핑 템플릿에 붙여넣습니다.

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

선택 항목을 검토한 다음 **생성**을 선택합니다. 방금 **validateEmail** 함수를 생성했습니다. 이 단계를 반복하여 다음 요청 및 응답 매핑 템플릿으로 **saveUser** 함수를 생성합니다(단순화를 위해 **없음** 데이터 원본을 사용하고 함수가 실행된 후 사용자가 시스템에 저장된 것으로 가장함).

요청 매핑 템플릿

```
## $ctx.prev.result contains the signup input values. We could have also
## used $ctx.args.input.
{
    "payload": $util.toJson($ctx.prev.result)
}
```

응답 매핑 템플릿:

```
## an id is required so let's add a unique random identifier to the output
$util.qr($ctx.result.put("id", $util.autoId()))
$util.toJson($ctx.result)
```

방금 **saveUser** 함수를 생성했습니다.

## 3단계: 파이프라인 해석기에 함수 추가
<a name="adding-a-function-to-a-pipeline-resolver"></a>

파이프라인 해석기에 방금 생성한 함수가 자동으로 추가되어야 합니다. 그렇지 않거나 **함수** 페이지를 통해 함수를 생성한 경우, 해석기 페이지에서 **함수 추가**를 클릭하여 연결할 수 있습니다. 해석기에 **validateEmail** 및 **saveUser** 함수를 모두 추가합니다. **validateEmail** 함수는 **saveUser** 함수 앞에 배치해야 합니다. 함수를 더 추가할 때 **위로 이동** 및 **아래로 이동** 옵션을 사용해 함수 실행 순서를 다시 정리할 수 있습니다. 변경 사항을 검토한 후 **저장**을 선택합니다.

## 4단계: 쿼리 실행
<a name="executing-a-query"></a>

 AWS AppSync 콘솔에서 **쿼리** 페이지로 이동합니다. 탐색기에서 변형을 사용하고 있는지 확인합니다. 그렇지 않다면 드롭다운 목록에서 `Mutation`을 선택한 다음 `+`를 선택합니다. 다음 쿼리를 입력합니다.

```
mutation {
  signUp(input: {
    email: "nadia@myvaliddomain.com"
    username: "nadia"
  }) {
    id
    email
  }
}
```

다음과 유사하게 반환되어야 합니다.

```
{
  "data": {
    "signUp": {
      "id": "256b6cc2-4694-46f4-a55e-8cb14cc5d7fc",
      "email": "nadia@myvaliddomain.com"
    }
  }
}
```

파이프라인 해석기를 사용하여 성공적으로 사용자를 등록했고, 입력한 이메일을 검증했습니다. 파이프라인 해석기에 대해 집중적으로 설명하는 자습서 전체를 살펴보려면 [자습서: 파이프라인 해석기](tutorial-pipeline-resolvers.md#aws-appsync-tutorial-pipeline-resolvers)를 참조하십시오.