자습서: DynamoDB 리졸버를 사용하여 간단한 포스트 애플리케이션 생성 - AWS AppSync

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

자습서: DynamoDB 리졸버를 사용하여 간단한 포스트 애플리케이션 생성

참고

이제 주로 APPSYNC _JS 런타임 및 설명서를 지원합니다. 여기에서 APPSYNC _JS 런타임 및 해당 가이드를 사용해 보세요.

이 자습서에서는 자체 Amazon DynamoDB 테이블을 AWS AppSync GraphQL로 가져와서 GraphQL에 연결하는 방법을 보여줍니다. API

사용자를 대신하여 DynamoDB 리소스를 AWS AppSync 프로비저닝할 수 있습니다. 또는 선호하는 경우 데이터 원본 및 해석기를 생성하여 기존 테이블을 GraphQL 스키마에 연결할 수 있습니다. 두 경우 모두 GraphQL 문을 통해 DynamoDB 데이터베이스를 읽고 여기에 쓸 수 있고 실시간 데이터를 구독할 수 있습니다.

GraphQL 문을 DynamoDB 작업으로 변환하고 응답을 다시 GraphQL로 변환하기 위해서는 순서대로 완료해야 하는 특정한 구성 단계가 있습니다. 이 자습서에서는 여러 가지 실제 시나리오와 데이터 액세스 패턴을 통해 구성 프로세스를 설명합니다.

DynamoDB 테이블 설정

이 자습서를 시작하려면 먼저 아래 단계에 따라 리소스를 AWS 프로비저닝해야 합니다.

  1. 에서 다음 AWS CloudFormation 템플릿을 사용하여 AWS 리소스를 프로비저닝하십시오CLI.

    aws cloudformation create-stack \ --stack-name AWSAppSyncTutorialForAmazonDynamoDB \ --template-url https://s3.us-west-2.amazonaws.com/awsappsync/resources/dynamodb/AmazonDynamoDBCFTemplate.yaml \ --capabilities CAPABILITY_NAMED_IAM

    또는 계정의 미국 서부 2 (오레곤) 지역에서 다음 AWS CloudFormation 스택을 시작할 수도 있습니다 AWS .

    Blue button labeled "Launch Stack" with an arrow icon indicating an action to start.

    다음을 생성합니다.

    • Post 데이터를 가지고 있는 AppSyncTutorial-Post라는 DynamoDB 테이블

    • 테이블과 상호 작용할 수 AWS AppSync 있는 IAM 역할 및 관련 IAM 관리형 정책 Post

  2. 스택과 생성된 리소스에 대한 자세한 내용을 보려면 다음 CLI 명령어를 실행하세요.

    aws cloudformation describe-stacks --stack-name AWSAppSyncTutorialForAmazonDynamoDB
  3. 나중에 리소스를 삭제하려면 다음을 실행할 수 있습니다.

    aws cloudformation delete-stack --stack-name AWSAppSyncTutorialForAmazonDynamoDB

GraphQL 만들기 API

APIGraphQL을 만들려면: AWS AppSync

  1. 에 AWS Management Console 로그인하고 콘솔을 엽니다. AppSync

    1. APIs대시보드에서 [Create] 를 선택합니다API.

  2. 사용자 지정 API 또는 Amazon DynamoDB에서 가져오기 창에서 처음부터 구축을 선택합니다.

    1. 같은 창 오른쪽에 있는 시작을 선택합니다.

  3. API이름 필드에 to의 API 이름을 설정합니다. AWSAppSyncTutorial

  4. 생성(Create)을 선택합니다.

AWS AppSync 콘솔은 키 인증 모드를 사용하여 새 API GraphQL을 생성합니다API. 이 자습서의 나머지 부분에서는 콘솔을 사용하여 나머지 API GraphQL을 설정하고 이에 대해 쿼리를 실행할 수 있습니다.

기본 게시물 정의 API

이제 AWS AppSync API GraphQL을 만들었으므로 게시물 데이터의 기본 생성, 검색 및 삭제를 허용하는 기본 스키마를 설정할 수 있습니다.

  1. 에 AWS Management Console 로그인하고 콘솔을 엽니다. AppSync

    1. APIs대시보드에서 방금 만든 API 것을 선택합니다.

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

    1. 스키마 창에서 파일 콘텐츠를 다음 코드로 바꿉니다.

      schema { query: Query mutation: Mutation } type Query { getPost(id: ID): Post } type Mutation { addPost( id: ID! author: String! title: String! content: String! url: String! ): Post! } type Post { id: ID! author: String title: String content: String url: String ups: Int! downs: Int! version: Int! }
  3. 저장(Save)을 선택합니다.

이 스키마는 Post 객체를 추가하고 가져올 작업과 Post 형식을 정의합니다.

DynamoDB 테이블에 대한 데이터 소스 구성

다음으로 스키마에 정의된 쿼리 및 뮤테이션을 AppSyncTutorial-Post DynamoDB 테이블에 연결합니다.

먼저 테이블을 잘 알고 AWS AppSync 있어야 합니다. 다음과 같이 데이터 원본을 설정하면 됩니다 AWS AppSync.

  1. 에 AWS Management Console 로그인하고 AppSync 콘솔을 엽니다.

    1. APIs대시보드에서 API GraphQL을 선택합니다.

    2. 사이드바에서 데이터 소스를 선택합니다.

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

    1. 데이터 소스 이름PostDynamoDBTable을 입력합니다.

    2. 데이터 소스 유형에서 Amazon DynamoDB 테이블을 선택합니다.

    3. 지역으로는 WEST US-2를 선택합니다.

    4. 테이블 이름으로 AppSyncTutorial -Post DynamoDB 테이블을 선택합니다.

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

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

      { "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:*" ] } ] }
  3. 생성(Create)을 선택합니다.

addPost 리졸버 설정 (DynamoDB) PutItem

DynamoDB 테이블을 인식한 후에는 AWS AppSync 리졸버를 정의하여 테이블을 개별 쿼리 및 뮤테이션에 연결할 수 있습니다. 생성한 첫 번째 해석기는 addPost 해석기로, 이 해석기를 통해 AppSyncTutorial-Post DynamoDB 테이블에서 게시물을 생성할 수 있습니다.

해석기의 구성 요소는 다음과 같습니다.

  • 해석기를 연결할 GraphQL 스키마의 위치. 이 경우 addPost 형식의 Mutation 필드에서 해석기를 설정합니다. 이 해석기는 호출자가 mutation { addPost(...){...} }를 호출하면 호출됩니다.

  • 이 해석기에 사용할 데이터 원본. 이 경우 앞서 정의한 PostDynamoDBTable 데이터 원본을 사용하려고 합니다. 따라서 AppSyncTutorial-Post DynamoDB 테이블에 항목을 추가할 수 있습니다.

  • 요청 매핑 템플릿. 요청 매핑 템플릿의 목적은 호출자로부터 들어오는 요청을 받아 DynamoDB에 대해 수행할 지침으로 변환하는 AWS AppSync 것입니다.

  • 응답 매핑 템플릿. 응답 매핑 템플릿의 작업은 DynamoDB의 응답을 받아 GraphQL에 필요한 것으로 변환하는 것입니다. 이러한 템플릿은 DynamoDB의 데이터 모양과 GraphQL의 Post 형식이 다른 경우 유용하지만 이 경우 모양이 서로 동일하기 때문에 데이터를 그냥 전달하면 됩니다.

해석기를 설정하려면:

  1. 에 AWS Management Console 로그인하고 콘솔을 엽니다. AppSync

    1. APIs대시보드에서 API GraphQL을 선택합니다.

    2. 사이드바에서 데이터 소스를 선택합니다.

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

    1. 데이터 소스 이름PostDynamoDBTable을 입력합니다.

    2. 데이터 소스 유형에서 Amazon DynamoDB 테이블을 선택합니다.

    3. 지역으로는 WEST US-2를 선택합니다.

    4. 테이블 이름으로 AppSyncTutorial -Post DynamoDB 테이블을 선택합니다.

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

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

      { "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:*" ] } ] }
  3. 생성(Create)을 선택합니다.

  4. 스키마 탭을 선택합니다.

  5. 오른쪽의 데이터 유형 패널에서 돌연변이 유형에 대한 addPost필드를 찾은 다음 연결을 선택합니다.

  6. 작업 메뉴에서 런타임 업데이트를 선택한 다음 Unit Resolver (VTL전용) 를 선택합니다.

  7. 데이터 소스 이름에서 을 선택합니다. PostDynamoDBTable

  8. 다음을 Configure the request mapping template(요청 매핑 템플릿 구성)에 붙여 넣습니다.

    { "version" : "2017-02-28", "operation" : "PutItem", "key" : { "id" : $util.dynamodb.toDynamoDBJson($context.arguments.id) }, "attributeValues" : { "author" : $util.dynamodb.toDynamoDBJson($context.arguments.author), "title" : $util.dynamodb.toDynamoDBJson($context.arguments.title), "content" : $util.dynamodb.toDynamoDBJson($context.arguments.content), "url" : $util.dynamodb.toDynamoDBJson($context.arguments.url), "ups" : { "N" : 1 }, "downs" : { "N" : 0 }, "version" : { "N" : 1 } } }

    참고: 형식은 모든 키와 속성 값에 대해 지정됩니다. 예를 들어, author 필드를 { "S" : "${context.arguments.author}" }로 설정합니다. 이 S 부분은 값이 문자열 AWS AppSync 값이 될 것임을 DynamoDB에 알립니다. 실제 값은 author 인수에서 채워집니다. 마찬가지로 version 필드는 형식에 N을 사용하기 때문에 숫자 필드입니다. 마지막으로, ups, downsversion 필드를 초기화합니다.

    이 자습서에서는 DynamoDB에 삽입되는 새 항목을 인덱싱하는 ID! GraphQL 형식이 클라이언트 인수의 일부로 제공되도록 지정했습니다. AWS AppSync 라는 $utils.autoId() 자동 ID 생성 유틸리티가 함께 제공됩니다. 이 유틸리티는 다음과 같은 형태로도 사용할 수 있습니다. "id" : { "S" : "${$utils.autoId()}" } 그런 다음 id: ID!의 스키마 정의 외부에 addPost()를 둘 수 있는데 자동으로 삽입됩니다. 이 자습서에서는 이러한 기술을 사용하지 않지만 DynamoDB 테이블에 쓰는 경우에는 이 기술의 사용을 고려해야 합니다.

    매핑 템플릿에 대한 자세한 내용은 해석기 매핑 템플릿 개요 참조 문서를 참조하십시오. GetItem 요청 매핑에 대한 자세한 내용은 GetItem참조 설명서를 참조하십시오. 행식에 대한 자세한 내용은 형식 시스템(요청 매핑) 참조 문서를 참조하십시오.

  9. 다음을 Configure the response mapping template(응답 매핑 템플릿 구성)에 붙여 넣습니다.

    $utils.toJson($context.result)

    참고: AppSyncTutorial-Post 테이블의 데이터 모양이 GraphQL의 Post 형식 모양과 정확하게 일치하기 때문에 응답 매핑 템플릿에서는 결과를 바로 전달하기만 합니다. 또한 파일을 하나만 생성할 수 있도록 이 자습서의 모든 예에서는 동일한 응답 매핑 템플릿을 사용합니다.

  10. 저장(Save)을 선택합니다.

