

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

# Membuat aplikasi posting sederhana menggunakan DynamoDB resolvers
<a name="tutorial-dynamodb-resolvers"></a>

**catatan**  
Kami sekarang terutama mendukung runtime APPSYNC\$1JS dan dokumentasinya. [Harap pertimbangkan untuk menggunakan runtime APPSYNC\$1JS dan panduannya di sini.](https://docs.aws.amazon.com/appsync/latest/devguide/tutorials-js.html)

Tutorial ini menunjukkan bagaimana Anda dapat membawa tabel Amazon DynamoDB Anda sendiri dan menghubungkannya AWS AppSync ke GraphQL API.

Anda dapat mengizinkan AWS AppSync penyediaan sumber daya DynamoDB atas nama Anda. Atau, jika Anda mau, Anda dapat menghubungkan tabel yang ada ke skema GraphQL dengan membuat sumber data dan resolver. Dalam kedua kasus, Anda akan dapat membaca dan menulis ke database DynamoDB Anda melalui pernyataan GraphQL dan berlangganan data real-time.

Ada langkah-langkah konfigurasi khusus yang perlu diselesaikan agar pernyataan GraphQL diterjemahkan ke operasi DynamoDB, dan agar tanggapan diterjemahkan kembali ke GraphQL. Tutorial ini menguraikan proses konfigurasi melalui beberapa skenario dunia nyata dan pola akses data.

## Menyiapkan tabel DynamoDB Anda
<a name="setting-up-your-ddb-tables"></a>

Untuk memulai tutorial ini, pertama-tama Anda harus mengikuti langkah-langkah di bawah ini untuk menyediakan AWS sumber daya.

1. Menyediakan AWS sumber daya menggunakan AWS CloudFormation template berikut di 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
   ```

   Atau, Anda dapat meluncurkan CloudFormation tumpukan berikut di wilayah AS-Barat 2 (Oregon) di akun Anda AWS .

   [https://console.aws.amazon.com/cloudformation/home?region=us-west-2#/stacks/new?templateURL=https://s3.us-west-2.amazonaws.com/awsappsync/resources/dynamodb/AmazonDynamoDBCFTemplate.yaml](https://console.aws.amazon.com/cloudformation/home?region=us-west-2#/stacks/new?templateURL=https://s3.us-west-2.amazonaws.com/awsappsync/resources/dynamodb/AmazonDynamoDBCFTemplate.yaml)

   Ini menciptakan yang berikut:
   + Sebuah tabel DynamoDB `AppSyncTutorial-Post` disebut yang akan menyimpan data. `Post`
   + Peran IAM dan kebijakan terkelola IAM terkait AWS AppSync untuk memungkinkan berinteraksi dengan tabel. `Post`

1. Untuk melihat detail selengkapnya tentang tumpukan dan sumber daya yang dibuat, jalankan perintah CLI berikut:

   ```
   aws cloudformation describe-stacks --stack-name AWSAppSyncTutorialForAmazonDynamoDB
   ```

1. Untuk menghapus sumber daya nanti, Anda dapat menjalankan yang berikut:

   ```
   aws cloudformation delete-stack --stack-name AWSAppSyncTutorialForAmazonDynamoDB
   ```

## Membuat GraphQL API
<a name="creating-your-graphql-api"></a>

Untuk membuat GraphQL API di: AWS AppSync

1. Masuk ke Konsol Manajemen AWS dan buka [AppSync konsol](https://console.aws.amazon.com/appsync/).

   1. Di **APIs dasbor**, pilih **Buat API**.

1. Di bawah jendela **Sesuaikan API atau impor dari Amazon DynamoDB**, **pilih** Bangun dari awal.

   1. Pilih **Mulai** di sebelah kanan jendela yang sama.

1. Di bidang **nama API**, atur nama API ke`AWSAppSyncTutorial`.

1. Pilih **Buat**.

 AWS AppSync Konsol membuat API GraphQL baru untuk Anda menggunakan mode autentikasi kunci API. Anda dapat menggunakan konsol untuk mengatur sisa GraphQL API dan menjalankan kueri terhadapnya selama sisa tutorial ini.

## Mendefinisikan API posting dasar
<a name="defining-a-basic-post-api"></a>

Sekarang setelah Anda membuat AWS AppSync GraphQL API, Anda dapat menyiapkan skema dasar yang memungkinkan pembuatan dasar, pengambilan, dan penghapusan data posting.

1. Masuk ke Konsol Manajemen AWS dan buka [AppSync konsol](https://console.aws.amazon.com/appsync/).

   1. Di **APIs dasbor**, pilih API yang baru saja Anda buat.

1. Di **Sidebar**, pilih **Skema**.

   1. Di panel **Skema**, ganti konten dengan kode berikut:

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

1. Pilih **Simpan**.

Skema ini mendefinisikan `Post` jenis dan operasi untuk menambah dan mendapatkan `Post` objek.

## Mengkonfigurasi Sumber Data untuk Tabel DynamoDB
<a name="configuring-the-data-source-for-the-ddb-tables"></a>

Selanjutnya, tautkan kueri dan mutasi yang ditentukan dalam skema ke tabel `AppSyncTutorial-Post` DynamoDB.

Pertama, AWS AppSync perlu menyadari tabel Anda. Anda melakukan ini dengan menyiapkan sumber data di AWS AppSync:

1. Masuk ke Konsol Manajemen AWS dan buka [AppSync konsol](https://console.aws.amazon.com/appsync/).

   1. Di **APIs dasbor**, pilih GraphQL API Anda.

   1. Di **Sidebar**, pilih **Sumber Data**.

1. Pilih **Buat sumber data**.

   1. Untuk **nama sumber data**, masukkan`PostDynamoDBTable`. 

   1. Untuk **tipe sumber data**, pilih tabel **Amazon DynamoDB**.

   1. Untuk **Wilayah**, pilih **US-WEST-2**.

   1. Untuk **nama Tabel**, pilih tabel **AppSyncTutorial-Post DynamoDB**.

   1. Buat peran IAM baru (disarankan) atau pilih peran yang sudah ada yang memiliki izin `lambda:invokeFunction` IAM. Peran yang ada memerlukan kebijakan kepercayaan, seperti yang dijelaskan di bagian [Melampirkan sumber data](attaching-a-data-source.md). 

      Berikut ini adalah contoh kebijakan IAM yang memiliki izin yang diperlukan untuk melakukan operasi pada sumber daya:

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

****  

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

------

1. Pilih **Buat**.

## Menyiapkan AddPost resolver (DynamoDB) PutItem
<a name="setting-up-the-addpost-resolver-dynamodb-putitem"></a>

**Setelah AWS AppSync mengetahui tabel DynamoDB, Anda dapat menautkannya ke kueri dan mutasi individual dengan mendefinisikan Resolvers.** Resolver pertama yang Anda buat adalah `addPost` resolver, yang memungkinkan Anda untuk membuat posting di tabel DynamoDB. `AppSyncTutorial-Post`

Sebuah resolver memiliki komponen-komponen berikut:
+ Lokasi dalam skema GraphQL untuk melampirkan resolver. Dalam hal ini, Anda menyiapkan resolver di `addPost` bidang pada tipe. `Mutation` Penyelesai ini akan dipanggil saat pemanggil memanggil. `mutation { addPost(...){...} }`
+ Sumber data yang akan digunakan untuk resolver ini. Dalam hal ini, Anda ingin menggunakan sumber `PostDynamoDBTable` data yang Anda tentukan sebelumnya, sehingga Anda dapat menambahkan entri ke dalam tabel `AppSyncTutorial-Post` DynamoDB.
+ Templat pemetaan permintaan . Tujuan dari template pemetaan permintaan adalah untuk mengambil permintaan masuk dari pemanggil dan menerjemahkannya ke dalam instruksi untuk melakukan AWS AppSync terhadap DynamoDB.
+ Templat pemetaan respons. Tugas template pemetaan respons adalah mengambil respons dari DynamoDB dan menerjemahkannya kembali menjadi sesuatu yang diharapkan GraphQL. Ini berguna jika bentuk data di DynamoDB berbeda dengan `Post` tipe di GraphQL, tetapi dalam hal ini mereka memiliki bentuk yang sama, jadi Anda cukup melewatkan data.

Untuk mengatur resolver:

1. Masuk ke Konsol Manajemen AWS dan buka [AppSync konsol](https://console.aws.amazon.com/appsync/).

   1. Di **APIs dasbor**, pilih GraphQL API Anda.

   1. Di **Sidebar**, pilih **Sumber Data**.

1. Pilih **Buat sumber data**.

   1. Untuk **nama sumber data**, masukkan`PostDynamoDBTable`. 

   1. Untuk **tipe sumber data**, pilih tabel **Amazon DynamoDB**.

   1. Untuk **Wilayah**, pilih **US-WEST-2**.

   1. Untuk **nama Tabel**, pilih tabel **AppSyncTutorial-Post DynamoDB**.

   1. Buat peran IAM baru (disarankan) atau pilih peran yang sudah ada yang memiliki izin `lambda:invokeFunction` IAM. Peran yang ada memerlukan kebijakan kepercayaan, seperti yang dijelaskan di bagian [Melampirkan sumber data](attaching-a-data-source.md). 

      Berikut ini adalah contoh kebijakan IAM yang memiliki izin yang diperlukan untuk melakukan operasi pada sumber daya:

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

****  

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

------

1. Pilih **Buat**.

1. Pilih tab **Skema**.

1. ****Di panel **tipe Data** di sebelah kanan, temukan bidang **AddPost** pada tipe Mutasi, lalu pilih Lampirkan.****

1. Di **menu Action**, pilih **Update runtime**, lalu pilih **Unit Resolver (hanya VTL**).

1. Di **Nama sumber data**, pilih **PostDynamoDBTable**.

1. Di **Konfigurasikan templat pemetaan permintaan**, tempel yang berikut ini:

   ```
   {
       "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 }
       }
   }
   ```

   **Catatan:** *Tipe* ditentukan pada semua kunci dan nilai atribut. Misalnya, Anda mengatur `author` bidang ke`{ "S" : "${context.arguments.author}" }`. `S`Bagian menunjukkan kepada AWS AppSync dan DynamoDB bahwa nilai akan menjadi nilai string. Nilai aktual akan diisi dari `author` argumen. Demikian pula, `version` bidang adalah bidang angka karena digunakan `N` untuk tipe. Akhirnya, Anda juga menginisialisasi`ups`, `downs` dan `version` bidang.

   Untuk tutorial ini Anda telah menentukan bahwa tipe `ID!` GraphQL, yang mengindeks item baru yang dimasukkan ke DynamoDB, datang sebagai bagian dari argumen klien. AWS AppSync dilengkapi dengan utilitas untuk pembuatan ID otomatis `$utils.autoId()` yang disebut yang bisa Anda gunakan juga dalam bentuk`"id" : { "S" : "${$utils.autoId()}" }`. Kemudian Anda bisa meninggalkan `id: ID!` keluar dari definisi skema `addPost()` dan itu akan dimasukkan secara otomatis. Anda tidak akan menggunakan teknik ini untuk tutorial ini, tetapi Anda harus menganggapnya sebagai praktik yang baik saat menulis ke tabel DynamoDB.

   Untuk informasi selengkapnya tentang templat pemetaan, lihat dokumentasi referensi [Ikhtisar Templat Pemetaan Resolver](resolver-mapping-template-reference-overview.md#aws-appsync-resolver-mapping-template-reference-overview). Untuk informasi selengkapnya tentang pemetaan GetItem permintaan, lihat dokumentasi [GetItem](aws-appsync-resolver-mapping-template-reference-dynamodb-getitem.md)referensi. Untuk informasi selengkapnya tentang jenis, lihat dokumentasi referensi [Sistem Jenis (Permintaan Pemetaan)](aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-request.md).

1. Di **Konfigurasikan template pemetaan respons**, tempel yang berikut ini:

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

    **Catatan:** Karena bentuk data dalam `AppSyncTutorial-Post` tabel sama persis dengan bentuk `Post` tipe di GraphQL, template pemetaan respons hanya meneruskan hasilnya secara langsung. Perhatikan juga bahwa semua contoh dalam tutorial ini menggunakan template pemetaan respons yang sama, jadi Anda hanya membuat satu file.

1. Pilih **Simpan**.

### Panggil API untuk Menambahkan Posting
<a name="call-the-api-to-add-a-post"></a>

Sekarang resolver sudah diatur, AWS AppSync dapat menerjemahkan `addPost` mutasi yang masuk ke operasi DynamoDB. PutItem Anda sekarang dapat menjalankan mutasi untuk meletakkan sesuatu di tabel.
+ Pilih tab **Kueri**.
+ Di panel **Kueri**, tempel mutasi berikut:

  ```
  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
    }
  }
  ```
+ Pilih **Execute query** (tombol putar oranye).
+ Hasil posting yang baru dibuat akan muncul di panel hasil di sebelah kanan panel kueri. Itu terlihat serupa dengan yang berikut ini:

  ```
  {
    "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
      }
    }
  }
  ```

Inilah yang terjadi:
+ AWS AppSync menerima permintaan `addPost` mutasi.
+ AWS AppSync mengambil permintaan, dan template pemetaan permintaan, dan menghasilkan dokumen pemetaan permintaan. Ini akan terlihat seperti:

  ```
  {
      "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 menggunakan dokumen pemetaan permintaan untuk menghasilkan dan mengeksekusi permintaan DynamoDB`PutItem`.
+ AWS AppSync mengambil hasil `PutItem` permintaan dan mengubahnya kembali ke tipe 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
  }
  ```
+ Melewatkannya melalui dokumen pemetaan respons, yang baru saja melewatinya tanpa perubahan.
+ Mengembalikan objek yang baru dibuat dalam respons GraphQL.

## Menyiapkan GetPost Resolver (DynamoDB) GetItem
<a name="setting-up-the-getpost-resolver-ddb-getitem"></a>

Sekarang bahwa Anda dapat menambahkan data ke tabel `AppSyncTutorial-Post` DynamoDB, Anda perlu mengatur query sehingga dapat mengambil data dari tabel. `getPost` `AppSyncTutorial-Post` Untuk melakukan ini, Anda mengatur resolver lain.
+ Pilih tab **Skema**.
+ ****Di panel **tipe Data** di sebelah kanan, temukan bidang **GetPost** pada tipe Query, lalu pilih Lampirkan.****
+ Di **menu Action**, pilih **Update runtime**, lalu pilih **Unit Resolver (hanya VTL**).
+ Di **Nama sumber data**, pilih **PostDynamoDBTable**.
+ Di **Konfigurasikan templat pemetaan permintaan**, tempel yang berikut ini:

  ```
  {
      "version" : "2017-02-28",
      "operation" : "GetItem",
      "key" : {
          "id" : $util.dynamodb.toDynamoDBJson($ctx.args.id)
      }
  }
  ```
+ Di **Konfigurasikan template pemetaan respons**, tempel yang berikut ini:

  ```
  $utils.toJson($context.result)
  ```
+ Pilih **Simpan**.

### Panggil API untuk Mendapatkan Postingan
<a name="call-the-api-to-get-a-post"></a>

Sekarang resolver telah diatur, AWS AppSync tahu bagaimana menerjemahkan `getPost` query masuk ke operasi DynamoDB. `GetItem` Anda sekarang dapat menjalankan kueri untuk mengambil posting yang Anda buat sebelumnya.
+ Pilih tab **Kueri**.
+ Di panel **Kueri**, tempel berikut ini:

  ```
  query getPost {
    getPost(id:123) {
      id
      author
      title
      content
      url
      ups
      downs
      version
    }
  }
  ```
+ Pilih **Execute query** (tombol putar oranye).
+ Posting yang diambil dari DynamoDB akan muncul di panel hasil di sebelah kanan panel kueri. Itu terlihat serupa dengan yang berikut ini:

  ```
  {
    "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
      }
    }
  }
  ```

Inilah yang terjadi:
+ AWS AppSync menerima permintaan `getPost` kueri.
+ AWS AppSync mengambil permintaan, dan template pemetaan permintaan, dan menghasilkan dokumen pemetaan permintaan. Ini akan terlihat seperti:

  ```
  {
      "version" : "2017-02-28",
      "operation" : "GetItem",
      "key" : {
          "id" : { "S" : "123" }
      }
  }
  ```
+ AWS AppSync menggunakan dokumen pemetaan permintaan untuk menghasilkan dan mengeksekusi permintaan DynamoDB GetItem .
+ AWS AppSync mengambil hasil `GetItem` permintaan dan mengubahnya kembali ke tipe 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
  }
  ```
