Menggunakan Aurora Serverless v2 dengan AWS AppSync - AWS AppSync GraphQL

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

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

Menyiapkan kluster database Anda

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

Anda dapat mengaktifkan Data API pada klaster Anda dengan mengikuti petunjuk dalam dokumentasi RDS. Data API harus diaktifkan sebelum menambahkan sebagai sumber AppSync data.

Buat database dan tabel

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

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

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

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

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

  2. perbarui hewan peliharaan menggunakan bidang mutation.updatePet

  3. hapus hewan peliharaan menggunakan bidang mutation.deletePet

  4. dapatkan satu menggunakan melalui bidang Query.getPet

  5. daftar semua menggunakan bidang Query.listPets

  6. daftar hewan peliharaan dalam kisaran harga menggunakan Query. listPetsByPriceRangelapangan

Mutasi.createPet

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

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

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

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

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

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

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

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. listPetsByPriceRangedengan query GraphQL berikut:

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

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

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

Amankan Akses Data Anda

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.

#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

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 inputnyaNadia's dog, Anda akan menghindarinya untuk pernyataan SQL seperti

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