를 API 호출하여 게시물을 추가하세요.

이제 리졸버가 설정되었으므로 들어오는 addPost 변이를 DynamoDB 작업으로 AWS AppSync 변환할 수 있습니다. PutItem 이제 변형을 실행해 테이블에 데이터를 입력할 수 있습니다.

  • Queries 탭을 선택합니다.

  • 쿼리 창에 다음 변형을 붙여 넣습니다.

    mutation addPost { addPost( id: 123 author: "AUTHORNAME" title: "Our first post!" content: "This is our first post." url: "https://aws.amazon.com/appsync/" ) { id author title content url ups downs version } }
  • Execute query(쿼리 실행)(주황색 재생 버튼)를 누릅니다.

  • 새로 생성한 게시물의 결과가 쿼리 창 오른쪽에 있는 결과 창에 나타나야 합니다. 예를 들면 다음과 같아야 합니다.

    { "data": { "addPost": { "id": "123", "author": "AUTHORNAME", "title": "Our first post!", "content": "This is our first post.", "url": "https://aws.amazon.com/appsync/", "ups": 1, "downs": 0, "version": 1 } } }

다음과 같은 작업이 수행되었습니다.

  • AWS AppSync 변이 요청을 받았습니다. addPost

  • AWS AppSync 요청과 요청 매핑 템플릿을 가져와서 요청 매핑 문서를 생성했습니다. 이 문서는 다음과 같은 형태입니다.

    { "version" : "2017-02-28", "operation" : "PutItem", "key" : { "id" : { "S" : "123" } }, "attributeValues" : { "author": { "S" : "AUTHORNAME" }, "title": { "S" : "Our first post!" }, "content": { "S" : "This is our first post." }, "url": { "S" : "https://aws.amazon.com/appsync/" }, "ups" : { "N" : 1 }, "downs" : { "N" : 0 }, "version" : { "N" : 1 } } }
  • AWS AppSync 요청 매핑 문서를 사용하여 PutItem DynamoDB 요청을 생성하고 실행했습니다.

  • AWS AppSync PutItem요청 결과를 가져와 GraphQL 유형으로 다시 변환했습니다.

    { "id" : "123", "author": "AUTHORNAME", "title": "Our first post!", "content": "This is our first post.", "url": "https://aws.amazon.com/appsync/", "ups" : 1, "downs" : 0, "version" : 1 }
  • 응답 매핑 문서를 통해 전달했습니다(변경 없이 전달됨).

  • GraphQL 응답에서 새로 생성된 객체가 반환되었습니다.

getPost 리졸버 설정 (DynamoDB) GetItem

이제 AppSyncTutorial-Post DynamoDB 테이블에 데이터를 추가할 수 있으므로 AppSyncTutorial-Post 테이블에서 데이터를 검색할 수 있도록 getPost 쿼리를 설정해야 합니다. 이렇게 하기 위해 다른 해석기를 설정합니다.

  • 스키마 탭을 선택합니다.

  • 오른쪽의 데이터 유형 패널에서 쿼리 유형의 getPost 필드를 찾은 다음 연결을 선택합니다.

  • 작업 메뉴에서 런타임 업데이트를 선택한 다음 Unit Resolver (VTL전용) 를 선택합니다.

  • 데이터 소스 이름에서 을 선택합니다. PostDynamoDBTable

  • 다음을 Configure the request mapping template(요청 매핑 템플릿 구성)에 붙여 넣습니다.

    { "version" : "2017-02-28", "operation" : "GetItem", "key" : { "id" : $util.dynamodb.toDynamoDBJson($ctx.args.id) } }
  • 다음을 Configure the response mapping template(응답 매핑 템플릿 구성)에 붙여 넣습니다.

    $utils.toJson($context.result)
  • 저장(Save)을 선택합니다.

를 API 호출하여 게시물을 가져오세요.

이제 리졸버가 설정되었으며 들어오는 getPost 쿼리를 DynamoDB 작업으로 변환하는 방법을 AWS AppSync 알고 있습니다. GetItem 이제 앞에서 생성한 게시물을 검색하는 쿼리를 실행할 수 있습니다.

  • Queries 탭을 선택합니다.

  • 쿼리 창에 다음을 붙여 넣습니다.

    query getPost { getPost(id:123) { id author title content url ups downs version } }
  • Execute query(쿼리 실행)(주황색 재생 버튼)를 누릅니다.

  • DynamoDB에서 가져온 게시물이 쿼리 창 오른쪽에 있는 결과 창에 나타나야 합니다. 예를 들면 다음과 같아야 합니다.

    { "data": { "getPost": { "id": "123", "author": "AUTHORNAME", "title": "Our first post!", "content": "This is our first post.", "url": "https://aws.amazon.com/appsync/", "ups": 1, "downs": 0, "version": 1 } } }

다음과 같은 작업이 수행되었습니다.

  • AWS AppSync 쿼리 요청을 받았습니다. getPost

  • AWS AppSync 요청과 요청 매핑 템플릿을 가져와 요청 매핑 문서를 생성했습니다. 이 문서는 다음과 같은 형태입니다.

    { "version" : "2017-02-28", "operation" : "GetItem", "key" : { "id" : { "S" : "123" } } }
  • AWS AppSync 요청 매핑 문서를 사용하여 GetItem DynamoDB 요청을 생성하고 실행했습니다.

  • AWS AppSync GetItem요청 결과를 가져와 GraphQL 유형으로 다시 변환했습니다.

    { "id" : "123", "author": "AUTHORNAME", "title": "Our first post!", "content": "This is our first post.", "url": "https://aws.amazon.com/appsync/", "ups" : 1, "downs" : 0, "version" : 1 }
  • 응답 매핑 문서를 통해 전달했습니다(변경 없이 전달됨).

  • 응답에서 가져온 객체가 반환되었습니다.

또는 다음 예를 사용합니다.

query getPost { getPost(id:123) { id author title } }

getPost 쿼리에 id, author, title만 필요한 경우, 요청 매핑 템플릿을 변경하여 프로젝션 표현식을 사용하여 DynamoDB 테이블에서 원하는 속성만 지정하면 DynamoDB에서 AWS AppSync로 불필요한 데이터 전송을 방지할 수 있습니다. 예를 들어 요청 매핑 템플릿은 아래 코드 조각과 비슷할 수 있습니다.

{ "version" : "2017-02-28", "operation" : "GetItem", "key" : { "id" : $util.dynamodb.toDynamoDBJson($ctx.args.id) }, "projection" : { "expression" : "#author, id, title", "expressionNames" : { "#author" : "author"} } }

updatePost 뮤테이션 생성 (DynamoDB UpdateItem)

이제 DynamoDB에서 Post 객체를 생성하고 검색할 수 있습니다. 다음에는, 객체 업데이트할 수 있도록 새 변형을 설정합니다. UpdateItem DynamoDB 작업을 사용하여 이 작업을 수행합니다.

  • 스키마 탭을 선택합니다.

  • 스키마 창에서 다음과 같이 Mutation 형식을 수정하여 새로운 updatePost 변형을 추가할 수 있습니다.

    type Mutation { updatePost( id: ID!, author: String!, title: String!, content: String!, url: String! ): Post addPost( author: String! title: String! content: String! url: String! ): Post! }
  • 저장(Save)을 선택합니다.

  • 오른쪽의 데이터 유형 패널에서 뮤테이션 유형에서 새로 생성된 updatePost필드를 찾은 다음 연결을 선택합니다.

  • 작업 메뉴에서 런타임 업데이트를 선택한 다음 Unit Resolver (VTL전용) 를 선택합니다.

  • 데이터 소스 이름에서 을 선택합니다. PostDynamoDBTable

  • 다음을 Configure the request mapping template(요청 매핑 템플릿 구성)에 붙여 넣습니다.

    { "version" : "2017-02-28", "operation" : "UpdateItem", "key" : { "id" : $util.dynamodb.toDynamoDBJson($context.arguments.id) }, "update" : { "expression" : "SET author = :author, title = :title, content = :content, #url = :url ADD version :one", "expressionNames": { "#url" : "url" }, "expressionValues": { ":author" : $util.dynamodb.toDynamoDBJson($context.arguments.author), ":title" : $util.dynamodb.toDynamoDBJson($context.arguments.title), ":content" : $util.dynamodb.toDynamoDBJson($context.arguments.content), ":url" : $util.dynamodb.toDynamoDBJson($context.arguments.url), ":one" : { "N": 1 } } } }

    참고: 이 리졸버는 DynamoDB를 UpdateItem 사용하며 이는 작업과 크게 다릅니다. PutItem 전체 항목을 쓰는 대신 특정 속성을 업데이트하도록 DynamoDB에 요청합니다. DynamoDB 업데이트 표현식을 사용하여 이 작업을 완료합니다. 표현식 자체는 expression 섹션의 update 필드에서 지정합니다. 이 표현식은 author, title, content 및 url 속성을 설정한 다음 version 필드를 증분하도록 합니다. 사용되는 값은 표현식 자체에 나타나지 않습니다. 대신 표현식에는 이름이 콜론으로 시작되는 자리 표시자가 있습니다. 표현식은 expressionValues 필드에서 정의됩니다. 마지막으로, DynamoDB에는 expression에 표시할 수 없는 예약어가 있습니다. 예를 들어, url은 예약어기 때문에 url 필드를 업데이트하려면 이름 자리 표시자를 사용해 expressionNames 필드에 해당 자리 표시자를 정의합니다.

    UpdateItem요청 매핑에 대한 자세한 내용은 참조 설명서를 참조하십시오. UpdateItem 업데이트 표현식을 작성하는 방법에 대한 자세한 내용은 UpdateExpressions DynamoDB 설명서를 참조하십시오.

  • 다음을 Configure the response mapping template(응답 매핑 템플릿 구성)에 붙여 넣습니다.

    $utils.toJson($context.result)