+ Melewatkannya melalui dokumen pemetaan respons, yang baru saja melewatinya tanpa perubahan.
+ Mengembalikan objek yang diambil dalam respons.

Atau, ambil contoh berikut:

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

Jika `getPost` kueri Anda hanya membutuhkan`id`,, dan `author``title`, Anda dapat mengubah template pemetaan permintaan Anda untuk menggunakan ekspresi proyeksi untuk menentukan hanya atribut yang Anda inginkan dari tabel DynamoDB Anda untuk menghindari transfer data yang tidak perlu dari DynamoDB ke. AWS AppSync Misalnya, template pemetaan permintaan mungkin terlihat seperti cuplikan di bawah ini:

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

## Membuat Mutasi UpdatePost (DynamoDB) UpdateItem
<a name="create-an-updatepost-mutation-ddb-updateitem"></a>

Sejauh ini Anda dapat membuat dan mengambil `Post` objek di DynamoDB. Selanjutnya, Anda akan mengatur mutasi baru untuk memungkinkan kita untuk memperbarui objek. Anda akan melakukan ini menggunakan operasi UpdateItem DynamoDB.
+ Pilih tab **Skema**.
+ Di panel **Skema**, ubah `Mutation` tipe untuk menambahkan `updatePost` mutasi baru sebagai berikut:

  ```
  type Mutation {
      updatePost(
          id: ID!,
          author: String!,
          title: String!,
          content: String!,
          url: String!
      ): Post
      addPost(
          author: String!
          title: String!
          content: String!
          url: String!
      ): Post!
  }
  ```
