

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

# Menggunakan Aurora Serverless v2 dengan AWS AppSync
<a name="tutorial-rds-resolvers"></a>

Hubungkan GraphQL API Anda ke database Aurora Serverless menggunakan. AWS AppSync Integrasi ini memungkinkan Anda mengeksekusi pernyataan SQL melalui kueri, mutasi, dan langganan GraphQL - memberi Anda cara yang fleksibel untuk berinteraksi dengan data relasional Anda.

**catatan**  
Tutorial ini menggunakan Wilayah `US-EAST-1`.

**Manfaat**
+ Integrasi mulus antara GraphQL dan database relasional
+ Kemampuan untuk melakukan operasi SQL melalui antarmuka GraphQL
+ Skalabilitas tanpa server dengan Aurora Serverless v2
+ Akses data aman melalui AWS Secrets Manager
+ Perlindungan terhadap injeksi SQL melalui sanitasi input
+ Kemampuan kueri yang fleksibel termasuk operasi penyaringan dan jangkauan

**Kasus Penggunaan Umum**
+ Membangun aplikasi yang dapat diskalakan dengan persyaratan data relasional
+ Membuat APIs yang membutuhkan fleksibilitas GraphQL dan kemampuan database SQL
+ Mengelola operasi data melalui mutasi dan kueri GraphQL
+ Menerapkan pola akses database yang aman

Dalam tutorial ini, Anda akan mempelajari yang berikut ini.
+ Siapkan cluster v2 Aurora Tanpa Server
+ Aktifkan fungsionalitas API Data
+ Membuat dan mengkonfigurasi struktur database
+ Tentukan skema GraphQL untuk operasi database
+ Menerapkan resolver untuk kueri dan mutasi
+ Amankan akses data Anda melalui sanitasi input yang tepat
+ Jalankan berbagai operasi database melalui antarmuka GraphQL