를 API 호출하여 게시물을 업데이트하십시오.

이제 리졸버가 설정되었으며 들어오는 update 변이를 DynamoDB 작업으로 변환하는 방법을 AWS AppSync 알고 있습니다. Update 이제 앞서 작성한 항목을 업데이트하는 변형을 실행할 수 있습니다.

  • Queries 탭을 선택합니다.

  • 쿼리 창에 다음 변형을 붙여 넣습니다. 또한 앞서 적어둔 값을 갖도록 id 인수를 업데이트해야 합니다.

    mutation updatePost { updatePost( id:"123" author: "A new author" title: "An updated author!" content: "Now with updated content!" url: "https://aws.amazon.com/appsync/" ) { id author title content url ups downs version } }
  • Execute query(쿼리 실행)(주황색 재생 버튼)를 누릅니다.

  • DynamoDB에서 업데이트된 게시물이 쿼리 창 오른쪽에 있는 결과 창에 나타나야 합니다. 예를 들면 다음과 같아야 합니다.

    { "data": { "updatePost": { "id": "123", "author": "A new author", "title": "An updated author!", "content": "Now with updated content!", "url": "https://aws.amazon.com/appsync/", "ups": 1, "downs": 0, "version": 2 } } }

이 예시에서는 요청 매핑 템플릿이 DynamoDB에 해당 downs 필드에 대해 어떤 작업도 수행하도록 요청하지 않았으므로 AWS AppSync 및 필드가 수정되지 않았습니다. ups 또한 사용자가 DynamoDB에 version 필드에 1을 추가하도록 AWS AppSync 요청했기 때문에 필드가 1씩 증가했습니다. version

updatePost 리졸버 수정 (DynamoDB) UpdateItem

이 작업은 updatePost 변형을 시작하기 좋은 지점이지만 다음과 같이 두 가지 주요한 문제가 있습니다.

  • 필드를 하나만 업데이트하고자 하는 경우에도 필드를 모두 업데이트해야 합니다.

  • 두 사람이 객체를 수정하는 경우 정보가 손실될 수 있습니다.