+ Pilih **Simpan**.
+ ****Di panel **tipe Data** di sebelah kanan, temukan bidang **UpdatePost** yang baru dibuat pada tipe Mutasi dan kemudian pilih Lampirkan.****
+ Di **menu Action**, pilih **Update runtime**, lalu pilih **Unit Resolver (hanya VTL**).
+ Di **Nama sumber data**, pilih **PostDynamoDBTable**.
+ Di **Konfigurasikan templat pemetaan permintaan**, tempel yang berikut ini:

  ```
  {
      "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 }
          }
      }
  }
  ```

   **Catatan:** Resolver ini menggunakan DynamoDB UpdateItem, yang secara signifikan berbeda dari operasi. PutItem Alih-alih menulis seluruh item, Anda hanya meminta DynamoDB untuk memperbarui atribut tertentu. Ini dilakukan dengan menggunakan DynamoDB Update Expressions. Ekspresi itu sendiri ditentukan dalam `expression` bidang di `update` bagian. Dikatakan untuk mengatur atribut `author``title`,, `content` dan url, dan kemudian menambah `version` bidang. Nilai yang digunakan tidak muncul dalam ekspresi itu sendiri; ekspresi memiliki placeholder yang memiliki nama dimulai dengan titik dua, yang kemudian didefinisikan di `expressionValues` bidang. Akhirnya, DynamoDB memiliki kata-kata cadangan yang tidak dapat muncul di. `expression` Misalnya, `url` adalah kata yang dicadangkan, jadi untuk memperbarui `url` bidang Anda dapat menggunakan placeholder nama dan mendefinisikannya di `expressionNames` bidang.

  Untuk info selengkapnya tentang pemetaan `UpdateItem` permintaan, lihat dokumentasi [UpdateItem](aws-appsync-resolver-mapping-template-reference-dynamodb-updateitem.md)referensi. Untuk informasi selengkapnya tentang cara menulis ekspresi pembaruan, lihat dokumentasi [DynamoDB UpdateExpressions ](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html).
+ Di **Konfigurasikan template pemetaan respons**, tempel yang berikut ini:

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

### Panggil API untuk Memperbarui Posting
<a name="call-the-api-to-update-a-post"></a>

Sekarang resolver telah diatur, AWS AppSync tahu bagaimana menerjemahkan `update` mutasi yang masuk ke operasi DynamoDB. `Update` Anda sekarang dapat menjalankan mutasi untuk memperbarui item yang Anda tulis sebelumnya.
+ Pilih tab **Kueri**.
+ Di panel **Kueri**, tempel mutasi berikut. Anda juga perlu memperbarui `id` argumen ke nilai yang Anda catat sebelumnya.

  ```
  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
    }
  }
  ```
+ Pilih **Execute query** (tombol putar oranye).
+ Posting yang diperbarui di DynamoDB akan muncul di panel hasil di sebelah kanan panel kueri. Itu terlihat serupa dengan yang berikut ini:

  ```
  {
    "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
      }
    }
  }
  ```

Dalam contoh ini, `downs` bidang `ups` and tidak dimodifikasi karena template pemetaan permintaan tidak meminta AWS AppSync dan DynamoDB melakukan apa pun dengan bidang tersebut. Juga, `version` bidang bertambah 1 karena Anda meminta AWS AppSync dan DynamoDB untuk menambahkan 1 ke bidang. `version`

## Memodifikasi UpdatePost Resolver (DynamoDB) UpdateItem
<a name="modifying-the-updatepost-resolver-dynamodb-updateitem"></a>

Ini adalah awal yang baik untuk `updatePost` mutasi, tetapi memiliki dua masalah utama:
+ Jika Anda ingin memperbarui hanya satu bidang, Anda harus memperbarui semua bidang.
+ Jika dua orang memodifikasi objek, Anda berpotensi kehilangan informasi.

Untuk mengatasi masalah ini, Anda akan memodifikasi `updatePost` mutasi untuk hanya memodifikasi argumen yang ditentukan dalam permintaan, dan kemudian menambahkan kondisi ke `UpdateItem` operasi.

1. Pilih tab **Skema**.

1. Di panel **Skema**, ubah `updatePost` bidang dalam `Mutation` tipe untuk menghapus tanda seru dari,,, dan `url` argumen `author` `title``content`, pastikan untuk membiarkan bidang apa adanya. `id` Ini akan membuat mereka argumen opsional. Juga, tambahkan `expectedVersion` argumen baru yang diperlukan.

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

1. Pilih **Simpan**.

1. **Di panel **tipe Data** di sebelah kanan, temukan bidang **UpdatePost** pada tipe Mutasi.**

1. Pilih **PostDynamoDBTable**untuk membuka resolver yang ada.

1. Di **Konfigurasikan templat pemetaan permintaan, ubah templat** pemetaan permintaan sebagai berikut:

   ```
   {
       "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)
           }
       }
   }
   ```

1. Pilih **Simpan**.

Template ini adalah salah satu contoh yang lebih kompleks. Ini menunjukkan kekuatan dan fleksibilitas template pemetaan. Ini mengulang semua argumen, melompati `id` dan`expectedVersion`. Jika argumen diatur ke sesuatu, ia meminta AWS AppSync dan DynamoDB untuk memperbarui atribut itu pada objek di DynamoDB. Jika atribut diatur ke null, ia meminta AWS AppSync dan DynamoDB untuk menghapus atribut itu dari objek post. Jika argumen tidak ditentukan, itu meninggalkan atribut saja. Ini juga menambah `version` bidang.