**Topics**
+ [Menyiapkan kluster database Anda](#create-cluster)
+ [Aktifkan API Data](#enable-data-api)
+ [Buat database dan tabel](#create-database-and-table)
+ [GraphQL skema](#graphql-schema)
+ [Hubungkan API Anda ke Operasi Database](#configuring-resolvers)
+ [Ubah Data Anda Melalui API](#run-mutations)
+ [Ambil Data Anda](#run-queries)
+ [Amankan Akses Data Anda](#input-sanitization)

## Menyiapkan kluster database Anda
<a name="create-cluster"></a>

Sebelum menambahkan sumber data Amazon RDS AWS AppSync, Anda harus terlebih dahulu mengaktifkan API Data pada klaster v2 Aurora Tanpa Server **dan** mengonfigurasi rahasia menggunakan. *AWS Secrets Manager* Anda dapat membuat cluster Aurora Serverless v2 menggunakan: AWS CLI

```
aws rds create-db-cluster \
    --db-cluster-identifier appsync-tutorial \
    --engine aurora-mysql \
    --engine-version 8.0 \
    --serverless-v2-scaling-configuration MinCapacity=0,MaxCapacity=1 \
    --master-username USERNAME \
    --master-user-password COMPLEX_PASSWORD \
    --enable-http-endpoint
```

Ini akan mengembalikan ARN untuk cluster.

Setelah membuat cluster, Anda harus menambahkan instance Aurora Serverless v2 menggunakan perintah berikut.

```
aws rds create-db-instance \
    --db-cluster-identifier appsync-tutorial \
    --db-instance-identifier appsync-tutorial-instance-1 \
    --db-instance-class db.serverless \
    --engine aurora-mysql
```

**catatan**  
Titik akhir ini membutuhkan waktu untuk diaktifkan. Anda dapat memeriksa statusnya di konsol Amazon RDS di tab **Konektivitas & keamanan** untuk cluster. Anda juga dapat memeriksa status cluster Anda dengan AWS CLI perintah berikut.   

```
aws rds describe-db-clusters \
    --db-cluster-identifier appsync-tutorial \
    --query "DBClusters[0].Status"
```

Anda dapat membuat *Rahasia* menggunakan AWS Secrets Manager Konsol atau AWS CLI dengan file input seperti berikut menggunakan `USERNAME` dan `COMPLEX_PASSWORD` dari langkah sebelumnya.

```
{
    "username": "USERNAME",
    "password": "COMPLEX_PASSWORD"
}
```

Berikan ini sebagai parameter ke AWS CLI:

```
aws secretsmanager create-secret --name HttpRDSSecret --secret-string file://creds.json --region us-east-1
```

Ini akan mengembalikan ARN untuk rahasianya.

 **Perhatikan ARN** cluster Aurora Tanpa Server Anda dan Rahasia untuk digunakan nanti di AppSync konsol saat membuat sumber data.

## Aktifkan API Data
<a name="enable-data-api"></a>

Anda dapat mengaktifkan Data API pada klaster Anda dengan [mengikuti petunjuk dalam dokumentasi RDS](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/data-api.html). Data API harus diaktifkan sebelum menambahkan sebagai sumber AppSync data.

## Buat database dan tabel
<a name="create-database-and-table"></a>

Setelah Anda mengaktifkan API Data Anda, Anda dapat memastikannya berfungsi dengan `aws rds-data execute-statement` perintah di AWS CLI. Ini akan memastikan bahwa cluster Aurora Serverless Anda dikonfigurasi dengan benar sebelum menambahkannya ke API Anda. AppSync Pertama membuat database yang disebut *TESTDB* dengan `--sql` parameter seperti:

```
aws rds-data execute-statement --resource-arn "arn:aws:rds:us-east-1:123456789000:cluster:http-endpoint-test" \
--schema "mysql"  --secret-arn "arn:aws:secretsmanager:us-east-1:123456789000:secret:testHttp2-AmNvc1"  \
--region us-east-1 --sql "create DATABASE TESTDB"
```

Jika ini berjalan tanpa kesalahan, tambahkan tabel dengan perintah *create table*:

```
aws rds-data execute-statement --resource-arn "arn:aws:rds:us-east-1:123456789000:cluster:http-endpoint-test" \
 --schema "mysql"  --secret-arn "arn:aws:secretsmanager:us-east-1:123456789000:secret:testHttp2-AmNvc1" \
 --region us-east-1 \
 --sql "create table Pets(id varchar(200), type varchar(200), price float)" --database "TESTDB"
```

Jika semuanya berjalan tanpa masalah, Anda dapat melanjutkan untuk menambahkan cluster sebagai sumber data di AppSync API Anda.

## GraphQL skema
<a name="graphql-schema"></a>

Sekarang setelah Aurora Serverless Data API Anda aktif dan berjalan dengan tabel, kami akan membuat skema GraphQL dan melampirkan resolver untuk melakukan mutasi dan langganan. Buat API baru di AWS AppSync konsol dan arahkan ke halaman **Skema**, lalu masukkan yang berikut ini:

```
type Mutation {
    createPet(input: CreatePetInput!): Pet
    updatePet(input: UpdatePetInput!): Pet
    deletePet(input: DeletePetInput!): Pet
}

input CreatePetInput {
    type: PetType
    price: Float!
}

input UpdatePetInput {
id: ID!
    type: PetType
    price: Float!
}

input DeletePetInput {
    id: ID!
}

type Pet {
    id: ID!
    type: PetType
    price: Float
}

enum PetType {
    dog
    cat
    fish
    bird
    gecko
}

type Query {
    getPet(id: ID!): Pet
    listPets: [Pet]
    listPetsByPriceRange(min: Float, max: Float): [Pet]
}

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

 **Simpan** skema Anda dan arahkan ke halaman **Sumber Data** dan buat sumber data baru. Pilih **Database relasional** untuk tipe sumber data, dan berikan nama yang ramah. Gunakan nama database yang Anda buat pada langkah terakhir, serta **ARN Cluster** tempat Anda membuatnya. Untuk **Peran**, Anda dapat AppSync membuat peran baru atau membuat peran dengan kebijakan yang mirip dengan di bawah ini:

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "rds-data:BatchExecuteStatement",
                "rds-data:BeginTransaction",
                "rds-data:CommitTransaction",
                "rds-data:ExecuteStatement",
                "rds-data:RollbackTransaction"
            ],
            "Resource": [
                "arn:aws:rds:us-east-1:111122223333:cluster:mydbcluster",
                "arn:aws:rds:us-east-1:111122223333:cluster:mydbcluster:*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "secretsmanager:GetSecretValue"
            ],
            "Resource": [
            "arn:aws:secretsmanager:us-east-1:111122223333:secret:mysecret",
            "arn:aws:secretsmanager:us-east-1:111122223333:secret:mysecret:*"
            ]
        }
    ]
}
```

------

Perhatikan ada dua **Pernyataan** dalam kebijakan ini yang Anda berikan akses peran. **Sumber daya** pertama adalah cluster Aurora Tanpa Server Anda dan yang kedua adalah ARN Anda. AWS Secrets Manager Anda harus memberikan **KEDUANYA** ARNs dalam konfigurasi sumber AppSync data sebelum mengklik **Buat**.

Lewati ini sebagai parameter ke file AWS CLI.

```
aws secretsmanager create-secret \
  --name HttpRDSSecret \
  --secret-string file://creds.json \
  --region us-east-1
```

Ini akan mengembalikan ARN untuk rahasianya. Catat ARN cluster Aurora Serverless Anda dan Rahasia untuk nanti saat membuat sumber data di konsol. AWS AppSync 

### Bangun Struktur Database Anda
<a name="create-database-and-table"></a>

Setelah Anda mengaktifkan API Data Anda, Anda dapat memastikannya berfungsi dengan `aws rds-data execute-statement` perintah di AWS CLI. Ini akan memastikan bahwa cluster Aurora Serverless v2 Anda dikonfigurasi dengan benar sebelum menambahkannya ke API Anda. AWS AppSync Pertama, buat database yang disebut *TESTDB* dengan `--sql` parameter sebagai berikut.

```
aws rds-data execute-statement \
                --resource-arn "arn:aws:rds:us-east-1:111122223333:cluster:appsync-tutorial" \
                --secret-arn "arn:aws:secretsmanager:us-east-1:111122223333:secret:appsync-tutorial-rds-secret"  \
                --region us-east-1 \
                --sql "create DATABASE TESTDB"
```

Jika ini berjalan tanpa kesalahan, tambahkan tabel dengan perintah *create table* berikut.

```
aws rds-data execute-statement \
      --resource-arn "arn:aws:rds:us-east-1:111122223333:cluster:http-endpoint-test" \
      --secret-arn "arn:aws:secretsmanager:us-east-1:111122223333:secret:testHttp2-AmNvc1" \
      --region us-east-1 \
      --sql "create table Pets(id varchar(200), type varchar(200), price float)" \
      --database "TESTDB"
```

### Rancang Antarmuka API Anda
<a name="graphql-schema"></a>

Setelah Aurora Serverless v2 Data API aktif dan berjalan dengan tabel, buat skema GraphQL dan lampirkan resolver untuk melakukan mutasi dan langganan. Buat API baru di AWS AppSync konsol dan arahkan ke halaman **Skema** di konsol, lalu masukkan yang berikut ini.

```
type Mutation {
        createPet(input: CreatePetInput!): Pet
        updatePet(input: UpdatePetInput!): Pet
        deletePet(input: DeletePetInput!): Pet
    }
    
    input CreatePetInput {
        type: PetType
        price: Float!
    }
    
    input UpdatePetInput {
        id: ID!
        type: PetType
        price: Float!
    }
    
    input DeletePetInput {
        id: ID!
    }
    
    type Pet {
        id: ID!
        type: PetType
        price: Float
    }
    
    enum PetType {
        dog
        cat
        fish
        bird
        gecko
    }
    
    type Query {
        getPet(id: ID!): Pet
        listPets: [Pet]
        listPetsByPriceRange(min: Float, max: Float): [Pet]
    }
    
    schema {
        query: Query
        mutation: Mutation
    }
```

 **Simpan** skema Anda dan arahkan ke halaman **Sumber Data** dan buat sumber data baru. Pilih **database Relasional** untuk tipe **sumber data**, dan berikan nama yang ramah. Gunakan nama database yang Anda buat pada langkah terakhir, serta **ARN Cluster** tempat Anda membuatnya. Untuk **Peran**, Anda dapat AWS AppSync membuat peran baru atau membuat peran dengan kebijakan yang mirip dengan berikut ini.

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

****  

```
{
        "Version":"2012-10-17",		 	 	 
        "Statement": [
            {
                "Effect": "Allow",
                "Action": [
                    "rds-data:BatchExecuteStatement",
                    "rds-data:BeginTransaction",
                    "rds-data:CommitTransaction",
                    "rds-data:ExecuteStatement",
                    "rds-data:RollbackTransaction"
                ],
                "Resource": [
                    "arn:aws:rds:us-east-1:111122223333:cluster:mydbcluster",
                    "arn:aws:rds:us-east-1:111122223333:cluster:mydbcluster:*"
                ]
            },
            {
                "Effect": "Allow",
                "Action": [
                    "secretsmanager:GetSecretValue"
                ],
                "Resource": [
                "arn:aws:secretsmanager:us-east-1:111122223333:secret:mysecret",
                "arn:aws:secretsmanager:us-east-1:111122223333:secret:mysecret:*"
                ]
            }
        ]
    }
```

------

Perhatikan ada dua **Pernyataan** dalam kebijakan ini yang Anda berikan akses peran. **Sumber daya** pertama adalah cluster Aurora Serverless v2 Anda dan yang kedua adalah ARN Anda. AWS Secrets Manager Anda harus memberikan **KEDUANYA** ARNs dalam konfigurasi sumber AWS AppSync data sebelum mengklik **Buat**.

## Hubungkan API Anda ke Operasi Database
<a name="configuring-resolvers"></a>

Sekarang kita memiliki skema GraphQL yang valid dan sumber data RDS, Anda dapat melampirkan resolver ke bidang GraphQL ke skema Anda. API kami akan menawarkan kemampuan berikut:

1. buat hewan peliharaan menggunakan bidang *mutation.createPet*

1. perbarui hewan peliharaan menggunakan bidang *mutation.updatePet*

1. hapus hewan peliharaan menggunakan bidang *mutation.deletePet*

1. dapatkan satu menggunakan melalui bidang *Query.getPet*

1. daftar semua menggunakan bidang *Query.listPets*

1. daftar hewan peliharaan dalam kisaran harga menggunakan *Query. listPetsByPriceRange*lapangan

### Mutasi.createPet
<a name="mutation-createpet"></a>

Dari editor skema di AWS AppSync konsol, di sisi kanan pilih **Lampirkan Resolver** untuk. `createPet(input: CreatePetInput!): Pet` Pilih sumber data RDS Anda. Di bagian **template pemetaan permintaan**, tambahkan template berikut:

```
#set($id=$utils.autoId())
{
"version": "2018-05-29",
    "statements": [
        "insert into Pets VALUES (:ID, :TYPE, :PRICE)",
        "select * from Pets WHERE id = :ID"
    ],
    "variableMap": {
        ":ID": "$ctx.args.input.id",
        ":TYPE": $util.toJson($ctx.args.input.type),
        ":PRICE": $util.toJson($ctx.args.input.price)
    }
}
```

**Sistem mengeksekusi pernyataan SQL secara berurutan, berdasarkan urutan dalam array pernyataan.** Hasilnya akan kembali dalam urutan yang sama. Karena ini adalah mutasi, Anda akan menjalankan pernyataan *pilih* setelah *sisipan untuk mengambil nilai yang dikomit* untuk mengisi template pemetaan respons GraphQL.

Di bagian **template pemetaan respons**, tambahkan templat berikut:

```
$utils.toJson($utils.rds.toJsonObject($ctx.result)[1][0])
```

Karena *pernyataan* memiliki dua query SQL, kita perlu menentukan hasil kedua dalam matriks yang kembali dari database dengan:. `$utils.rds.toJsonString($ctx.result))[1][0])`

### mutasi.updatePET
<a name="mutation-updatepet"></a>

Dari editor skema di AWS AppSync konsol, pilih **Lampirkan Resolver** untuk. `updatePet(input: UpdatePetInput!): Pet` Pilih **sumber data RDS** Anda. Di bagian **template pemetaan permintaan**, tambahkan template berikut.

```
{
"version": "2018-05-29",
    "statements": [
        $util.toJson("update Pets set type=:TYPE, price=:PRICE WHERE id=:ID"),
        $util.toJson("select * from Pets WHERE id = :ID")
    ],
    "variableMap": {
        ":ID": "$ctx.args.input.id",
        ":TYPE": $util.toJson($ctx.args.input.type),
        ":PRICE": $util.toJson($ctx.args.input.price)
    }
}
```

Di bagian **template pemetaan respons**, tambahkan template berikut.

```
$utils.toJson($utils.rds.toJsonObject($ctx.result)[1][0])
```

### mutasi.deletePet
<a name="mutation-deletepet"></a>

Dari editor skema di AWS AppSync konsol, pilih **Lampirkan Resolver** untuk. `deletePet(input: DeletePetInput!): Pet` Pilih **sumber data RDS** Anda. Di bagian **template pemetaan permintaan**, tambahkan template berikut.

```
{
"version": "2018-05-29",
    "statements": [
        $util.toJson("select * from Pets WHERE id=:ID"),
        $util.toJson("delete from Pets WHERE id=:ID")
    ],
    "variableMap": {
        ":ID": "$ctx.args.input.id"
    }
}
```

Di bagian **template pemetaan respons**, tambahkan template berikut.

```
$utils.toJson($utils.rds.toJsonObject($ctx.result)[0][0])
```

### Query.getPet
<a name="query-getpet"></a>

Sekarang mutasi dibuat untuk skema Anda, hubungkan tiga kueri untuk menampilkan cara mendapatkan item individual, daftar, dan menerapkan pemfilteran SQL. Dari **editor skema** di AWS AppSync konsol, pilih **Lampirkan Resolver** untuk. `getPet(id: ID!): Pet` Pilih **sumber data RDS** Anda. Di bagian **template pemetaan permintaan**, tambahkan template berikut.

```
{
"version": "2018-05-29",
        "statements": [
            $util.toJson("select * from Pets WHERE id=:ID")
    ],
    "variableMap": {
        ":ID": "$ctx.args.id"
    }
}
```

Di bagian **template pemetaan respons**, tambahkan templat berikut:

```
$utils.toJson($utils.rds.toJsonObject($ctx.result)[0][0])
```

### Query.listpets
<a name="query-listpets"></a>

Dari editor skema di AWS AppSync konsol, di sisi kanan pilih **Lampirkan Resolver** untuk. `getPet(id: ID!): Pet` Pilih **sumber data RDS** Anda. Di bagian **template pemetaan permintaan**, tambahkan template berikut.

```
{
    "version": "2018-05-29",
    "statements": [
        "select * from Pets"
    ]
}
```

Di bagian **template pemetaan respons**, tambahkan template berikut.

```
$utils.toJson($utils.rds.toJsonObject($ctx.result)[0])
```

### Permintaan. listPetsByPriceRange
<a name="query-listpetsbypricerange"></a>

Dari editor skema di AWS AppSync konsol, di sisi kanan pilih **Lampirkan Resolver** untuk. `getPet(id: ID!): Pet` Pilih **sumber data RDS** Anda. Di bagian **template pemetaan permintaan**, tambahkan template berikut.

```
{
    "version": "2018-05-29",
    "statements": [
            "select * from Pets where price > :MIN and price < :MAX"
    ],

    "variableMap": {
        ":MAX": $util.toJson($ctx.args.max),
        ":MIN": $util.toJson($ctx.args.min)
    }
}
```

Di bagian **template pemetaan respons**, tambahkan templat berikut:

```
$utils.toJson($utils.rds.toJsonObject($ctx.result)[0])
```

## Ubah Data Anda Melalui API
<a name="run-mutations"></a>

Sekarang setelah Anda mengonfigurasi semua resolver Anda dengan pernyataan SQL dan menghubungkan GraphQL API Anda ke API Data Aurora Tanpa Server, Anda dapat mulai melakukan mutasi dan kueri. Di AWS AppSync konsol, pilih tab **Kueri** dan masukkan yang berikut ini untuk membuat Pet:

```
mutation add {
    createPet(input : { type:fish, price:10.0 }){
        id
        type
        price
    }
}
```

Respons harus berisi *id*, *tipe*, dan *harga* seperti:

```
{
  "data": {
    "createPet": {
      "id": "c6fedbbe-57ad-4da3-860a-ffe8d039882a",
      "type": "fish",
      "price": "10.0"
    }
  }
}
```

Anda dapat memodifikasi item ini dengan menjalankan mutasi *updatePet*:

```
mutation update {
    updatePet(input : {
        id: ID_PLACEHOLDER,
        type:bird,
        price:50.0
    }){
        id
        type
        price
    }
}
```

Perhatikan bahwa kami menggunakan *id* yang dikembalikan dari operasi *createPet* sebelumnya. Ini akan menjadi nilai unik untuk catatan Anda saat resolver dimanfaatkan. `$util.autoId()` Anda dapat menghapus catatan dengan cara yang sama:

```
mutation delete {
    deletePet(input : {id:ID_PLACEHOLDER}){
        id
        type
        price
    }
}
```

Buat beberapa catatan dengan mutasi pertama dengan nilai *harga* yang berbeda dan kemudian jalankan beberapa kueri.

## Ambil Data Anda
<a name="run-queries"></a>

Masih di tab **Kueri** konsol, gunakan pernyataan berikut untuk mencantumkan semua catatan yang telah Anda buat.

```
query allpets {
    listPets {
        id
        type
        price
    }
}
```

*Manfaatkan predikat SQL *WHERE* yang ada `where price > :MIN and price < :MAX` di template pemetaan kami untuk Query. listPetsByPriceRange*dengan query GraphQL berikut:

```
query petsByPriceRange {
    listPetsByPriceRange(min:1, max:11) {
        id
        type
        price
    }
}
```

Anda seharusnya hanya melihat catatan dengan *harga* lebih dari \$11 atau kurang dari \$110. Akhirnya, Anda dapat melakukan kueri untuk mengambil catatan individual sebagai berikut:

```
query onePet {
    getPet(id:ID_PLACEHOLDER){
        id
        type
        price
    }
}
```

## Amankan Akses Data Anda
<a name="input-sanitization"></a>

Injeksi SQL adalah kerentanan keamanan dalam aplikasi database. Itu terjadi ketika penyerang memasukkan kode SQL berbahaya melalui bidang input pengguna. Ini dapat memungkinkan akses tidak sah ke data database. Kami menyarankan Anda memvalidasi dan membersihkan semua input pengguna dengan hati-hati sebelum memproses penggunaan `variableMap` untuk perlindungan terhadap serangan injeksi SQL. Jika peta variabel tidak digunakan, Anda bertanggung jawab untuk membersihkan argumen operasi GraphQL mereka. Salah satu cara untuk melakukannya adalah dengan memberikan input langkah-langkah validasi spesifik dalam template pemetaan permintaan sebelum eksekusi pernyataan SQL terhadap API Data Anda. Mari kita lihat bagaimana kita dapat memodifikasi template pemetaan permintaan dari `listPetsByPriceRange` contoh. Alih-alih hanya mengandalkan input pengguna, Anda dapat melakukan hal berikut:

```
#set($validMaxPrice = $util.matches("\d{1,3}[,\\.]?(\\d{1,2})?",$ctx.args.maxPrice))

#set($validMinPrice = $util.matches("\d{1,3}[,\\.]?(\\d{1,2})?",$ctx.args.minPrice))


#if (!$validMaxPrice || !$validMinPrice)
    $util.error("Provided price input is not valid.")
#end
{
    "version": "2018-05-29",
    "statements": [
            "select * from Pets where price > :MIN and price < :MAX"
    ],

    "variableMap": {
        ":MAX": $util.toJson($ctx.args.maxPrice),
        ":MIN": $util.toJson($ctx.args.minPrice)
    }
}
```

Cara lain untuk melindungi terhadap masukan jahat saat mengeksekusi resolver terhadap API Data Anda adalah dengan menggunakan pernyataan yang disiapkan bersama dengan prosedur tersimpan dan input berparameter. Misalnya, dalam resolver untuk `listPets` menentukan prosedur berikut yang mengeksekusi *pilih* sebagai pernyataan yang disiapkan:

```
CREATE PROCEDURE listPets (IN type_param VARCHAR(200))
  BEGIN
     PREPARE stmt FROM 'SELECT * FROM Pets where type=?';
     SET @type = type_param;
     EXECUTE stmt USING @type;
     DEALLOCATE PREPARE stmt;
  END
```

Buat ini di Instans Aurora Serverless v2 Anda.

```
aws rds-data execute-statement --resource-arn "arn:aws:rds:us-east-1:xxxxxxxxxxxx:cluster:http-endpoint-test" \
--schema "mysql"  --secret-arn "arn:aws:secretsmanager:us-east-1:xxxxxxxxxxxx:secret:httpendpoint-xxxxxx"  \
--region us-east-1  --database "DB_NAME" \
--sql "CREATE PROCEDURE listPets (IN type_param VARCHAR(200)) BEGIN PREPARE stmt FROM 'SELECT * FROM Pets where type=?'; SET @type = type_param; EXECUTE stmt USING @type; DEALLOCATE PREPARE stmt; END"
```

Kode resolver yang dihasilkan untuk ListPets disederhanakan karena kita sekarang cukup memanggil prosedur tersimpan. Minimal, setiap input string harus memiliki tanda kutip tunggal yang [lolos.](#escaped)

```
#set ($validType = $util.isString($ctx.args.type) && !$util.isNullOrBlank($ctx.args.type))
#if (!$validType)
    $util.error("Input for 'type' is not valid.", "ValidationError")
#end

{
    "version": "2018-05-29",
    "statements": [
        "CALL listPets(:type)"
    ]
    "variableMap": {
        ":type": $util.toJson($ctx.args.type.replace("'", "''"))
    }
}
```

### Menggunakan string pelarian
<a name="escaped"></a>

Gunakan tanda kutip tunggal untuk menandai awal dan akhir literal string dalam pernyataan SQL misalnya.. `'some string value'`. Untuk memungkinkan nilai string dengan satu atau lebih karakter kutipan tunggal (`'`) untuk digunakan dalam string, masing-masing harus diganti dengan dua tanda kutip tunggal (`''`). Misalnya, jika string inputnya`Nadia's dog`, Anda akan menghindarinya untuk pernyataan SQL seperti

```
update Pets set type='Nadia''s dog' WHERE id='1'
```