DynamoDB 해석기를 사용하여 간단한 사후 애플리케이션 생성 - AWS AppSync

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

DynamoDB 해석기를 사용하여 간단한 사후 애플리케이션 생성

참고

이제 APPSYNC_JS 런타임과 해당 설명서를 주로 지원합니다. 여기에서 APPSYNC_JS 런타임 및 해당 가이드를 사용하는 것이 좋습니다.

이 자습서에서는 자체 Amazon DynamoDB 테이블을 에 가져오 AWS AppSync 고 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 테이블

    • Post 테이블과 AWS AppSync 상호 작용할 수 있도록 허용하는 IAM 역할 및 관련 IAM 관리형 정책입니다.

  2. 스택 및 생성된 리소스에 대한 자세한 내용을 보려면 다음 CLI 명령을 실행합니다.

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

    aws cloudformation delete-stack --stack-name AWSAppSyncTutorialForAmazonDynamoDB

GraphQL 생성 API

에서 GraphQLAPI을 생성하려면 AWS AppSync:

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

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

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

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

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

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

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

기본 게시물 정의 API

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

  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 대시보드 에서 GraphQL 을 선택합니다API.

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

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

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

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

    3. 리전 에서 US-WEST-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)

AWS AppSync 가 DynamoDB 테이블을 인식한 후 해석기 를 정의하여 개별 쿼리 및 돌연변이에 연결할 수 있습니다. 생성한 첫 번째 해석기는 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 대시보드 에서 GraphQL 을 선택합니다API.

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

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

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

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

    3. 리전 에서 US-WEST-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 에 삽입된 새 항목을 인덱싱하는 GraphQL ID! 유형이 의 형태로도 사용할 수 $utils.autoId() 있는 자동 ID 생성을 위한 유틸리티와 함께 클라이언트 arguments. AWS AppSync com의 일부로 제공되도록 지정했습니다"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 PutItem 작업으로 변환할 AWS AppSync 수 있습니다. 이제 변형을 실행해 테이블에 데이터를 입력할 수 있습니다.

  • 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 는 요청 매핑 문서를 사용하여 DynamoDBPutItem 요청을 생성하고 실행합니다.

  • 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 쿼리를 DynamoDBGetItem 작업으로 변환하는 방법을 AWS AppSync 알아봅니다. 이제 앞에서 생성한 게시물을 검색하는 쿼리를 실행할 수 있습니다.

  • 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 는 요청 매핑 문서를 사용하여 DynamoDB GetItem 요청을 생성하고 실행합니다.

  • 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 } } } }

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

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

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

    $utils.toJson($context.result)

를 호출API하여 게시물 업데이트

이제 해석기가 설정되었습니다.수신 update 돌연변이를 DynamoDBUpdate 작업으로 변환하는 방법을 AWS AppSync 알아봅니다. 이제 앞서 작성한 항목을 업데이트하는 변형을 실행할 수 있습니다.

  • 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 } } }

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

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을 건너뜁니다. 인수가 무언가로 설정된 경우 AWS AppSync 및 DynamoDB에 DynamoDB 의 객체에서 해당 속성을 업데이트하도록 요청합니다. 속성이 null로 설정된 경우 AWS AppSync 및 DynamoDB에 해당 속성을 포스트 객체에서 제거하도록 요청합니다. 인수가 지정되어 있지 않은 경우에는 속성을 그냥 둡니다. 이 템플릿 역시 version 필드를 증가시킵니다.

또한 새로운 condition 섹션이 있습니다. 조건 표현식을 사용하면 작업이 수행되기 전에 DynamoDB에 이미 있는 객체의 상태를 기반으로 요청이 성공해야 하는지 여부를 AWS AppSync 및 DynamoDB에 알릴 수 있습니다. 이 경우에는 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에 titlecontent 필드만 업데이트하도록 요청했습니다. 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 유형에는 레코드 업보트 및 다운보트를 활성화할 수 있는 upsdowns 필드가 있지만, 지금까지 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 UpdateItem 작업으로 변환하는 방법을 AWS AppSync 알고 있습니다. 이제 앞서 생성한 게시물을 추천 또는 비추천하는 변형을 실행할 수 있습니다.

  • 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 필드를 찾은 다음 연결을 선택합니다.

  • 작업 메뉴 에서 런타임 업데이트를 선택한 다음 Unit Resolver(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 돌연변이를 DynamoDBDeleteItem 작업으로 변환하는 방법을 AWS AppSync 알아봅니다. 이제 변형을 실행해 테이블에 데이터를 삭제할 수 있습니다.

  • 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 쿼리를 DynamoDBScan 작업으로 변환하는 방법을 AWS AppSync 알아봅니다. 이제 테이블을 스캔해 게시물을 모두 검색할 수 있습니다.

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

  • 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하여 작성자가 모든 게시물 쿼리

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

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

  • 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태그 필드를 찾은 다음 연결 을 선택합니다.

  • 데이터 소스 이름 에서 를 선택합니다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하여 태그 작업

이제 해석기를 설정했으므로 들어오는 , 및 allPostsByTag 요청을 DynamoDBUpdateItem addTag removeTagScan 작업으로 변환하는 방법을 AWS AppSync 알아봅니다.

실행해 보기 위해 이전에 생성한 게시물 중 선택해 보겠습니다. 예를 들어, 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)을 선택합니다.

  • 오른쪽의 데이터 유형 창에서 돌연변이 유형에서 새로 생성된 addComment 필드를 찾은 다음 연결 을 선택합니다.

  • 데이터 소스 이름 에서 를 선택합니다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 요청을 DynamoDBUpdateItem 작업으로 변환하는 방법을 AWS AppSync 알아봅니다.

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

  • 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." } ] } } }

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

결론

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

정리하려면 콘솔API에서 AppSync GraphQL을 삭제할 수 있습니다.

DynamoDB 테이블과 이 자습서를 위해 생성한 IAM 역할을 삭제하려면 다음을 실행하여 AWSAppSyncTutorialForAmazonDynamoDB 스택을 삭제하거나 AWS CloudFormation 콘솔을 방문하여 스택을 삭제할 수 있습니다.

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