Juga, ada `condition` bagian baru. Ekspresi kondisi memungkinkan Anda memberi tahu AWS AppSync dan DynamoDB apakah permintaan harus berhasil atau tidak berdasarkan status objek yang sudah ada di DynamoDB sebelum operasi dilakukan. Dalam hal ini, Anda hanya ingin `UpdateItem` permintaan berhasil jika `version` bidang item saat ini di DynamoDB sama persis dengan argumen. `expectedVersion`

Untuk informasi selengkapnya tentang ekspresi kondisi, lihat dokumentasi referensi [Ekspresi Kondisi](aws-appsync-resolver-mapping-template-reference-dynamodb-condition-expressions.md).

### Panggil API untuk Memperbarui Posting
<a name="id1"></a>

Mari kita coba memperbarui `Post` objek dengan resolver baru:
+ Pilih tab **Kueri**.
+ Di panel **Kueri**, tempel mutasi berikut. Anda juga perlu memperbarui `id` argumen ke nilai yang Anda catat sebelumnya.

  ```
  mutation updatePost {
    updatePost(
      id:123
      title: "An empty story"
      content: null
      expectedVersion: 2
    ) {
      id
      author
      title
      content
      url
      ups
      downs
      version
    }
  }
  ```
+ Pilih **Execute query** (tombol putar oranye).
+ Posting yang diperbarui di DynamoDB akan muncul di panel hasil di sebelah kanan panel kueri. Itu terlihat serupa dengan yang berikut ini:

  ```
  {
    "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
      }
    }
  }
  ```

Dalam permintaan ini, Anda meminta AWS AppSync dan DynamoDB untuk memperbarui bidang dan saja`title`. `content` Itu meninggalkan semua bidang lainnya sendirian (selain menambah `version` bidang). Anda mengatur `title` atribut ke nilai baru, dan menghapus `content` atribut dari posting. Bidang `author``url`,`ups`, dan `downs` ladang dibiarkan tak tersentuh.

Coba jalankan permintaan mutasi lagi, biarkan permintaan persis seperti apa adanya. Anda akan melihat respons yang mirip dengan berikut ini:

```
{
  "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)"
    }
  ]
}
```

Permintaan gagal karena ekspresi kondisi dievaluasi menjadi false:
+ Pertama kali Anda menjalankan permintaan, nilai `version` bidang posting di DynamoDB `2` adalah, yang cocok dengan argumen. `expectedVersion` Permintaan berhasil, yang berarti `version` bidang tersebut bertambah di DynamoDB ke. `3`
+ Kedua kalinya Anda menjalankan permintaan, nilai `version` bidang posting di DynamoDB `3` adalah, yang tidak cocok dengan argumen. `expectedVersion`

Pola ini biasanya disebut *penguncian optimis*.

Sebuah fitur dari AWS AppSync DynamoDB resolver adalah bahwa ia mengembalikan nilai saat ini dari objek post di DynamoDB. Anda dapat menemukan ini di `data` bidang di `errors` bagian respons GraphQL. Aplikasi Anda dapat menggunakan informasi ini untuk memutuskan bagaimana hal itu harus dilanjutkan. Dalam hal ini, Anda dapat melihat `version` bidang objek di DynamoDB diatur `3` ke, sehingga Anda bisa memperbarui `expectedVersion` argumen `3` ke dan permintaan akan berhasil lagi.

Untuk informasi selengkapnya tentang menangani kegagalan pemeriksaan kondisi, lihat dokumentasi referensi templat pemetaan [Ekspresi Kondisi](aws-appsync-resolver-mapping-template-reference-dynamodb-condition-expressions.md).

## Buat Mutasi UpVotePost dan DownVotePost (DynamoDB) UpdateItem
<a name="create-upvotepost-and-downvotepost-mutations-ddb-updateitem"></a>

`Post`Jenis memiliki `ups` dan `downs` bidang untuk mengaktifkan rekam suara positif dan suara turun, tetapi sejauh ini API tidak mengizinkan kami melakukan apa pun dengannya. Mari tambahkan beberapa mutasi untuk memungkinkan kita meningkatkan dan menurunkan suara posting.
+ Pilih tab **Skema**.
+ Di panel **Skema**, ubah `Mutation` tipe untuk menambahkan baru `upvotePost` dan `downvotePost` mutasi sebagai berikut:

  ```
  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!
  }
  ```
+ Pilih **Simpan**.
+ **Di panel **Jenis data** di sebelah kanan, temukan bidang **UpVotePost** yang baru dibuat pada tipe Mutasi, lalu pilih **Lampirkan**.**
+ Di **menu Action**, pilih **Update runtime**, lalu pilih **Unit Resolver (hanya VTL**).
+ Di **Nama sumber data**, pilih **PostDynamoDBTable**.
+ Di **Konfigurasikan templat pemetaan permintaan**, tempel yang berikut ini:

  ```
  {
      "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 }
          }
      }
  }
  ```
+ Di **Konfigurasikan template pemetaan respons**, tempel yang berikut ini:

  ```
  $utils.toJson($context.result)
  ```
+ Pilih **Simpan**.
+ **Di panel **Jenis data** di sebelah kanan, temukan `downvotePost` bidang yang baru dibuat pada tipe **Mutasi**, lalu pilih Lampirkan.**
+ Di **Nama sumber data**, pilih **PostDynamoDBTable**.
+ Di **Konfigurasikan templat pemetaan permintaan**, tempel yang berikut ini:

  ```
  {
      "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 }
          }
      }
  }
  ```
+ Di **Konfigurasikan template pemetaan respons**, tempel yang berikut ini:

  ```
  $utils.toJson($context.result)
  ```
+ Pilih **Simpan**.

### Panggil API untuk melakukan upvote dan downvote sebuah Post
<a name="call-the-api-to-upvote-and-downvote-a-post"></a>

Sekarang resolver baru telah diatur, AWS AppSync tahu bagaimana menerjemahkan masuk `upvotePost` atau `downvote` mutasi ke operasi DynamoDB. UpdateItem Anda sekarang dapat menjalankan mutasi untuk upvote atau downvote posting yang Anda buat sebelumnya.
+ Pilih tab **Kueri**.
+ Di panel **Kueri**, tempel mutasi berikut. Anda juga perlu memperbarui `id` argumen ke nilai yang Anda catat sebelumnya.

  ```
  mutation votePost {
    upvotePost(id:123) {
      id
      author
      title
      content
      url
      ups
      downs
      version
    }
  }
  ```
+ Pilih **Execute query** (tombol putar oranye).
+ Posting diperbarui di DynamoDB dan akan muncul di panel hasil di sebelah kanan panel kueri. Itu terlihat serupa dengan yang berikut ini:

  ```
  {
    "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
      }
    }
  }
  ```
+ Pilih **Jalankan kueri** beberapa kali lagi. Anda akan melihat `version` bidang `ups` dan bertambah 1 setiap kali Anda menjalankan kueri.
+ Ubah kueri untuk memanggil `downvotePost` mutasi sebagai berikut:

  ```
  mutation votePost {
    downvotePost(id:123) {
      id
      author
      title
      content
      url
      ups
      downs
      version
    }
  }
  ```
+ Pilih **Execute query** (tombol putar oranye). Kali ini, Anda akan melihat `version` bidang `downs` dan bertambah 1 setiap kali Anda menjalankan kueri.

  ```
  {
    "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
      }
    }
  }
  ```

## Menyiapkan DeletePost Resolver (DynamoDB) DeleteItem
<a name="setting-up-the-deletepost-resolver-ddb-deletepost"></a>