이러한 문제를 해결하기 위해 요청에 지정된 인수만 수정한 다음 UpdateItem 작업에 조건을 추가하도록 updatePost 변형을 수정하려고 합니다.

  1. 스키마 탭을 선택합니다.

  2. 스키마 패널에서 Mutation 유형의 updatePost 필드를 수정하여 author, title, contenturl 인수에서 느낌표를 제거하고 id 필드는 그대로 둡니다. 이렇게 하면 해당 인수가 선택적 인수가 됩니다. 또한 새로운 필수 인수인 expectedVersion 버전을 추가합니다.

    type Mutation { updatePost( id: ID!, author: String, title: String, content: String, url: String, expectedVersion: Int! ): Post addPost( author: String! title: String! content: String! url: String! ): Post! }
  3. 저장(Save)을 선택합니다.

  4. 오른쪽의 데이터 유형 패널에서 뮤테이션 유형에 대한 updatePost필드를 찾으십시오.

  5. 기존 PostDynamoDBTable리졸버를 열도록 선택합니다.

  6. Configure the request mapping template(요청 매핑 템플릿 구성)에서 다음과 같이 요청 매핑 템플릿을 수정합니다.

    { "version" : "2017-02-28", "operation" : "UpdateItem", "key" : { "id" : $util.dynamodb.toDynamoDBJson($context.arguments.id) }, ## Set up some space to keep track of things you're updating ** #set( $expNames = {} ) #set( $expValues = {} ) #set( $expSet = {} ) #set( $expAdd = {} ) #set( $expRemove = [] ) ## Increment "version" by 1 ** $!{expAdd.put("version", ":one")} $!{expValues.put(":one", { "N" : 1 })} ## Iterate through each argument, skipping "id" and "expectedVersion" ** #foreach( $entry in $context.arguments.entrySet() ) #if( $entry.key != "id" && $entry.key != "expectedVersion" ) #if( (!$entry.value) && ("$!{entry.value}" == "") ) ## If the argument is set to "null", then remove that attribute from the item in DynamoDB ** #set( $discard = ${expRemove.add("#${entry.key}")} ) $!{expNames.put("#${entry.key}", "$entry.key")} #else ## Otherwise set (or update) the attribute on the item in DynamoDB ** $!{expSet.put("#${entry.key}", ":${entry.key}")} $!{expNames.put("#${entry.key}", "$entry.key")} $!{expValues.put(":${entry.key}", { "S" : "${entry.value}" })} #end #end #end ## Start building the update expression, starting with attributes you're going to SET ** #set( $expression = "" ) #if( !${expSet.isEmpty()} ) #set( $expression = "SET" ) #foreach( $entry in $expSet.entrySet() ) #set( $expression = "${expression} ${entry.key} = ${entry.value}" ) #if ( $foreach.hasNext ) #set( $expression = "${expression}," ) #end #end #end ## Continue building the update expression, adding attributes you're going to ADD ** #if( !${expAdd.isEmpty()} ) #set( $expression = "${expression} ADD" ) #foreach( $entry in $expAdd.entrySet() ) #set( $expression = "${expression} ${entry.key} ${entry.value}" ) #if ( $foreach.hasNext ) #set( $expression = "${expression}," ) #end #end #end ## Continue building the update expression, adding attributes you're going to REMOVE ** #if( !${expRemove.isEmpty()} ) #set( $expression = "${expression} REMOVE" ) #foreach( $entry in $expRemove ) #set( $expression = "${expression} ${entry}" ) #if ( $foreach.hasNext ) #set( $expression = "${expression}," ) #end #end #end ## Finally, write the update expression into the document, along with any expressionNames and expressionValues ** "update" : { "expression" : "${expression}" #if( !${expNames.isEmpty()} ) ,"expressionNames" : $utils.toJson($expNames) #end #if( !${expValues.isEmpty()} ) ,"expressionValues" : $utils.toJson($expValues) #end }, "condition" : { "expression" : "version = :expectedVersion", "expressionValues" : { ":expectedVersion" : $util.dynamodb.toDynamoDBJson($context.arguments.expectedVersion) } } }
  7. 저장(Save)을 선택합니다.

이 템플릿은 보다 복잡한 예 중 하나입니다. 이 템플릿은 보다 복잡한 예 중 하나로, 매핑 템플릿의 이점과 유연성을 보여줍니다. 이 템플릿은 모든 인수를 루핑하면서 idexpectedVersion을 건너뜁니다. 인수가 무언가로 설정되면 DynamoDB에 있는 객체의 해당 속성을 업데이트하도록 DynamoDB에 AWS AppSync 요청합니다. 속성이 null로 설정된 경우 DynamoDB에 게시물 객체에서 해당 속성을 제거하도록 AWS AppSync 요청합니다. 인수가 지정되어 있지 않은 경우에는 속성을 그냥 둡니다. 이 템플릿 역시 version 필드를 증가시킵니다.

또한 새로운 condition 섹션이 있습니다. 조건식을 사용하면 작업이 수행되기 전에 DynamoDB에 이미 있는 객체의 상태를 기반으로 요청의 성공 여부를 DynamoDB에 알릴 AWS AppSync 수 있습니다. 이 경우에는 DynamoDB에 현재 있는 항목의 version 필드가 expectedVersion 인수와 정확하게 일치하는 경우에만 UpdateItem 요청에 성공하면 됩니다.

조건 표현식에 대한 자세한 내용은 조건 표현식 참조 문서를 참조하십시오.

를 호출하여 게시물을 업데이트하십시오. API

새 해석기를 사용해 Post 객체를 업데이트해 보십시오.

  • Queries 탭을 선택합니다.

  • 쿼리 창에 다음 변형을 붙여 넣습니다. 또한 앞서 적어둔 값을 갖도록 id 인수를 업데이트해야 합니다.

    mutation updatePost { updatePost( id:123 title: "An empty story" content: null expectedVersion: 2 ) { id author title content url ups downs version } }
  • Execute query(쿼리 실행)(주황색 재생 버튼)를 누릅니다.

  • DynamoDB에서 업데이트된 게시물이 쿼리 창 오른쪽에 있는 결과 창에 나타나야 합니다. 예를 들면 다음과 같아야 합니다.

    { "data": { "updatePost": { "id": "123", "author": "A new author", "title": "An empty story", "content": null, "url": "https://aws.amazon.com/appsync/", "ups": 1, "downs": 0, "version": 3 } } }

이 요청에서는 AWS AppSync 및 DynamoDB에 및 필드만 업데이트하도록 title 요청했습니다content. version 필드를 증분하는 것을 제외하고 다른 모든 필드는 그대로 둡니다. title 속성을 새 값으로 설정하고 게시물에서 content 속성을 제거했습니다. author, url, upsdowns 필드는 그대로 남아 있습니다.

변형 요청을 다시 실행해도 요청은 정확하게 그대로 유지됩니다. 다음과 유사한 응답이 나타납니다.

{ "data": { "updatePost": null }, "errors": [ { "path": [ "updatePost" ], "data": { "id": "123", "author": "A new author", "title": "An empty story", "content": null, "url": "https://aws.amazon.com/appsync/", "ups": 1, "downs": 0, "version": 3 }, "errorType": "DynamoDB:ConditionalCheckFailedException", "locations": [ { "line": 2, "column": 3 } ], "message": "The conditional request failed (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ConditionalCheckFailedException; Request ID: ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ)" } ] }

조건 표현식이 false로 평가되었으므로 요청에 실패합니다.

  • 요청을 처음 실행했을 때 DynamoDB에 있는 게시물의 version 필드 값은 2였고, 이는 expectedVersion 인수와 일치했습니다. 요청에 성공하자 DynamoDB의 version 필드가 3으로 증가했습니다.

  • 요청을 두 번째로 실행했을 때 DynamoDB에 있는 게시물의 version 필드 값은 3이었고, 이는 expectedVersion 인수와 일치하지 않았습니다.

이러한 패턴을 일반적으로 낙관적 잠금이라고 합니다.

AWS AppSync DynamoDB 리졸버의 기능 중 하나는 DynamoDB에 있는 게시물 객체의 현재 값을 반환한다는 것입니다. 현재 값은 GraphQL 응답의 data 섹션에 있는 errors 필드에서 찾을 수 있습니다. 애플리케이션에서는 이러한 정보를 사용하여 처리 방식을 결정합니다. 이 경우, DynamoDB에 있는 객체의 version 필드가 3으로 설정되어 있은데, 방금 expectedVersion 인수를 3으로 업데이트했으므로 결과는 다시 성공입니다.

조건 검사 실패 처리에 대한 자세한 내용은 조건 표현식 매핑 템플릿 참조 문서를 참조하십시오.

생성 upvotePost 및 downvotePost 변형 (DynamoDB UpdateItem)

Post 유형에는 찬성 투표 ups 및 반대 투표를 기록할 수 있는 downs 필드가 있지만, 지금까지는 이러한 필드로 API 아무 것도 할 수 없습니다. 게시물을 추천 및 비추천하도록 하는 몇 가지 변형을 추가해 보겠습니다.

  • 스키마 탭을 선택합니다.

  • 스키마 창에서 다음과 같이 Mutation 유형을 수정하여 새로운 upvotePostdownvotePost 뮤테이션을 추가할 수 있습니다.

    type Mutation { upvotePost(id: ID!): Post downvotePost(id: ID!): Post updatePost( id: ID!, author: String, title: String, content: String, url: String, expectedVersion: Int! ): Post addPost( author: String!, title: String!, content: String!, url: String! ): Post! }
  • 저장(Save)을 선택합니다.

  • 오른쪽의 데이터 유형 패널에서 뮤테이션 유형에서 새로 만든 upvotePost필드를 찾은 다음 연결을 선택합니다.

  • 작업 메뉴에서 런타임 업데이트를 선택한 다음 Unit Resolver (VTL전용) 를 선택합니다.

  • 데이터 소스 이름에서 을 선택합니다. PostDynamoDBTable

  • 다음을 Configure the request mapping template(요청 매핑 템플릿 구성)에 붙여 넣습니다.

    { "version" : "2017-02-28", "operation" : "UpdateItem", "key" : { "id" : $util.dynamodb.toDynamoDBJson($context.arguments.id) }, "update" : { "expression" : "ADD ups :plusOne, version :plusOne", "expressionValues" : { ":plusOne" : { "N" : 1 } } } }
  • 다음을 Configure the response mapping template(응답 매핑 템플릿 구성)에 붙여 넣습니다.

    $utils.toJson($context.result)
  • 저장(Save)을 선택합니다.

  • 오른쪽의 데이터 유형 창의 뮤테이션 유형에서 새로 생성한 downvotePost 필드를 찾은 다음 연결을 선택합니다.

  • 데이터 소스 이름에서 선택합니다 PostDynamoDBTable.

  • 다음을 Configure the request mapping template(요청 매핑 템플릿 구성)에 붙여 넣습니다.

    { "version" : "2017-02-28", "operation" : "UpdateItem", "key" : { "id" : $util.dynamodb.toDynamoDBJson($context.arguments.id) }, "update" : { "expression" : "ADD downs :plusOne, version :plusOne", "expressionValues" : { ":plusOne" : { "N" : 1 } } } }
  • 다음을 Configure the response mapping template(응답 매핑 템플릿 구성)에 붙여 넣습니다.

    $utils.toJson($context.result)
  • 저장(Save)을 선택합니다.

를 API 호출하여 게시물에 찬성 및 반대 투표를 하세요.

이제 새 리졸버가 설정되었으며 수신 upvotePost 또는 downvote 변이를 DynamoDB 작업으로 변환하는 방법을 AWS AppSync 알고 있습니다. UpdateItem 이제 앞서 생성한 게시물을 추천 또는 비추천하는 변형을 실행할 수 있습니다.

  • Queries 탭을 선택합니다.

  • 쿼리 창에 다음 변형을 붙여 넣습니다. 또한 앞서 적어둔 값을 갖도록 id 인수를 업데이트해야 합니다.

    mutation votePost { upvotePost(id:123) { id author title content url ups downs version } }
  • Execute query(쿼리 실행)(주황색 재생 버튼)를 누릅니다.

  • 게시물이 DynamoDB에서 업데이트되고 쿼리 창 오른쪽에 있는 결과 창에 나타나야 합니다. 예를 들면 다음과 같아야 합니다.

    { "data": { "upvotePost": { "id": "123", "author": "A new author", "title": "An empty story", "content": null, "url": "https://aws.amazon.com/appsync/", "ups": 6, "downs": 0, "version": 4 } } }
  • Execute query(쿼리 실행)를 몇 번 더 선택합니다. 쿼리를 실행할 때마다 upsversion 필드가 1씩 증가하는 것이 보여야 합니다.

  • 다음과 같이 downvotePost 변형을 호출하도록 쿼리를 변경합니다.

    mutation votePost { downvotePost(id:123) { id author title content url ups downs version } }
  • Execute query(쿼리 실행)(주황색 재생 버튼)를 누릅니다. 쿼리를 실행할 때마다 downsversion 필드가 1씩 증가하는 것이 보여야 합니다.

    { "data": { "downvotePost": { "id": "123", "author": "A new author", "title": "An empty story", "content": null, "url": "https://aws.amazon.com/appsync/", "ups": 6, "downs": 4, "version": 12 } } }

deletePost리졸버 설정 (DynamoDB) DeleteItem

설정하려는 다음 변형은 게시물을 삭제하는 변형입니다. 이 작업은 DeleteItem DynamoDB 작업을 사용하여 수행합니다.

  • 스키마 탭을 선택합니다.

  • 스키마 창에서 다음과 같이 Mutation 형식을 수정하여 새로운 deletePost 변형을 추가할 수 있습니다.

    type Mutation { deletePost(id: ID!, expectedVersion: Int): Post upvotePost(id: ID!): Post downvotePost(id: ID!): Post updatePost( id: ID!, author: String, title: String, content: String, url: String, expectedVersion: Int! ): Post addPost( author: String!, title: String!, content: String!, url: String! ): Post! }

    이번에는expectedVersion 필드를 선택 사항으로 설정했는데, 이에 관한 사항은 나중에 요청 매핑 템플릿을 추가할 때 설명하겠습니다.

  • 저장(Save)을 선택합니다.

  • 오른쪽의 데이터 유형 창의 뮤테이션 유형에서 새로 생성한 delete 필드를 찾은 다음 연결을 선택합니다.

  • 작업 메뉴에서 런타임 업데이트를 선택한 다음 유닛 리졸버 (전용) 를 선택합니다. VTL

  • 데이터 소스 이름에서 을 선택합니다. PostDynamoDBTable

  • 다음을 Configure the request mapping template(요청 매핑 템플릿 구성)에 붙여 넣습니다.

    { "version" : "2017-02-28", "operation" : "DeleteItem", "key": { "id": $util.dynamodb.toDynamoDBJson($context.arguments.id) } #if( $context.arguments.containsKey("expectedVersion") ) ,"condition" : { "expression" : "attribute_not_exists(id) OR version = :expectedVersion", "expressionValues" : { ":expectedVersion" : $util.dynamodb.toDynamoDBJson($context.arguments.expectedVersion) } } #end }

    참고: expectedVersion 인수는 선택적 인수입니다. 호출자가 요청에서 expectedVersion 인수를 설정하면, 템플릿에서는 항목이 이미 삭제된 경우 또는 DynamoDB에 있는 version 속성이 expectedVersion과 정확하게 일치하는 경우, DeleteItem 요청이 완료되게 하는 조건을 추가합니다. 그냥 두면 DeleteItem 요청에 아무런 조건 표현식도 지정되지 않습니다. 이는 version의 값이나 해당 항목이 DynamoDB에 존재하는지 여부에 관계없이 완료됩니다.

  • 다음을 Configure the response mapping template(응답 매핑 템플릿 구성)에 붙여 넣습니다.

    $utils.toJson($context.result)

    참고: 항목을 삭제하고 있더라도 항목이 아직 삭제되지 않은 경우 삭제된 항목을 반환할 수 있습니다.

  • 저장(Save)을 선택합니다.

DeleteItem요청 매핑에 대한 자세한 내용은 DeleteItem참조 문서를 참조하십시오.

를 API 호출하여 게시물을 삭제하십시오.

이제 리졸버가 설정되었으며 들어오는 delete 변이를 DynamoDB 작업으로 변환하는 방법을 AWS AppSync 알고 있습니다. DeleteItem 이제 변형을 실행해 테이블에 데이터를 삭제할 수 있습니다.

  • Queries 탭을 선택합니다.

  • 쿼리 창에 다음 변형을 붙여 넣습니다. 또한 앞서 적어둔 값을 갖도록 id 인수를 업데이트해야 합니다.

    mutation deletePost { deletePost(id:123) { id author title content url ups downs version } }
  • Execute query(쿼리 실행)(주황색 재생 버튼)를 누릅니다.

  • DynamoDB에서 게시물이 삭제되었습니다. 참고로 DynamoDB에서 삭제된 항목의 값을 AWS AppSync 반환하며, 이 값은 쿼리 창 오른쪽에 있는 결과 창에 표시되어야 합니다. 예를 들면 다음과 같아야 합니다.

    { "data": { "deletePost": { "id": "123", "author": "A new author", "title": "An empty story", "content": null, "url": "https://aws.amazon.com/appsync/", "ups": 6, "downs": 4, "version": 12 } } }

deletePost에 대한 호출이 DynamoDB에서 실제로 삭제된 항목인 경우에만 값이 반환됩니다.

  • Execute query(쿼리 실행)을 다시 선택합니다.

  • 호출에는 계속 성공하지만 반환되는 값은 없습니다.

    { "data": { "deletePost": null } }

이제 게시물을 삭제해 보는데, 이번에는 expectedValue를 지정해 보겠습니다. 지금까지 작업한 게시물 하나를 방금 삭제했기 때문에 먼저 새 게시물을 생성해야 합니다.

  • 쿼리 창에 다음 변형을 붙여 넣습니다.

    mutation addPost { addPost( id:123 author: "AUTHORNAME" title: "Our second post!" content: "A new post." url: "https://aws.amazon.com/appsync/" ) { id author title content url ups downs version } }
  • Execute query(쿼리 실행)(주황색 재생 버튼)를 누릅니다.

  • 새로 생성한 게시물의 결과가 쿼리 창 오른쪽에 있는 결과 창에 나타나야 합니다. 곧 필요할 것이기 때문에 새로 생성한 객체의 id를 적어 둡니다. 예를 들면 다음과 같아야 합니다.

    { "data": { "addPost": { "id": "123", "author": "AUTHORNAME", "title": "Our second post!", "content": "A new post.", "url": "https://aws.amazon.com/appsync/", "ups": 1, "downs": 0, "version": 1 } } }

이제 게시물을 삭제해 보는데 expectedVersion에 대해 잘못된 값을 입력할 것입니다.

  • 쿼리 창에 다음 변형을 붙여 넣습니다. 또한 앞서 적어둔 값을 갖도록 id 인수를 업데이트해야 합니다.

    mutation deletePost { deletePost( id:123 expectedVersion: 9999 ) { id author title content url ups downs version } }
  • Execute query(쿼리 실행)(주황색 재생 버튼)를 누릅니다.

    { "data": { "deletePost": null }, "errors": [ { "path": [ "deletePost" ], "data": { "id": "123", "author": "AUTHORNAME", "title": "Our second post!", "content": "A new post.", "url": "https://aws.amazon.com/appsync/", "ups": 1, "downs": 0, "version": 1 }, "errorType": "DynamoDB:ConditionalCheckFailedException", "locations": [ { "line": 2, "column": 3 } ], "message": "The conditional request failed (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ConditionalCheckFailedException; Request ID: ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ)" } ] }

    DynamoDB에 있는 게시물의 version 값이 인수에 지정된 expectedValue와 일치하지 않아 조건 표현식이 false로 평가되었기 때문에 요청에 실패했습니다. 객체의 현재 값은 GraphQL 응답에서 data 섹션의 errors 필드에 반환됩니다.

  • 이 요청을 다시 실행하되 expectedVersion을 수정합니다.

    mutation deletePost { deletePost( id:123 expectedVersion: 1 ) { id author title content url ups downs version } }
  • Execute query(쿼리 실행)(주황색 재생 버튼)를 누릅니다.

  • 이번에는 요청에 성공하고 DynamoDB에서 삭제된 값이 반환됩니다.

    { "data": { "deletePost": { "id": "123", "author": "AUTHORNAME", "title": "Our second post!", "content": "A new post.", "url": "https://aws.amazon.com/appsync/", "ups": 1, "downs": 0, "version": 1 } } }
  • Execute query(쿼리 실행)을 다시 선택합니다.

  • 호출에 계속해서 성공하지만 이번에는 게시물이 이미 DynamoDB에서 삭제되었으므로 반환되는 값이 없습니다.

{ "data": { "deletePost": null } }

allPost리졸버 설정 (DynamoDB 스캔)

API지금까지는 살펴보려는 각 게시물의 내용을 알고 있는 경우에만 유용합니다. id 테이블의 게시물을 모두 반환하는 새 해석기를 추가해 보겠습니다.

  • 스키마 탭을 선택합니다.

  • 스키마 창에서 다음과 같이 Query 형식을 수정하여 새로운 allPost 쿼리를 추가할 수 있습니다.

    type Query { allPost(count: Int, nextToken: String): PaginatedPosts! getPost(id: ID): Post }
  • 새로운 PaginationPosts 형식을 다음과 같이 추가합니다.

    type PaginatedPosts { posts: [Post!]! nextToken: String }
  • 저장(Save)을 선택합니다.

  • 오른쪽의 데이터 유형 패널에서 쿼리 유형에서 새로 만든 allPost필드를 찾은 다음 첨부를 선택합니다.

  • 작업 메뉴에서 런타임 업데이트를 선택한 다음 Unit Resolver (VTL전용) 를 선택합니다.

  • 데이터 소스 이름에서 을 선택합니다. PostDynamoDBTable

  • 다음을 Configure the request mapping template(요청 매핑 템플릿 구성)에 붙여 넣습니다.

    { "version" : "2017-02-28", "operation" : "Scan" #if( ${context.arguments.count} ) ,"limit": $util.toJson($context.arguments.count) #end #if( ${context.arguments.nextToken} ) ,"nextToken": $util.toJson($context.arguments.nextToken) #end }

    이 해석기에는 두 가지 선택적 인수가 있는데, count는 단일 호출 시 반환되는 최대 항목 수를 지정하고, nextToken은 다음 결과 집합을 가져오는 데 사용할 수 있습니다(nextToken의 값을 가져오는 위치는 나중에 설명할 예정임).

  • 다음을 Configure the response mapping template(응답 매핑 템플릿 구성)에 붙여 넣습니다.

    { "posts": $utils.toJson($context.result.items) #if( ${context.result.nextToken} ) ,"nextToken": $util.toJson($context.result.nextToken) #end }

    참고: 이 응답 매핑 템플릿은 지금까지 사용한 다른 모든 템플릿과 다릅니다. allPost 쿼리의 결과는 게시물 목록과 페이지 매김 토큰을 포함하고 있는 PaginatedPosts입니다. 이 객체의 모양은 AWS AppSync DynamoDB 리졸버에서 반환되는 것과 다릅니다. 게시물 목록은 AWS AppSync DynamoDB 리졸버 items 결과에서 호출되지만 호출됩니다. posts PaginatedPosts

  • 저장(Save)을 선택합니다.

Scan 요청 매핑에 대한 자세한 내용은 스캔 참조 문서를 참조하십시오.

를 호출하여 모든 게시물을 스캔하십시오. API

이제 리졸버가 설정되었으며 들어오는 allPost 쿼리를 DynamoDB 작업으로 변환하는 방법을 AWS AppSync 알고 있습니다. Scan 이제 테이블을 스캔해 게시물을 모두 검색할 수 있습니다.

지금까지 작업했던 데이터를 모두 삭제했기 때문에 이 요청을 수행하기 전에 몇 가지 데이터로 테이블을 채워야 합니다.

  • Queries 탭을 선택합니다.

  • 쿼리 창에 다음 변형을 붙여 넣습니다.

    mutation addPost { post1: addPost(id:1 author: "AUTHORNAME" title: "A series of posts, Volume 1" content: "Some content" url: "https://aws.amazon.com/appsync/" ) { title } post2: addPost(id:2 author: "AUTHORNAME" title: "A series of posts, Volume 2" content: "Some content" url: "https://aws.amazon.com/appsync/" ) { title } post3: addPost(id:3 author: "AUTHORNAME" title: "A series of posts, Volume 3" content: "Some content" url: "https://aws.amazon.com/appsync/" ) { title } post4: addPost(id:4 author: "AUTHORNAME" title: "A series of posts, Volume 4" content: "Some content" url: "https://aws.amazon.com/appsync/" ) { title } post5: addPost(id:5 author: "AUTHORNAME" title: "A series of posts, Volume 5" content: "Some content" url: "https://aws.amazon.com/appsync/" ) { title } post6: addPost(id:6 author: "AUTHORNAME" title: "A series of posts, Volume 6" content: "Some content" url: "https://aws.amazon.com/appsync/" ) { title } post7: addPost(id:7 author: "AUTHORNAME" title: "A series of posts, Volume 7" content: "Some content" url: "https://aws.amazon.com/appsync/" ) { title } post8: addPost(id:8 author: "AUTHORNAME" title: "A series of posts, Volume 8" content: "Some content" url: "https://aws.amazon.com/appsync/" ) { title } post9: addPost(id:9 author: "AUTHORNAME" title: "A series of posts, Volume 9" content: "Some content" url: "https://aws.amazon.com/appsync/" ) { title } }
  • Execute query(쿼리 실행)(주황색 재생 버튼)를 누릅니다.

이제 테이블을 스캔해 보겠습니다. 한 번에 5개 결과를 반환합니다.

  • 쿼리 창에 다음 쿼리를 붙여 넣습니다.

    query allPost { allPost(count: 5) { posts { id title } nextToken } }
  • Execute query(쿼리 실행)(주황색 재생 버튼)를 누릅니다.

  • 처음 5개 게시물이 쿼리 창 오른쪽에 있는 결과 창에 나타나야 합니다. 예를 들면 다음과 같아야 합니다.

    { "data": { "allPost": { "posts": [ { "id": "5", "title": "A series of posts, Volume 5" }, { "id": "1", "title": "A series of posts, Volume 1" }, { "id": "6", "title": "A series of posts, Volume 6" }, { "id": "9", "title": "A series of posts, Volume 9" }, { "id": "7", "title": "A series of posts, Volume 7" } ], "nextToken": "eyJ2ZXJzaW9uIjoxLCJ0b2tlbiI6IkFRSUNBSGo4eHR0RG0xWXhUa1F0cEhXMEp1R3B0M1B3eThOSmRvcG9ad2RHYjI3Z0lnRkJEdXdUK09hcnovRGhNTGxLTGdMUEFBQUI1akNDQWVJR0NTcUdTSWIzRFFFSEJxQ0NBZE13Z2dIUEFnRUFNSUlCeUFZSktvWklodmNOQVFjQk1CNEdDV0NHU0FGbEF3UUJMakFSQkF6ajFodkhKU1paT1pncTRaUUNBUkNBZ2dHWnJiR1dQWGxkMDB1N0xEdGY4Z2JsbktzRjRua1VCcks3TFJLcjZBTFRMeGFwVGJZMDRqOTdKVFQyYVRwSzdzbVdtNlhWWFVCTnFIOThZTzBWZHVkdDI2RlkxMHRqMDJ2QTlyNWJTUWpTbWh6NE5UclhUMG9KZWJSQ2JJbXBlaDRSVlg0Tis0WTVCN1IwNmJQWWQzOVhsbTlUTjBkZkFYMVErVCthaXZoNE5jMk50RitxVmU3SlJ5WmpzMEFkSGduM3FWd2VrOW5oeFVVd3JlK1loUks5QkRzemdiMDlmZmFPVXpzaFZ4cVJRbC93RURlOTcrRmVJdXZNby9NZ1F6dUdNbFRyalpNR3FuYzZBRnhwa0VlZTFtR0FwVDFISElUZlluakptYklmMGUzUmcxbVlnVHVSbDh4S0trNmR0QVoraEhLVDhuNUI3VnF4bHRtSnlNUXBrZGl6KzkyL3VzNDl4OWhrMnVxSW01ZFFwMjRLNnF0dm9ZK1BpdERuQTc5djhzb0grVytYT3VuQ2NVVDY4TVZ1Wk5KYkRuSEFSSEVlaTlVNVBTelU5RGZ6d2pPdmhqWDNJMWhwdWUrWi83MDVHVjlPQUxSTGlwZWZPeTFOZFhwZTdHRDZnQW00bUJUK2c1eC9Ec3ZDbWVnSDFDVXRTdHVuU1ZFa2JpZytQRC9oMUwyRTNqSHhVQldaa28yU256WUc0cG0vV1RSWkFVZHZuQT09In0=" } } }

5개 결과가 반환되고 다음 결과 집합을 가져오는데 사용할 수 있는 nextToken도 있습니다.

  • 이전 결과 집합에서 allPost을 포함하도록 nextToken 쿼리를 업데이트합니다.

    query allPost { allPost( count: 5 nextToken: "eyJ2ZXJzaW9uIjoxLCJ0b2tlbiI6IkFRSUNBSGo4eHR0RG0xWXhUa1F0cEhXMEp1R3B0M1B3eThOSmRvcG9ad2RHYjI3Z0lnRlluNktJRWl6V0ZlR3hJOVJkaStrZUFBQUI1akNDQWVJR0NTcUdTSWIzRFFFSEJxQ0NBZE13Z2dIUEFnRUFNSUlCeUFZSktvWklodmNOQVFjQk1CNEdDV0NHU0FGbEF3UUJMakFSQkF5cW8yUGFSZThnalFpemRCTUNBUkNBZ2dHWk1JODhUNzhIOFVUZGtpdFM2ZFluSWRyVDg4c2lkN1RjZzB2d1k3VGJTTWpSQ2U3WjY3TkUvU2I1dWNETUdDMmdmMHErSGJSL0pteGRzYzVEYnE1K3BmWEtBdU5jSENJdWNIUkJ0UHBPWVdWdCtsS2U5L1pNcWdocXhrem1RaXI1YnIvQkt6dU5hZmJCdE93NmtoM2Jna1BKM0RjWWhpMFBGbmhMVGg4TUVGSjBCcXg3RTlHR1V5N0tUS0JLZlV3RjFQZ0JRREdrNzFYQnFMK2R1S2IrVGtZZzVYMjFrc3NyQmFVTmNXZmhTeXE0ZUJHSWhqZWQ5c3VKWjBSSTc2ZnVQdlZkR3FLNENjQmxHYXhpekZnK2pKK1FneEU1SXduRTNYYU5TR0I4QUpmamR2bU1wbUk1SEdvWjlMUUswclczbG14RDRtMlBsaTNLaEVlcm9pem5zcmdINFpvcXIrN2ltRDN3QkJNd3BLbGQzNjV5Nnc4ZnMrK2FnbTFVOUlKOFFrOGd2bEgySHFROHZrZXBrMWlLdWRIQ25LaS9USnBlMk9JeEVPazVnRFlzRTRUU09HUlVJTkxYY2MvdW1WVEpBMUthV2hWTlAvdjNlSnlZQUszbWV6N2h5WHVXZ1BkTVBNWERQdTdjVnVRa3EwK3NhbGZOd2wvSUx4bHNyNDVwTEhuVFpyRWZvVlV1bXZ5S2VKY1RUU1lET05hM1NwWEd2UT09In0=" ) { posts { id author } nextToken } }
  • Execute query(쿼리 실행)(주황색 재생 버튼)를 누릅니다.

  • 나머지 4개 게시물이 쿼리 창 오른쪽에 있는 결과 창에 나타나야 합니다. 게시물이 모두 9개이며 남은 게시물이 없기 때문에 이 결과 집합에는 nextToken이 없습니다. 예를 들면 다음과 같아야 합니다.

    { "data": { "allPost": { "posts": [ { "id": "2", "title": "A series of posts, Volume 2" }, { "id": "3", "title": "A series of posts, Volume 3" }, { "id": "4", "title": "A series of posts, Volume 4" }, { "id": "8", "title": "A series of posts, Volume 8" } ], "nextToken": null } } }

allPostsBy작성자 리졸버 설정 (DynamoDB 쿼리)

DynamoDB에서 모든 게시물을 스캔하는 것 이외에 DynamoDB를 쿼리해 특정 작성자가 생성한 게시물을 검색할 수 있습니다. 앞서 이미 생성한 DynamoDB 테이블에는 특정 작성자가 생성한 게시물을 모두 검색하는 DynamoDB Query 작업에 사용할 수 있는 author-index라는 GlobalSecondaryIndex가 있습니다.

  • 스키마 탭을 선택합니다.

  • 스키마 창에서 다음과 같이 Query 형식을 수정하여 새로운 allPostsByAuthor 쿼리를 추가할 수 있습니다.

    type Query { allPostsByAuthor(author: String!, count: Int, nextToken: String): PaginatedPosts! allPost(count: Int, nextToken: String): PaginatedPosts! getPost(id: ID): Post }

    참고: 여기서는 allPost 쿼리에 사용한 것과 동일한 PaginatedPosts 형식을 사용합니다.

  • 저장(Save)을 선택합니다.

  • 오른쪽의 데이터 유형 창에서 쿼리 유형에서 새로 만든 allPostsBy작성자 필드를 찾은 다음 첨부를 선택합니다.

  • 작업 메뉴에서 런타임 업데이트를 선택한 다음 Unit Resolver (VTL전용) 를 선택합니다.

  • 데이터 소스 이름에서 을 선택합니다. PostDynamoDBTable

  • 다음을 Configure the request mapping template(요청 매핑 템플릿 구성)에 붙여 넣습니다.

    { "version" : "2017-02-28", "operation" : "Query", "index" : "author-index", "query" : { "expression": "author = :author", "expressionValues" : { ":author" : $util.dynamodb.toDynamoDBJson($context.arguments.author) } } #if( ${context.arguments.count} ) ,"limit": $util.toJson($context.arguments.count) #end #if( ${context.arguments.nextToken} ) ,"nextToken": "${context.arguments.nextToken}" #end }

    allPost 해석기처럼 이 해석기에는 두 가지 선택적 인수가 있는데, count는 단일 호출 시 반환되는 최대 항목 수를 지정하고, nextToken은 다음 결과 집합을 가져오는 데 사용할 수 있습니다(nextToken의 값은 이전 호출에서 얻을 수 있음).

  • 다음을 Configure the response mapping template(응답 매핑 템플릿 구성)에 붙여 넣습니다.

    { "posts": $utils.toJson($context.result.items) #if( ${context.result.nextToken} ) ,"nextToken": $util.toJson($context.result.nextToken) #end }

    참고: 이는 allPost 해석기에서 사용한 것과 동일한 응답 매핑 템플릿입니다.

  • 저장(Save)을 선택합니다.

Query 요청 매핑에 대한 자세한 내용은 쿼리 참조 문서를 참조하십시오.

를 API 호출하여 작성자의 모든 게시물을 쿼리하십시오.

이제 리졸버가 설정되었으며 들어오는 allPostsByAuthor 변이를 인덱스에 대한 Query DynamoDB 작업으로 변환하는 방법을 AWS AppSync 알고 있습니다. author-index 이제 테이블을 쿼리해 특정 작성자별로 게시물을 모두 검색할 수 있습니다.

지금까지 사용한 모든 게시물은 작성자가 동일하기 때문에 검색하기 전에 추가 게시물로 테이블을 채우겠습니다.

  • Queries 탭을 선택합니다.

  • 쿼리 창에 다음 변형을 붙여 넣습니다.

    mutation addPost { post1: addPost(id:10 author: "Nadia" title: "The cutest dog in the world" content: "So cute. So very, very cute." url: "https://aws.amazon.com/appsync/" ) { author, title } post2: addPost(id:11 author: "Nadia" title: "Did you know...?" content: "AppSync works offline?" url: "https://aws.amazon.com/appsync/" ) { author, title } post3: addPost(id:12 author: "Steve" title: "I like GraphQL" content: "It's great" url: "https://aws.amazon.com/appsync/" ) { author, title } }
  • Execute query(쿼리 실행)(주황색 재생 버튼)를 누릅니다.

이제 Nadia가 작성한 게시물을 모두 반환하도록 테이블을 쿼리하겠습니다.

  • 쿼리 창에 다음 쿼리를 붙여 넣습니다.

    query allPostsByAuthor { allPostsByAuthor(author: "Nadia") { posts { id title } nextToken } }
  • Execute query(쿼리 실행)(주황색 재생 버튼)를 누릅니다.

  • Nadia가 작성한 모든 게시물이 쿼리 창 오른쪽에 있는 결과 창에 나타나야 합니다. 예를 들면 다음과 같아야 합니다.

    { "data": { "allPostsByAuthor": { "posts": [ { "id": "10", "title": "The cutest dog in the world" }, { "id": "11", "title": "Did you know...?" } ], "nextToken": null } } }

Query에 대한 페이지 매김은 Scan을 수행할 때와 동일하게 작동합니다. 예를 들어, AUTHORNAME의 모든 게시물을 살펴보겠습니다. 이 경우 한 번에 5개 결과를 반환합니다.

  • 쿼리 창에 다음 쿼리를 붙여 넣습니다.

    query allPostsByAuthor { allPostsByAuthor( author: "AUTHORNAME" count: 5 ) { posts { id title } nextToken } }
  • Execute query(쿼리 실행)(주황색 재생 버튼)를 누릅니다.

  • AUTHORNAME가 작성한 모든 게시물이 쿼리 창 오른쪽에 있는 결과 창에 나타나야 합니다. 예를 들면 다음과 같아야 합니다.

    { "data": { "allPostsByAuthor": { "posts": [ { "id": "6", "title": "A series of posts, Volume 6" }, { "id": "4", "title": "A series of posts, Volume 4" }, { "id": "2", "title": "A series of posts, Volume 2" }, { "id": "7", "title": "A series of posts, Volume 7" }, { "id": "1", "title": "A series of posts, Volume 1" } ], "nextToken": "eyJ2ZXJzaW9uIjoxLCJ0b2tlbiI6IkFRSUNBSGo4eHR0RG0xWXhUa1F0cEhXMEp1R3B0M1B3eThOSmRvcG9ad2RHYjI3Z0lnSExqRnVhVUR3ZUhEZ2QzNGJ2QlFuY0FBQUNqekNDQW9zR0NTcUdTSWIzRFFFSEJxQ0NBbnd3Z2dKNEFnRUFNSUlDY1FZSktvWklodmNOQVFjQk1CNEdDV0NHU0FGbEF3UUJMakFSQkF5Qkg4Yk1obW9LVEFTZHM3SUNBUkNBZ2dKQ3dISzZKNlJuN3pyYUVKY1pWNWxhSkNtZW1KZ0F5N1dhZkc2UEdTNHpNQzJycTkwZHFJTFV6Z25wck9Gd3pMS3VOQ2JvUXc3VDI5eCtnVExIbGg4S3BqbzB1YjZHQ3FwcDhvNDVmMG9JbDlmdS9JdjNXcFNNSXFKTXZ1MEVGVWs1VzJQaW5jZGlUaVRtZFdYWlU1bkV2NkgyRFBRQWZYYlNnSmlHSHFLbmJZTUZZM0FTdmRIL0hQaVZBb1RCMk1YZkg0eGJOVTdEbjZtRFNhb2QwbzdHZHJEWDNtODQ1UXBQUVNyUFhHemY0WDkyajhIdlBCSWE4Smcrb0RxbHozUVQ5N2FXUXdYWWU2S0h4emI1ejRITXdEdXEyRDRkYzhoMi9CbW10MzRMelVGUVIyaExSZGRaZ0xkdzF5cHJZdFZwY3dEc1d4UURBTzdOcjV2ZEp4VVR2TVhmODBRSnp1REhXREpTVlJLdDJwWmlpaXhXeGRwRmNod1BzQ3d2aVBqMGwrcWFFWU1jMXNQbENkVkFGem43VXJrSThWbS8wWHlwR2xZb3BSL2FkV0xVekgrbGMrYno1ZEM2SnVLVXdtY1EyRXlZeDZiS0Izbi9YdUViWGdFeU5PMWZTdE1rRlhyWmpvMVpzdlYyUFRjMzMrdEs0ZDhkNkZrdjh5VVR6WHhJRkxIaVNsOUx6VVdtT3BCaWhrTFBCT09jcXkyOHh1UmkzOEM3UFRqMmN6c3RkOUo1VUY0azBJdUdEbVZzM2xjdWg1SEJjYThIeXM2aEpvOG1HbFpMNWN6R2s5bi8vRE1EbDY3RlJraG5QNFNhSDBpZGI5VFEvMERLeFRBTUdhcWpPaEl5ekVqd2ZDQVJleFdlbldyOGlPVkhScDhGM25WZVdvbFRGK002N0xpdi9XNGJXdDk0VEg3b0laUU5lYmZYKzVOKy9Td25Hb1dyMTlWK0pEb2lIRVFLZ1cwMWVuYjZKUXo5Slh2Tm95ZzF3RnJPVmxGc2xwNlRHa1BlN2Rnd2IrWT0ifQ==" } } }
  • 다음과 같이 이전 쿼리에서 반환된 값으로 nextToken 인수를 업데이트합니다.

    query allPostsByAuthor { allPostsByAuthor( author: "AUTHORNAME" count: 5 nextToken: "eyJ2ZXJzaW9uIjoxLCJ0b2tlbiI6IkFRSUNBSGo4eHR0RG0xWXhUa1F0cEhXMEp1R3B0M1B3eThOSmRvcG9ad2RHYjI3Z0lnSExqRnVhVUR3ZUhEZ2QzNGJ2QlFuY0FBQUNqekNDQW9zR0NTcUdTSWIzRFFFSEJxQ0NBbnd3Z2dKNEFnRUFNSUlDY1FZSktvWklodmNOQVFjQk1CNEdDV0NHU0FGbEF3UUJMakFSQkF5Qkg4Yk1obW9LVEFTZHM3SUNBUkNBZ2dKQ3dISzZKNlJuN3pyYUVKY1pWNWxhSkNtZW1KZ0F5N1dhZkc2UEdTNHpNQzJycTkwZHFJTFV6Z25wck9Gd3pMS3VOQ2JvUXc3VDI5eCtnVExIbGg4S3BqbzB1YjZHQ3FwcDhvNDVmMG9JbDlmdS9JdjNXcFNNSXFKTXZ1MEVGVWs1VzJQaW5jZGlUaVRtZFdYWlU1bkV2NkgyRFBRQWZYYlNnSmlHSHFLbmJZTUZZM0FTdmRIL0hQaVZBb1RCMk1YZkg0eGJOVTdEbjZtRFNhb2QwbzdHZHJEWDNtODQ1UXBQUVNyUFhHemY0WDkyajhIdlBCSWE4Smcrb0RxbHozUVQ5N2FXUXdYWWU2S0h4emI1ejRITXdEdXEyRDRkYzhoMi9CbW10MzRMelVGUVIyaExSZGRaZ0xkdzF5cHJZdFZwY3dEc1d4UURBTzdOcjV2ZEp4VVR2TVhmODBRSnp1REhXREpTVlJLdDJwWmlpaXhXeGRwRmNod1BzQ3d2aVBqMGwrcWFFWU1jMXNQbENkVkFGem43VXJrSThWbS8wWHlwR2xZb3BSL2FkV0xVekgrbGMrYno1ZEM2SnVLVXdtY1EyRXlZeDZiS0Izbi9YdUViWGdFeU5PMWZTdE1rRlhyWmpvMVpzdlYyUFRjMzMrdEs0ZDhkNkZrdjh5VVR6WHhJRkxIaVNsOUx6VVdtT3BCaWhrTFBCT09jcXkyOHh1UmkzOEM3UFRqMmN6c3RkOUo1VUY0azBJdUdEbVZzM2xjdWg1SEJjYThIeXM2aEpvOG1HbFpMNWN6R2s5bi8vRE1EbDY3RlJraG5QNFNhSDBpZGI5VFEvMERLeFRBTUdhcWpPaEl5ekVqd2ZDQVJleFdlbldyOGlPVkhScDhGM25WZVdvbFRGK002N0xpdi9XNGJXdDk0VEg3b0laUU5lYmZYKzVOKy9Td25Hb1dyMTlWK0pEb2lIRVFLZ1cwMWVuYjZKUXo5Slh2Tm95ZzF3RnJPVmxGc2xwNlRHa1BlN2Rnd2IrWT0ifQ==" ) { posts { id title } nextToken } }
  • Execute query(쿼리 실행)(주황색 재생 버튼)를 누릅니다.

  • AUTHORNAME가 작성한 잔여 게시물이 쿼리 창 오른쪽에 있는 결과 창에 나타나야 합니다. 예를 들면 다음과 같아야 합니다.

    { "data": { "allPostsByAuthor": { "posts": [ { "id": "8", "title": "A series of posts, Volume 8" }, { "id": "5", "title": "A series of posts, Volume 5" }, { "id": "3", "title": "A series of posts, Volume 3" }, { "id": "9", "title": "A series of posts, Volume 9" } ], "nextToken": null } } }

집합 사용

지금까지 Post 형식은 플랫 키/값 객체였습니다. AWS AppSyncDynamoDB 리졸버를 사용하여 세트, 목록, 맵과 같은 복잡한 객체를 모델링할 수도 있습니다.

태그를 포함하도록 Post 형식을 업데이트해 보겠습니다. 게시물에는 태그가 0개 이상 있을 수 있는데, 태그는 DynamoDB에 문자열 집합으로 저장됩니다. 또한 태그를 추가 및 제거하는 몇 가지 변형과 특정 태그가 지정된 게시물을 스캔하는 새 쿼리를 설정해 볼 것입니다.

  • 스키마 탭을 선택합니다.

  • 스키마 창에서 다음과 같이 Post 형식을 수정하여 새로운 tags 필드를 추가할 수 있습니다.

    type Post { id: ID! author: String title: String content: String url: String ups: Int! downs: Int! version: Int! tags: [String!] }
  • 스키마 창에서 다음과 같이 Query 형식을 수정하여 새로운 allPostsByTag 쿼리를 추가할 수 있습니다.

    type Query { allPostsByTag(tag: String!, count: Int, nextToken: String): PaginatedPosts! allPostsByAuthor(author: String!, count: Int, nextToken: String): PaginatedPosts! allPost(count: Int, nextToken: String): PaginatedPosts! getPost(id: ID): Post }
  • 스키마 창에서 다음과 같이 Mutation 유형을 수정하여 새로운 addTagremoveTag 뮤테이션을 추가할 수 있습니다.

    type Mutation { addTag(id: ID!, tag: String!): Post removeTag(id: ID!, tag: String!): Post deletePost(id: ID!, expectedVersion: Int): Post upvotePost(id: ID!): Post downvotePost(id: ID!): Post updatePost( id: ID!, author: String, title: String, content: String, url: String, expectedVersion: Int! ): Post addPost( author: String!, title: String!, content: String!, url: String! ): Post! }
  • 저장(Save)을 선택합니다.

  • 오른쪽의 데이터 유형 패널에서 쿼리 유형에서 새로 만든 allPostsBy태그 필드를 찾은 다음 [Attach] 를 선택합니다.

  • 데이터 원본 이름에서 을 선택합니다 PostDynamoDBTable.

  • 다음을 Configure the request mapping template(요청 매핑 템플릿 구성)에 붙여 넣습니다.

    { "version" : "2017-02-28", "operation" : "Scan", "filter": { "expression": "contains (tags, :tag)", "expressionValues": { ":tag": $util.dynamodb.toDynamoDBJson($context.arguments.tag) } } #if( ${context.arguments.count} ) ,"limit": $util.toJson($context.arguments.count) #end #if( ${context.arguments.nextToken} ) ,"nextToken": $util.toJson($context.arguments.nextToken) #end }
  • 다음을 Configure the response mapping template(응답 매핑 템플릿 구성)에 붙여 넣습니다.

    { "posts": $utils.toJson($context.result.items) #if( ${context.result.nextToken} ) ,"nextToken": $util.toJson($context.result.nextToken) #end }
  • 저장(Save)을 선택합니다.

  • 오른쪽의 데이터 유형 패널에서 뮤테이션 유형에서 새로 만든 addTag필드를 찾은 다음 연결을 선택합니다.

  • 데이터 원본 이름에서 을 선택합니다 PostDynamoDBTable.

  • 다음을 Configure the request mapping template(요청 매핑 템플릿 구성)에 붙여 넣습니다.

    { "version" : "2017-02-28", "operation" : "UpdateItem", "key" : { "id" : $util.dynamodb.toDynamoDBJson($context.arguments.id) }, "update" : { "expression" : "ADD tags :tags, version :plusOne", "expressionValues" : { ":tags" : { "SS": [ $util.toJson($context.arguments.tag) ] }, ":plusOne" : { "N" : 1 } } } }
  • 다음을 Configure the response mapping template(응답 매핑 템플릿 구성)에 붙여 넣습니다.

    $utils.toJson($context.result)
  • 저장(Save)을 선택합니다.

  • 오른쪽의 데이터 유형 패널에서 뮤테이션 유형에서 새로 만든 removeTag필드를 찾은 다음 연결을 선택합니다.

  • 데이터 원본 이름에서 을 선택합니다 PostDynamoDBTable.

  • 다음을 Configure the request mapping template(요청 매핑 템플릿 구성)에 붙여 넣습니다.

    { "version" : "2017-02-28", "operation" : "UpdateItem", "key" : { "id" : $util.dynamodb.toDynamoDBJson($context.arguments.id) }, "update" : { "expression" : "DELETE tags :tags ADD version :plusOne", "expressionValues" : { ":tags" : { "SS": [ $util.toJson($context.arguments.tag) ] }, ":plusOne" : { "N" : 1 } } } }
  • 다음을 Configure the response mapping template(응답 매핑 템플릿 구성)에 붙여 넣습니다.

    $utils.toJson($context.result)
  • 저장(Save)을 선택합니다.

를 API 호출하여 태그 사용

이제 리졸버를 설정했으니 수신 addTagremoveTag, 및 allPostsByTag 요청을 DynamoDB 및 작업으로 변환하는 방법을 AWS AppSync 알게 되었습니다. UpdateItem Scan

실행해 보기 위해 이전에 생성한 게시물 중 선택해 보겠습니다. 예를 들어, Nadia에서 작성한 게시물을 사용해 보겠습니다.

  • Queries 탭을 선택합니다.

  • 쿼리 창에 다음 쿼리를 붙여 넣습니다.

    query allPostsByAuthor { allPostsByAuthor( author: "Nadia" ) { posts { id title } nextToken } }
  • Execute query(쿼리 실행)(주황색 재생 버튼)를 누릅니다.

  • Nadia의 모든 게시물이 쿼리 창 오른쪽에 있는 결과 창에 나타나야 합니다. 예를 들면 다음과 같아야 합니다.

    { "data": { "allPostsByAuthor": { "posts": [ { "id": "10", "title": "The cutest dog in the world" }, { "id": "11", "title": "Did you known...?" } ], "nextToken": null } } }
  • 제목이 "The cutest dog in the world"인 게시물을 사용하겠습니다. 나중에 사용할 것이기 때문에 이 게시물의 id를 적어 둡니다.

dog 태그를 추가합니다.

  • 쿼리 창에 다음 변형을 붙여 넣습니다. 또한 앞서 적어둔 값을 갖도록 id 인수를 업데이트해야 합니다.

    mutation addTag { addTag(id:10 tag: "dog") { id title tags } }
  • Execute query(쿼리 실행)(주황색 재생 버튼)를 누릅니다.

  • 새 태그로 게시물이 업데이트됩니다.

    { "data": { "addTag": { "id": "10", "title": "The cutest dog in the world", "tags": [ "dog" ] } } }

태그를 다음과 같이 더 추가할 수 있습니다.

  • tag 인수를 puppy로 변경하도록 변형을 업데이트합니다.

    mutation addTag { addTag(id:10 tag: "puppy") { id title tags } }
  • Execute query(쿼리 실행)(주황색 재생 버튼)를 누릅니다.

  • 새 태그로 게시물이 업데이트됩니다.

    { "data": { "addTag": { "id": "10", "title": "The cutest dog in the world", "tags": [ "dog", "puppy" ] } } }

태그를 삭제할 수도 있습니다.

  • 쿼리 창에 다음 변형을 붙여 넣습니다. 또한 앞서 적어둔 값을 갖도록 id 인수를 업데이트해야 합니다.

    mutation removeTag { removeTag(id:10 tag: "puppy") { id title tags } }
  • Execute query(쿼리 실행)(주황색 재생 버튼)를 누릅니다.

  • 게시물이 업데이트되고 puppy 태그가 삭제됩니다.

    { "data": { "addTag": { "id": "10", "title": "The cutest dog in the world", "tags": [ "dog" ] } } }

또한 태그가 지정된 게시물을 모두 검색할 수도 있습니다.

  • 쿼리 창에 다음 쿼리를 붙여 넣습니다.

    query allPostsByTag { allPostsByTag(tag: "dog") { posts { id title tags } nextToken } }
  • Execute query(쿼리 실행)(주황색 재생 버튼)를 누릅니다.

  • dog 태그가 지정된 게시물이 다음과 같이 모두 반환됩니다.

    { "data": { "allPostsByTag": { "posts": [ { "id": "10", "title": "The cutest dog in the world", "tags": [ "dog", "puppy" ] } ], "nextToken": null } } }

목록 및 맵 사용

DynamoDB 집합을 사용하는 것 이외에 DynamoDB 목록 및 맵을 사용하여 단일 객체 내에서 복잡한 데이터를 모델링할 수 있습니다.

게시물에 주석을 추가하는 기능을 추가해 보겠습니다. 이 기능은 DynamoDB의 Post 객체에 대한 맵 객체 목록으로 모델링됩니다.

참고: 실제 애플리케이션에서는 설명을 고유의 테이블에 모델링하게 될 것입니다. 이 자습서에서는 설명을 Post 테이블에 추가하겠습니다.

  • 스키마 탭을 선택합니다.

  • 스키마 창에서 다음과 같이 새로운 Comment 형식을 추가합니다.

    type Comment { author: String! comment: String! }
  • 스키마 창에서 다음과 같이 Post 형식을 수정하여 새로운 comments 필드를 추가할 수 있습니다.

    type Post { id: ID! author: String title: String content: String url: String ups: Int! downs: Int! version: Int! tags: [String!] comments: [Comment!] }
  • 스키마 창에서 다음과 같이 Mutation 형식을 수정하여 새로운 addComment 변형을 추가할 수 있습니다.

    type Mutation { addComment(id: ID!, author: String!, comment: String!): Post addTag(id: ID!, tag: String!): Post removeTag(id: ID!, tag: String!): Post deletePost(id: ID!, expectedVersion: Int): Post upvotePost(id: ID!): Post downvotePost(id: ID!): Post updatePost( id: ID!, author: String, title: String, content: String, url: String, expectedVersion: Int! ): Post addPost( author: String!, title: String!, content: String!, url: String! ): Post! }
  • 저장(Save)을 선택합니다.

  • 오른쪽의 데이터 유형 패널에서 Mutation 유형에서 새로 만든 addComment필드를 찾은 다음 Attach를 선택합니다.

  • 데이터 원본 이름에서 을 선택합니다 PostDynamoDBTable.

  • 다음을 Configure the request mapping template(요청 매핑 템플릿 구성)에 붙여 넣습니다.

    { "version" : "2017-02-28", "operation" : "UpdateItem", "key" : { "id" : $util.dynamodb.toDynamoDBJson($context.arguments.id) }, "update" : { "expression" : "SET comments = list_append(if_not_exists(comments, :emptyList), :newComment) ADD version :plusOne", "expressionValues" : { ":emptyList": { "L" : [] }, ":newComment" : { "L" : [ { "M": { "author": $util.dynamodb.toDynamoDBJson($context.arguments.author), "comment": $util.dynamodb.toDynamoDBJson($context.arguments.comment) } } ] }, ":plusOne" : $util.dynamodb.toDynamoDBJson(1) } } }

    이 업데이트 표현식은 새 주석이 포함된 목록을 기존 comments 목록에 추가합니다. 목록이 아직 없으면 생성됩니다.

  • 다음을 Configure the response mapping template(응답 매핑 템플릿 구성)에 붙여 넣습니다.

    $utils.toJson($context.result)
  • 저장(Save)을 선택합니다.

를 API 호출하여 댓글을 추가합니다.

이제 리졸버를 설정했으니 수신 addComment 요청을 DynamoDB 작업으로 변환하는 방법을 AWS AppSync 알게 되었습니다. UpdateItem

태그를 추가한 것과 동일한 게시물에 주석을 추가해 보겠습니다.

  • Queries 탭을 선택합니다.

  • 쿼리 창에 다음 쿼리를 붙여 넣습니다.

    mutation addComment { addComment( id:10 author: "Steve" comment: "Such a cute dog." ) { id comments { author comment } } }
  • Execute query(쿼리 실행)(주황색 재생 버튼)를 누릅니다.

  • Nadia의 모든 게시물이 쿼리 창 오른쪽에 있는 결과 창에 나타나야 합니다. 예를 들면 다음과 같아야 합니다.

    { "data": { "addComment": { "id": "10", "comments": [ { "author": "Steve", "comment": "Such a cute dog." } ] } } }

이 요청을 여러 번 실행하면 목록에 주석이 여러 개 추가됩니다.

결론

이 자습서에서는 GraphQL을 사용하여 AWS AppSync DynamoDB에서 Post 객체를 조작할 수 API 있는 방법을 구축했습니다. 자세한 내용은 해석기 매핑 템플릿 참조 단원을 참조하십시오.

정리하려면 콘솔에서 AppSync API GraphQL을 삭제하면 됩니다.

이 자습서에서 생성한 DynamoDB 테이블과 IAM 역할을 삭제하려면 다음을 실행하여 스택을 AWSAppSyncTutorialForAmazonDynamoDB 삭제하거나 콘솔로 이동하여 스택을 삭제하면 AWS CloudFormation 됩니다.

aws cloudformation delete-stack \ --stack-name AWSAppSyncTutorialForAmazonDynamoDB