Mutasi berikutnya yang ingin Anda atur adalah menghapus posting. Anda akan melakukan ini menggunakan operasi `DeleteItem` DynamoDB.
+ Pilih tab **Skema**.
+ Di panel **Skema**, ubah `Mutation` tipe untuk menambahkan `deletePost` mutasi baru sebagai berikut:

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

  Kali ini Anda membuat `expectedVersion` bidang opsional, yang dijelaskan nanti ketika Anda menambahkan template pemetaan permintaan.
+ Pilih **Simpan**.
+ **Di panel **Jenis data** di sebelah kanan, temukan bidang **hapus** yang baru dibuat pada Jenis **mutasi**, lalu pilih Lampirkan.**
+ Di **menu Action**, pilih **Update runtime**, lalu pilih **Unit Resolver (hanya VTL**).
+ Di **Nama sumber data**, pilih **PostDynamoDBTable**.
+ Di **Konfigurasikan templat pemetaan permintaan**, tempel yang berikut ini:

  ```
  {
      "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
  }
  ```

   **Catatan:** `expectedVersion` Argumen adalah argumen opsional. Jika pemanggil menetapkan `expectedVersion` argumen dalam permintaan, template menambahkan kondisi yang hanya memungkinkan `DeleteItem` permintaan untuk berhasil jika item sudah dihapus atau jika `version` atribut posting di DynamoDB sama persis dengan. `expectedVersion` Jika ditinggalkan, tidak ada ekspresi kondisi yang ditentukan pada `DeleteItem` permintaan. Ini berhasil terlepas dari nilai`version`, atau apakah item ada atau tidak di DynamoDB.
+ Di **Konfigurasikan template pemetaan respons**, tempel yang berikut ini:

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

   **Catatan:** Meskipun Anda menghapus item, Anda dapat mengembalikan item yang telah dihapus, jika belum dihapus.
+ Pilih **Simpan**.

Untuk info selengkapnya tentang pemetaan `DeleteItem` permintaan, lihat dokumentasi [DeleteItem](aws-appsync-resolver-mapping-template-reference-dynamodb-deleteitem.md)referensi.

### Panggil API untuk Menghapus Posting
<a name="call-the-api-to-delete-a-post"></a>

Sekarang resolver telah diatur, AWS AppSync tahu bagaimana menerjemahkan `delete` mutasi yang masuk ke operasi DynamoDB. `DeleteItem` Anda sekarang dapat menjalankan mutasi untuk menghapus sesuatu di tabel.
+ Pilih tab **Kueri**.
+ Di panel **Kueri**, tempel mutasi berikut. Anda juga perlu memperbarui `id` argumen ke nilai yang Anda catat sebelumnya.

  ```
  mutation deletePost {
    deletePost(id:123) {
      id
      author
      title
      content
      url
      ups
      downs
      version
    }
  }
  ```
+ Pilih **Execute query** (tombol putar oranye).
+ Posting dihapus dari DynamoDB. Perhatikan bahwa AWS AppSync mengembalikan nilai item yang telah dihapus dari DynamoDB, yang akan muncul di panel hasil di sebelah kanan panel kueri. Itu terlihat serupa dengan yang berikut ini:

  ```
  {
    "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
      }
    }
  }
  ```

Nilai hanya dikembalikan jika panggilan ini adalah salah satu yang `deletePost` benar-benar menghapusnya dari DynamoDB.
+ Pilih **Jalankan kueri** lagi.
+ Panggilan masih berhasil, tetapi tidak ada nilai yang dikembalikan.

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

Sekarang mari kita coba menghapus posting, tapi kali ini menentukan. `expectedValue` Pertama-tama, Anda harus membuat posting baru karena Anda baru saja menghapus yang telah Anda kerjakan sejauh ini.
+ Di panel **Kueri**, tempel mutasi berikut:

  ```
  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
    }
  }
  ```
+ Pilih **Execute query** (tombol putar oranye).
+ Hasil posting yang baru dibuat akan muncul di panel hasil di sebelah kanan panel kueri. Catat objek `id` yang baru dibuat karena Anda membutuhkannya hanya dalam beberapa saat. Itu terlihat serupa dengan yang berikut ini:

  ```
  {
    "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
      }
    }
  }
  ```

Sekarang mari kita coba menghapus posting itu, tetapi masukkan nilai yang salah untuk`expectedVersion`:
+ Di panel **Kueri**, tempel mutasi berikut. Anda juga perlu memperbarui `id` argumen ke nilai yang Anda catat sebelumnya.

  ```
  mutation deletePost {
    deletePost(
      id:123
      expectedVersion: 9999
    ) {
      id
      author
      title
      content
      url
      ups
      downs
      version
    }
  }
  ```
+ Pilih **Execute query** (tombol putar oranye).

  ```
  {
    "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)"
      }
    ]
  }
  ```

  Permintaan gagal karena ekspresi kondisi dievaluasi menjadi false: nilai untuk `version` posting di DynamoDB tidak cocok dengan `expectedValue` yang ditentukan dalam argumen. Nilai objek saat ini dikembalikan di `data` bidang di `errors` bagian respons GraphQL.
+ Coba lagi permintaannya, tetapi `expectedVersion` perbaiki:

  ```
  mutation deletePost {
    deletePost(
      id:123
      expectedVersion: 1
    ) {
      id
      author
      title
      content
      url
      ups
      downs
      version
    }
  }
  ```
+ Pilih **Execute query** (tombol putar oranye).
+ Kali ini permintaan berhasil, dan nilai yang dihapus dari DynamoDB dikembalikan:

  ```
  {
    "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
      }
    }
  }
  ```
+ Pilih **Jalankan kueri** lagi.
+ Panggilan masih berhasil, tetapi kali ini tidak ada nilai yang dikembalikan karena posting sudah dihapus di DynamoDB.

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

## Menyiapkan AllPost Resolver (DynamoDB Scan)
<a name="setting-up-the-allpost-resolver-dynamodb-scan"></a>

Sejauh ini API hanya berguna jika Anda mengetahui setiap posting yang ingin Anda lihat. `id` Mari tambahkan resolver baru yang mengembalikan semua posting dalam tabel.
+ Pilih tab **Skema**.
+ Di panel **Skema**, ubah `Query` jenis untuk menambahkan `allPost` kueri baru sebagai berikut:

  ```
  type Query {
      allPost(count: Int, nextToken: String): PaginatedPosts!
      getPost(id: ID): Post
  }
  ```
+ Tambahkan `PaginationPosts` tipe baru:

  ```
  type PaginatedPosts {
      posts: [Post!]!
      nextToken: String
  }
  ```
+ Pilih **Simpan**.
+ ****Di panel **tipe Data** di sebelah kanan, temukan bidang **AllPost** yang baru dibuat pada tipe Query, lalu pilih Lampirkan.****
+ Di **menu Action**, pilih **Update runtime**, lalu pilih **Unit Resolver (hanya VTL**).
+ Di **Nama sumber data**, pilih **PostDynamoDBTable**.
+ Di **Konfigurasikan templat pemetaan permintaan**, tempel yang berikut ini:

  ```
  {
      "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
  }
  ```

  Penyelesai ini memiliki dua argumen opsional:`count`, yang menentukan jumlah maksimum item yang akan dikembalikan dalam satu panggilan, dan`nextToken`, yang dapat digunakan untuk mengambil set hasil berikutnya (Anda akan menunjukkan dari mana nilai untuk `nextToken` berasal nanti).
+ Di **Konfigurasikan template pemetaan respons**, tempel yang berikut ini:

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

   **Catatan:** Template pemetaan respons ini berbeda dari yang lainnya sejauh ini. Hasil `allPost` kueri adalah`PaginatedPosts`, yang berisi daftar posting dan token pagination. Bentuk objek ini berbeda dengan apa yang dikembalikan dari AWS AppSync DynamoDB Resolver: daftar posting dipanggil dalam hasil AWS AppSync DynamoDB Resolver, tetapi dipanggil `items` dalam. `posts` `PaginatedPosts`
+ Pilih **Simpan**.

Untuk informasi selengkapnya tentang pemetaan `Scan` permintaan, lihat dokumentasi referensi [Pindai](aws-appsync-resolver-mapping-template-reference-dynamodb-scan.md).

### Panggil API untuk Memindai Semua Posting
<a name="call-the-api-to-scan-all-posts"></a>

Sekarang resolver telah diatur, AWS AppSync tahu bagaimana menerjemahkan `allPost` query masuk ke operasi DynamoDB. `Scan` Anda sekarang dapat memindai tabel untuk mengambil semua posting.

Sebelum Anda dapat mencobanya, Anda perlu mengisi tabel dengan beberapa data karena Anda telah menghapus semua yang telah Anda kerjakan sejauh ini.
+ Pilih tab **Kueri**.
+ Di panel **Kueri**, tempel mutasi berikut:

  ```
  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 }
  }
  ```
+ Pilih **Execute query** (tombol putar oranye).

Sekarang, mari kita pindai tabel, mengembalikan lima hasil sekaligus.
+ Di panel **Kueri**, tempel kueri berikut:

  ```
  query allPost {
    allPost(count: 5) {
      posts {
        id
        title
      }
      nextToken
    }
  }
  ```
+ Pilih **Execute query** (tombol putar oranye).
+ Lima posting pertama akan muncul di panel hasil di sebelah kanan panel kueri. Itu terlihat serupa dengan yang berikut ini:

  ```
  {
    "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="
      }
    }
  }
  ```

Anda mendapat lima hasil dan `nextToken` yang dapat Anda gunakan untuk mendapatkan set hasil berikutnya.
+ Perbarui `allPost` kueri untuk menyertakan `nextToken` dari kumpulan hasil sebelumnya:

  ```
  query allPost {
    allPost(
      count: 5
      nextToken: "eyJ2ZXJzaW9uIjoxLCJ0b2tlbiI6IkFRSUNBSGo4eHR0RG0xWXhUa1F0cEhXMEp1R3B0M1B3eThOSmRvcG9ad2RHYjI3Z0lnRlluNktJRWl6V0ZlR3hJOVJkaStrZUFBQUI1akNDQWVJR0NTcUdTSWIzRFFFSEJxQ0NBZE13Z2dIUEFnRUFNSUlCeUFZSktvWklodmNOQVFjQk1CNEdDV0NHU0FGbEF3UUJMakFSQkF5cW8yUGFSZThnalFpemRCTUNBUkNBZ2dHWk1JODhUNzhIOFVUZGtpdFM2ZFluSWRyVDg4c2lkN1RjZzB2d1k3VGJTTWpSQ2U3WjY3TkUvU2I1dWNETUdDMmdmMHErSGJSL0pteGRzYzVEYnE1K3BmWEtBdU5jSENJdWNIUkJ0UHBPWVdWdCtsS2U5L1pNcWdocXhrem1RaXI1YnIvQkt6dU5hZmJCdE93NmtoM2Jna1BKM0RjWWhpMFBGbmhMVGg4TUVGSjBCcXg3RTlHR1V5N0tUS0JLZlV3RjFQZ0JRREdrNzFYQnFMK2R1S2IrVGtZZzVYMjFrc3NyQmFVTmNXZmhTeXE0ZUJHSWhqZWQ5c3VKWjBSSTc2ZnVQdlZkR3FLNENjQmxHYXhpekZnK2pKK1FneEU1SXduRTNYYU5TR0I4QUpmamR2bU1wbUk1SEdvWjlMUUswclczbG14RDRtMlBsaTNLaEVlcm9pem5zcmdINFpvcXIrN2ltRDN3QkJNd3BLbGQzNjV5Nnc4ZnMrK2FnbTFVOUlKOFFrOGd2bEgySHFROHZrZXBrMWlLdWRIQ25LaS9USnBlMk9JeEVPazVnRFlzRTRUU09HUlVJTkxYY2MvdW1WVEpBMUthV2hWTlAvdjNlSnlZQUszbWV6N2h5WHVXZ1BkTVBNWERQdTdjVnVRa3EwK3NhbGZOd2wvSUx4bHNyNDVwTEhuVFpyRWZvVlV1bXZ5S2VKY1RUU1lET05hM1NwWEd2UT09In0="
    ) {
      posts {
        id
        author
      }
      nextToken
    }
  }
  ```
+ Pilih **Execute query** (tombol putar oranye).
+ Empat posting yang tersisa akan muncul di panel hasil di sebelah kanan panel kueri. Tidak ada `nextToken` dalam rangkaian hasil ini karena Anda telah membaca semua sembilan posting, dengan tidak ada yang tersisa. Itu terlihat serupa dengan yang berikut ini:

  ```
  {
    "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
      }
    }
  }
  ```

## Menyiapkan Resolver allPostsBy Penulis (Query DynamoDB)
<a name="setting-up-the-allpostsbyauthor-resolver-ddb-query"></a>

Selain memindai DynamoDB untuk semua posting, Anda juga dapat meminta DynamoDB untuk mengambil posting yang dibuat oleh penulis tertentu. Tabel DynamoDB yang Anda buat sebelumnya sudah memiliki panggilan `GlobalSecondaryIndex` yang dapat Anda `author-index` gunakan dengan operasi DynamoDB untuk mengambil `Query` semua posting yang dibuat oleh penulis tertentu.
+ Pilih tab **Skema**.
+ Di panel **Skema**, ubah `Query` jenis untuk menambahkan `allPostsByAuthor` kueri baru sebagai berikut:

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

   **Catatan:** Ini menggunakan `PaginatedPosts` jenis yang sama yang Anda gunakan dengan `allPost` kueri.
+ Pilih **Simpan**.
+ Di panel **Jenis data** di sebelah kanan, temukan bidang **allPostsByPenulis** yang baru dibuat pada jenis **kueri**, lalu pilih **Lampirkan**.
+ Di **menu Action**, pilih **Update runtime**, lalu pilih **Unit Resolver (hanya VTL**).
+ Di **Nama sumber data**, pilih **PostDynamoDBTable**.
+ Di **Konfigurasikan templat pemetaan permintaan**, tempel yang berikut ini:

  ```
  {
      "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
  }
  ```

  Seperti `allPost` resolver, resolver ini memiliki dua argumen opsional:`count`, yang menentukan jumlah maksimum item yang akan dikembalikan dalam satu panggilan, dan`nextToken`, yang dapat digunakan untuk mengambil set hasil berikutnya (nilai untuk `nextToken` dapat diperoleh dari panggilan sebelumnya).
+ Di **Konfigurasikan template pemetaan respons**, tempel yang berikut ini:

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

   **Catatan:** Ini adalah template pemetaan respons yang sama yang Anda gunakan dalam `allPost` resolver.
+ Pilih **Simpan**.

Untuk informasi selengkapnya tentang pemetaan `Query` permintaan, lihat dokumentasi referensi [kueri](aws-appsync-resolver-mapping-template-reference-dynamodb-query.md).

### Panggil API untuk Menanyakan Semua Postingan oleh Penulis
<a name="call-the-api-to-query-all-posts-by-an-author"></a>

Sekarang resolver telah diatur, AWS AppSync tahu bagaimana menerjemahkan `allPostsByAuthor` mutasi yang masuk ke operasi DynamoDB terhadap indeks. `Query` `author-index` Anda sekarang dapat meminta tabel untuk mengambil semua posting oleh penulis tertentu.

Sebelum Anda melakukan itu, bagaimanapun, mari kita mengisi tabel dengan beberapa posting lagi, karena setiap posting sejauh ini memiliki penulis yang sama.
+ Pilih tab **Kueri**.
+ Di panel **Kueri**, tempel mutasi berikut:

  ```
  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 }
  }
  ```
+ Pilih **Execute query** (tombol putar oranye).

Sekarang, mari kita menanyakan tabel, mengembalikan semua posting yang ditulis oleh. `Nadia`
+ Di panel **Kueri**, tempel kueri berikut:

  ```
  query allPostsByAuthor {
    allPostsByAuthor(author: "Nadia") {
      posts {
        id
        title
      }
      nextToken
    }
  }
  ```
+ Pilih **Execute query** (tombol putar oranye).
+ Semua posting yang ditulis oleh akan `Nadia` muncul di panel hasil di sebelah kanan panel query. Itu terlihat serupa dengan yang berikut ini:

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

Pagination bekerja untuk hal yang `Query` sama seperti yang dilakukannya. `Scan` Sebagai contoh, mari kita cari semua posting dengan`AUTHORNAME`, mendapatkan lima sekaligus.
+ Di panel **Kueri**, tempel kueri berikut:

  ```
  query allPostsByAuthor {
    allPostsByAuthor(
      author: "AUTHORNAME"
      count: 5
    ) {
      posts {
        id
        title
      }
      nextToken
    }
  }
  ```
+ Pilih **Execute query** (tombol putar oranye).
+ Semua posting yang ditulis oleh akan `AUTHORNAME` muncul di panel hasil di sebelah kanan panel query. Itu terlihat serupa dengan yang berikut ini:

  ```
  {
    "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=="
      }
    }
  }
  ```
+ Perbarui `nextToken` argumen dengan nilai yang dikembalikan dari kueri sebelumnya sebagai berikut:

  ```
  query allPostsByAuthor {
    allPostsByAuthor(
      author: "AUTHORNAME"
      count: 5
      nextToken: "eyJ2ZXJzaW9uIjoxLCJ0b2tlbiI6IkFRSUNBSGo4eHR0RG0xWXhUa1F0cEhXMEp1R3B0M1B3eThOSmRvcG9ad2RHYjI3Z0lnSExqRnVhVUR3ZUhEZ2QzNGJ2QlFuY0FBQUNqekNDQW9zR0NTcUdTSWIzRFFFSEJxQ0NBbnd3Z2dKNEFnRUFNSUlDY1FZSktvWklodmNOQVFjQk1CNEdDV0NHU0FGbEF3UUJMakFSQkF5Qkg4Yk1obW9LVEFTZHM3SUNBUkNBZ2dKQ3dISzZKNlJuN3pyYUVKY1pWNWxhSkNtZW1KZ0F5N1dhZkc2UEdTNHpNQzJycTkwZHFJTFV6Z25wck9Gd3pMS3VOQ2JvUXc3VDI5eCtnVExIbGg4S3BqbzB1YjZHQ3FwcDhvNDVmMG9JbDlmdS9JdjNXcFNNSXFKTXZ1MEVGVWs1VzJQaW5jZGlUaVRtZFdYWlU1bkV2NkgyRFBRQWZYYlNnSmlHSHFLbmJZTUZZM0FTdmRIL0hQaVZBb1RCMk1YZkg0eGJOVTdEbjZtRFNhb2QwbzdHZHJEWDNtODQ1UXBQUVNyUFhHemY0WDkyajhIdlBCSWE4Smcrb0RxbHozUVQ5N2FXUXdYWWU2S0h4emI1ejRITXdEdXEyRDRkYzhoMi9CbW10MzRMelVGUVIyaExSZGRaZ0xkdzF5cHJZdFZwY3dEc1d4UURBTzdOcjV2ZEp4VVR2TVhmODBRSnp1REhXREpTVlJLdDJwWmlpaXhXeGRwRmNod1BzQ3d2aVBqMGwrcWFFWU1jMXNQbENkVkFGem43VXJrSThWbS8wWHlwR2xZb3BSL2FkV0xVekgrbGMrYno1ZEM2SnVLVXdtY1EyRXlZeDZiS0Izbi9YdUViWGdFeU5PMWZTdE1rRlhyWmpvMVpzdlYyUFRjMzMrdEs0ZDhkNkZrdjh5VVR6WHhJRkxIaVNsOUx6VVdtT3BCaWhrTFBCT09jcXkyOHh1UmkzOEM3UFRqMmN6c3RkOUo1VUY0azBJdUdEbVZzM2xjdWg1SEJjYThIeXM2aEpvOG1HbFpMNWN6R2s5bi8vRE1EbDY3RlJraG5QNFNhSDBpZGI5VFEvMERLeFRBTUdhcWpPaEl5ekVqd2ZDQVJleFdlbldyOGlPVkhScDhGM25WZVdvbFRGK002N0xpdi9XNGJXdDk0VEg3b0laUU5lYmZYKzVOKy9Td25Hb1dyMTlWK0pEb2lIRVFLZ1cwMWVuYjZKUXo5Slh2Tm95ZzF3RnJPVmxGc2xwNlRHa1BlN2Rnd2IrWT0ifQ=="
    ) {
      posts {
        id
        title
      }
      nextToken
    }
  }
  ```
+ Pilih **Execute query** (tombol putar oranye).
+ Posting yang tersisa yang ditulis oleh `AUTHORNAME` akan muncul di panel hasil di sebelah kanan panel kueri. Itu terlihat serupa dengan yang berikut ini:

  ```
  {
    "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
      }
    }
  }
  ```

## Menggunakan Set
<a name="using-sets"></a>

Sampai saat ini `Post` tipe telah menjadi key/value objek datar. Anda juga dapat memodelkan objek kompleks dengan resolver AWS AppSyncDynamo DB, seperti set, daftar, dan peta.

Mari kita perbarui `Post` jenis untuk menyertakan tag. Sebuah posting dapat memiliki 0 atau lebih tag, yang disimpan di DynamoDB sebagai String Set. Anda juga akan menyiapkan beberapa mutasi untuk menambah dan menghapus tag, dan kueri baru untuk memindai posting dengan tag tertentu.
+ Pilih tab **Skema**.
+ Di panel **Skema**, ubah `Post` jenis untuk menambahkan `tags` bidang baru sebagai berikut:

  ```
  type Post {
    id: ID!
    author: String
    title: String
    content: String
    url: String
    ups: Int!
    downs: Int!
    version: Int!
    tags: [String!]
  }
  ```
+ Di panel **Skema**, ubah `Query` jenis untuk menambahkan `allPostsByTag` kueri baru sebagai berikut:

  ```
  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
  }
  ```
+ Di panel **Skema**, ubah `Mutation` tipe untuk menambahkan baru `addTag` dan `removeTag` mutasi sebagai berikut:

  ```
  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!
  }
  ```
+ Pilih **Simpan**.
+ Di panel **Tipe data** di sebelah kanan, temukan bidang **allPostsByTag** yang baru dibuat pada Jenis **kueri**, lalu pilih **Lampirkan**.
+ Di **Nama sumber data**, pilih **PostDynamoDBTable**.
+ Di **Konfigurasikan templat pemetaan permintaan**, tempel yang berikut ini:

  ```
  {
      "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
  }
  ```
+ Di **Konfigurasikan template pemetaan respons**, tempel yang berikut ini:

  ```
  {
      "posts": $utils.toJson($context.result.items)
      #if( ${context.result.nextToken} )
          ,"nextToken": $util.toJson($context.result.nextToken)
      #end
  }
  ```
+ Pilih **Simpan**.
+ ****Di panel **Jenis data** di sebelah kanan, temukan bidang **AddTag** yang baru dibuat pada tipe Mutasi, lalu pilih Lampirkan.****
+ Di **Nama sumber data**, pilih **PostDynamoDBTable**.
+ Di **Konfigurasikan templat pemetaan permintaan**, tempel yang berikut ini:

  ```
  {
      "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 }
          }
      }
  }
  ```
+ Di **Konfigurasikan template pemetaan respons**, tempel yang berikut ini:

  ```
  $utils.toJson($context.result)
  ```
+ Pilih **Simpan**.
+ ****Di panel **tipe Data** di sebelah kanan, temukan bidang **RemoveTag yang baru** dibuat pada tipe Mutasi, lalu pilih Lampirkan.****
+ Di **Nama sumber data**, pilih **PostDynamoDBTable**.
+ Di **Konfigurasikan templat pemetaan permintaan**, tempel yang berikut ini:

  ```
  {
      "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 }
          }
      }
  }
  ```
+ Di **Konfigurasikan template pemetaan respons**, tempel yang berikut ini:

  ```
  $utils.toJson($context.result)
  ```
+ Pilih **Simpan**.

### Panggil API untuk Bekerja dengan Tag
<a name="call-the-api-to-work-with-tags"></a>

Sekarang setelah Anda menyiapkan resolver, AWS AppSync tahu cara menerjemahkan masuk `addTag``removeTag`, dan permintaan `allPostsByTag` ke DynamoDB dan operasi. `UpdateItem` `Scan`

Untuk mencobanya, mari pilih salah satu posting yang Anda buat sebelumnya. Misalnya, mari kita gunakan posting yang ditulis oleh. `Nadia`
+ Pilih tab **Kueri**.
+ Di panel **Kueri**, tempel kueri berikut:

  ```
  query allPostsByAuthor {
    allPostsByAuthor(
      author: "Nadia"
    ) {
      posts {
        id
        title
      }
      nextToken
    }
  }
  ```
+ Pilih **Execute query** (tombol putar oranye).
+ Semua posting Nadia akan muncul di panel hasil di sebelah kanan panel kueri. Itu terlihat serupa dengan yang berikut ini:

  ```
  {
    "data": {
      "allPostsByAuthor": {
        "posts": [
          {
            "id": "10",
            "title": "The cutest dog in the world"
          },
          {
            "id": "11",
            "title": "Did you known...?"
          }
        ],
        "nextToken": null
      }
    }
  }
  ```
+ Mari kita gunakan yang dengan judul`"The cutest dog in the world"`. Catat `id` karena Anda akan menggunakannya nanti.

Sekarang mari kita coba menambahkan `dog` tag.
+ Di panel **Kueri**, tempel mutasi berikut. Anda juga perlu memperbarui `id` argumen ke nilai yang Anda catat sebelumnya.

  ```
  mutation addTag {
    addTag(id:10 tag: "dog") {
      id
      title
      tags
    }
  }
  ```
+ Pilih **Execute query** (tombol putar oranye).
+ Posting diperbarui dengan tag baru.

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

Anda dapat menambahkan lebih banyak tag sebagai berikut:
+ Perbarui mutasi untuk mengubah `tag` argumen menjadi`puppy`.

  ```
  mutation addTag {
    addTag(id:10 tag: "puppy") {
      id
      title
      tags
    }
  }
  ```
+ Pilih **Execute query** (tombol putar oranye).
+ Posting diperbarui dengan tag baru.

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

Anda juga dapat menghapus tag:
+ Di panel **Kueri**, tempel mutasi berikut. Anda juga perlu memperbarui `id` argumen ke nilai yang Anda catat sebelumnya.

  ```
  mutation removeTag {
    removeTag(id:10 tag: "puppy") {
      id
      title
      tags
    }
  }
  ```
+ Pilih **Execute query** (tombol putar oranye).
+ Posting diperbarui dan `puppy` tag dihapus.

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

Anda juga dapat mencari semua posting yang memiliki tag:
+ Di panel **Kueri**, tempel kueri berikut:

  ```
  query allPostsByTag {
    allPostsByTag(tag: "dog") {
      posts {
        id
        title
        tags
      }
      nextToken
    }
  }
  ```
+ Pilih **Execute query** (tombol putar oranye).
+ Semua posting yang memiliki `dog` tag dikembalikan sebagai berikut:

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

## Menggunakan Daftar dan Peta
<a name="using-lists-and-maps"></a>

Selain menggunakan set DynamoDB, Anda juga dapat menggunakan daftar dan peta DynamoDB untuk memodelkan data kompleks dalam satu objek.

Mari tambahkan kemampuan untuk menambahkan komentar ke posting. Ini akan dimodelkan sebagai daftar objek peta pada objek di DynamoDB. `Post`

 **Catatan:** dalam aplikasi nyata, Anda akan memodelkan komentar di tabel mereka sendiri. Untuk tutorial ini, Anda hanya akan menambahkannya di `Post` tabel.
+ Pilih tab **Skema**.
+ Di panel **Skema**, tambahkan `Comment` tipe baru sebagai berikut:

  ```
  type Comment {
      author: String!
      comment: String!
  }
  ```
+ Di panel **Skema**, ubah `Post` jenis untuk menambahkan `comments` bidang baru sebagai berikut:

  ```
  type Post {
    id: ID!
    author: String
    title: String
    content: String
    url: String
    ups: Int!
    downs: Int!
    version: Int!
    tags: [String!]
    comments: [Comment!]
  }
  ```
+ Di panel **Skema**, ubah `Mutation` tipe untuk menambahkan `addComment` mutasi baru sebagai berikut:

  ```
  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!
  }
  ```
+ Pilih **Simpan**.
+ ****Di panel **tipe Data** di sebelah kanan, temukan bidang **AddComment** yang baru dibuat pada tipe Mutasi, lalu pilih Lampirkan.****
+ Di **Nama sumber data**, pilih **PostDynamoDBTable**.
+ Di **Konfigurasikan templat pemetaan permintaan**, tempel yang berikut ini:

  ```
  {
    "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)
      }
    }
  }
  ```

  Ekspresi pembaruan ini akan menambahkan daftar yang berisi komentar baru kami ke `comments` daftar yang ada. Jika daftar belum ada, itu akan dibuat.
+ Di **Konfigurasikan template pemetaan respons**, tempel yang berikut ini:

  ```
  $utils.toJson($context.result)
  ```
+ Pilih **Simpan**.

### Panggil API untuk Menambahkan Komentar
<a name="call-the-api-to-add-a-comment"></a>

Sekarang setelah Anda menyiapkan resolver, AWS AppSync tahu cara menerjemahkan permintaan masuk `addComment` ke dalam operasi DynamoDB. `UpdateItem`

Mari kita coba dengan menambahkan komentar ke posting yang sama dengan yang Anda tambahkan tag.
+ Pilih tab **Kueri**.
+ Di panel **Kueri**, tempel kueri berikut:

  ```
  mutation addComment {
    addComment(
      id:10
      author: "Steve"
      comment: "Such a cute dog."
    ) {
      id
      comments {
        author
        comment
      }
    }
  }
  ```
+ Pilih **Execute query** (tombol putar oranye).
+ Semua posting Nadia akan muncul di panel hasil di sebelah kanan panel kueri. Itu terlihat serupa dengan yang berikut ini:

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

Jika Anda menjalankan permintaan beberapa kali, beberapa komentar akan ditambahkan ke daftar.

## Kesimpulan
<a name="conclusion"></a>

Dalam tutorial ini, Anda telah membangun sebuah API yang memungkinkan kita memanipulasi objek Post di AWS AppSync DynamoDB menggunakan dan GraphQL. Untuk informasi selengkapnya, lihat Referensi [Template Pemetaan Resolver](resolver-mapping-template-reference.md#aws-appsync-resolver-mapping-template-reference).

Untuk membersihkan, Anda dapat menghapus AppSync GraphQL API dari konsol.

Untuk menghapus tabel DynamoDB dan peran IAM yang Anda buat untuk tutorial ini, Anda dapat menjalankan yang berikut ini untuk menghapus `AWSAppSyncTutorialForAmazonDynamoDB` tumpukan, atau mengunjungi CloudFormation konsol dan menghapus tumpukan:

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