Tutorial: Penyelesai Transaksi DynamoDB - AWS AppSync

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

Tutorial: Penyelesai Transaksi DynamoDB

catatan

Kami sekarang terutama mendukung runtime APPSYNC_JS dan dokumentasinya. Harap pertimbangkan untuk menggunakan runtime APPSYNC_JS dan panduannya di sini.

AWS AppSync mendukung penggunaan operasi transaksi Amazon DynamoDB di satu atau beberapa tabel dalam satu wilayah. Operasi yang didukung adalah TransactGetItems danTransactWriteItems. Dengan menggunakan fitur-fitur ini di AWS AppSync, Anda dapat melakukan tugas-tugas seperti:

  • Lewati daftar kunci dalam satu kueri dan kembalikan hasil dari tabel

  • Membaca catatan dari satu atau beberapa tabel dalam satu kueri

  • Menulis catatan dalam transaksi ke satu atau beberapa tabel dengan all-or-nothing cara

  • Jalankan transaksi ketika beberapa kondisi terpenuhi

Izin

Seperti resolver lainnya, Anda perlu membuat sumber data AWS AppSync dan membuat peran atau menggunakan yang sudah ada. Karena operasi transaksi memerlukan izin yang berbeda pada tabel DynamoDB, Anda perlu memberikan izin peran yang dikonfigurasi untuk tindakan baca atau tulis:

{ "Version": "2012-10-17", "Statement": [ { "Action": [ "dynamodb:DeleteItem", "dynamodb:GetItem", "dynamodb:PutItem", "dynamodb:Query", "dynamodb:Scan", "dynamodb:UpdateItem" ], "Effect": "Allow", "Resource": [ "arn:aws:dynamodb:region:accountId:table/TABLENAME", "arn:aws:dynamodb:region:accountId:table/TABLENAME/*" ] } ] }

Catatan: Peran terkait dengan sumber data di AWS AppSync, dan resolver pada bidang dipanggil terhadap sumber data. Sumber data yang dikonfigurasi untuk mengambil terhadap DynamoDB hanya memiliki satu tabel yang ditentukan, untuk menjaga konfigurasi tetap sederhana. Oleh karena itu, saat melakukan operasi transaksi terhadap beberapa tabel dalam satu resolver, yang merupakan tugas yang lebih maju, Anda harus memberikan peran pada akses sumber data tersebut ke tabel mana pun yang akan berinteraksi dengan resolver. Ini akan dilakukan di bidang Sumber Daya dalam kebijakan IAM di atas. Konfigurasi panggilan transaksi terhadap tabel dilakukan dalam template resolver, yang kami jelaskan di bawah ini.

Sumber Data

Demi kesederhanaan, kita akan menggunakan sumber data yang sama untuk semua resolver yang digunakan dalam tutorial ini. Pada tab Sumber data, buat sumber data DynamoDB baru dan beri nama. TransactTutorial Nama tabel dapat berupa apa saja karena nama tabel ditentukan sebagai bagian dari template pemetaan permintaan untuk operasi transaksi. Kami akan memberikan nama tabelempty.

Kita akan memiliki dua tabel yang disebut SavingAccounts dan CheckingAccounts, accountNumber keduanya dengan kunci partisi, dan tabel TransactionHistory dengan as partition key. transactionId

Untuk tutorial ini, peran apa pun dengan kebijakan inline berikut akan berfungsi. Ganti region dan accountId dengan wilayah dan ID akun Anda:

{ "Version": "2012-10-17", "Statement": [ { "Action": [ "dynamodb:DeleteItem", "dynamodb:GetItem", "dynamodb:PutItem", "dynamodb:Query", "dynamodb:Scan", "dynamodb:UpdateItem" ], "Effect": "Allow", "Resource": [ "arn:aws:dynamodb:region:accountId:table/savingAccounts", "arn:aws:dynamodb:region:accountId:table/savingAccounts/*", "arn:aws:dynamodb:region:accountId:table/checkingAccounts", "arn:aws:dynamodb:region:accountId:table/checkingAccounts/*", "arn:aws:dynamodb:region:accountId:table/transactionHistory", "arn:aws:dynamodb:region:accountId:table/transactionHistory/*" ] } ] }

Transaksi

Untuk contoh ini, konteksnya adalah transaksi perbankan klasik, di mana kita akan menggunakan TransactWriteItems untuk:

  • Transfer uang dari rekening tabungan ke rekening giro

  • Menghasilkan catatan transaksi baru untuk setiap transaksi

Dan kemudian kita akan menggunakan TransactGetItems untuk mengambil rincian dari rekening tabungan dan rekening giro.

Kami mendefinisikan skema GraphQL kami sebagai berikut:

type SavingAccount { accountNumber: String! username: String balance: Float } type CheckingAccount { accountNumber: String! username: String balance: Float } type TransactionHistory { transactionId: ID! from: String to: String amount: Float } type TransactionResult { savingAccounts: [SavingAccount] checkingAccounts: [CheckingAccount] transactionHistory: [TransactionHistory] } input SavingAccountInput { accountNumber: String! username: String balance: Float } input CheckingAccountInput { accountNumber: String! username: String balance: Float } input TransactionInput { savingAccountNumber: String! checkingAccountNumber: String! amount: Float! } type Query { getAccounts(savingAccountNumbers: [String], checkingAccountNumbers: [String]): TransactionResult } type Mutation { populateAccounts(savingAccounts: [SavingAccountInput], checkingAccounts: [CheckingAccountInput]): TransactionResult transferMoney(transactions: [TransactionInput]): TransactionResult } schema { query: Query mutation: Mutation }

TransactWriteItems - Mengisi Akun

Untuk mentransfer uang antar akun, kita perlu mengisi tabel dengan detailnya. Kami akan menggunakan Mutation.populateAccounts operasi GraphQL untuk melakukannya.

Di bagian Skema, klik Lampirkan di sebelah Mutation.populateAccounts operasi. Buka Resolver Unit VTL, lalu pilih sumber data yang sama. TransactTutorial

Sekarang gunakan template pemetaan permintaan berikut:

Templat Pemetaan Permintaan

#set($savingAccountTransactPutItems = []) #set($index = 0) #foreach($savingAccount in ${ctx.args.savingAccounts}) #set($keyMap = {}) $util.qr($keyMap.put("accountNumber", $util.dynamodb.toString($savingAccount.accountNumber))) #set($attributeValues = {}) $util.qr($attributeValues.put("username", $util.dynamodb.toString($savingAccount.username))) $util.qr($attributeValues.put("balance", $util.dynamodb.toNumber($savingAccount.balance))) #set($index = $index + 1) #set($savingAccountTransactPutItem = {"table": "savingAccounts", "operation": "PutItem", "key": $keyMap, "attributeValues": $attributeValues}) $util.qr($savingAccountTransactPutItems.add($savingAccountTransactPutItem)) #end #set($checkingAccountTransactPutItems = []) #set($index = 0) #foreach($checkingAccount in ${ctx.args.checkingAccounts}) #set($keyMap = {}) $util.qr($keyMap.put("accountNumber", $util.dynamodb.toString($checkingAccount.accountNumber))) #set($attributeValues = {}) $util.qr($attributeValues.put("username", $util.dynamodb.toString($checkingAccount.username))) $util.qr($attributeValues.put("balance", $util.dynamodb.toNumber($checkingAccount.balance))) #set($index = $index + 1) #set($checkingAccountTransactPutItem = {"table": "checkingAccounts", "operation": "PutItem", "key": $keyMap, "attributeValues": $attributeValues}) $util.qr($checkingAccountTransactPutItems.add($checkingAccountTransactPutItem)) #end #set($transactItems = []) $util.qr($transactItems.addAll($savingAccountTransactPutItems)) $util.qr($transactItems.addAll($checkingAccountTransactPutItems)) { "version" : "2018-05-29", "operation" : "TransactWriteItems", "transactItems" : $util.toJson($transactItems) }

Dan template pemetaan respons berikut:

Templat Pemetaan Respon

#if ($ctx.error) $util.appendError($ctx.error.message, $ctx.error.type, null, $ctx.result.cancellationReasons) #end #set($savingAccounts = []) #foreach($index in [0..2]) $util.qr($savingAccounts.add(${ctx.result.keys[$index]})) #end #set($checkingAccounts = []) #foreach($index in [3..5]) $util.qr($checkingAccounts.add(${ctx.result.keys[$index]})) #end #set($transactionResult = {}) $util.qr($transactionResult.put('savingAccounts', $savingAccounts)) $util.qr($transactionResult.put('checkingAccounts', $checkingAccounts)) $util.toJson($transactionResult)

Simpan resolver dan navigasikan ke bagian Kueri AWS AppSync konsol untuk mengisi akun.

Jalankan mutasi berikut:

mutation populateAccounts { populateAccounts ( savingAccounts: [ {accountNumber: "1", username: "Tom", balance: 100}, {accountNumber: "2", username: "Amy", balance: 90}, {accountNumber: "3", username: "Lily", balance: 80}, ] checkingAccounts: [ {accountNumber: "1", username: "Tom", balance: 70}, {accountNumber: "2", username: "Amy", balance: 60}, {accountNumber: "3", username: "Lily", balance: 50}, ]) { savingAccounts { accountNumber } checkingAccounts { accountNumber } } }

Kami mengisi 3 rekening tabungan dan 3 rekening giro dalam satu mutasi.

Gunakan konsol DynamoDB untuk memvalidasi bahwa data muncul di tabel SavingAccounts dan CheckingAccounts.

TransactWriteItems - Transfer Uang

Lampirkan resolver ke transferMoney mutasi dengan Template Pemetaan Permintaan berikut. Perhatikan nilai-nilaiamounts,savingAccountNumbers, checkingAccountNumbers dan sama.

#set($amounts = []) #foreach($transaction in ${ctx.args.transactions}) #set($attributeValueMap = {}) $util.qr($attributeValueMap.put(":amount", $util.dynamodb.toNumber($transaction.amount))) $util.qr($amounts.add($attributeValueMap)) #end #set($savingAccountTransactUpdateItems = []) #set($index = 0) #foreach($transaction in ${ctx.args.transactions}) #set($keyMap = {}) $util.qr($keyMap.put("accountNumber", $util.dynamodb.toString($transaction.savingAccountNumber))) #set($update = {}) $util.qr($update.put("expression", "SET balance = balance - :amount")) $util.qr($update.put("expressionValues", $amounts[$index])) #set($index = $index + 1) #set($savingAccountTransactUpdateItem = {"table": "savingAccounts", "operation": "UpdateItem", "key": $keyMap, "update": $update}) $util.qr($savingAccountTransactUpdateItems.add($savingAccountTransactUpdateItem)) #end #set($checkingAccountTransactUpdateItems = []) #set($index = 0) #foreach($transaction in ${ctx.args.transactions}) #set($keyMap = {}) $util.qr($keyMap.put("accountNumber", $util.dynamodb.toString($transaction.checkingAccountNumber))) #set($update = {}) $util.qr($update.put("expression", "SET balance = balance + :amount")) $util.qr($update.put("expressionValues", $amounts[$index])) #set($index = $index + 1) #set($checkingAccountTransactUpdateItem = {"table": "checkingAccounts", "operation": "UpdateItem", "key": $keyMap, "update": $update}) $util.qr($checkingAccountTransactUpdateItems.add($checkingAccountTransactUpdateItem)) #end #set($transactionHistoryTransactPutItems = []) #foreach($transaction in ${ctx.args.transactions}) #set($keyMap = {}) $util.qr($keyMap.put("transactionId", $util.dynamodb.toString(${utils.autoId()}))) #set($attributeValues = {}) $util.qr($attributeValues.put("from", $util.dynamodb.toString($transaction.savingAccountNumber))) $util.qr($attributeValues.put("to", $util.dynamodb.toString($transaction.checkingAccountNumber))) $util.qr($attributeValues.put("amount", $util.dynamodb.toNumber($transaction.amount))) #set($transactionHistoryTransactPutItem = {"table": "transactionHistory", "operation": "PutItem", "key": $keyMap, "attributeValues": $attributeValues}) $util.qr($transactionHistoryTransactPutItems.add($transactionHistoryTransactPutItem)) #end #set($transactItems = []) $util.qr($transactItems.addAll($savingAccountTransactUpdateItems)) $util.qr($transactItems.addAll($checkingAccountTransactUpdateItems)) $util.qr($transactItems.addAll($transactionHistoryTransactPutItems)) { "version" : "2018-05-29", "operation" : "TransactWriteItems", "transactItems" : $util.toJson($transactItems) }

Kami akan memiliki 3 transaksi perbankan dalam satu TransactWriteItems operasi. Gunakan Template Pemetaan Respons berikut:

#if ($ctx.error) $util.appendError($ctx.error.message, $ctx.error.type, null, $ctx.result.cancellationReasons) #end #set($savingAccounts = []) #foreach($index in [0..2]) $util.qr($savingAccounts.add(${ctx.result.keys[$index]})) #end #set($checkingAccounts = []) #foreach($index in [3..5]) $util.qr($checkingAccounts.add(${ctx.result.keys[$index]})) #end #set($transactionHistory = []) #foreach($index in [6..8]) $util.qr($transactionHistory.add(${ctx.result.keys[$index]})) #end #set($transactionResult = {}) $util.qr($transactionResult.put('savingAccounts', $savingAccounts)) $util.qr($transactionResult.put('checkingAccounts', $checkingAccounts)) $util.qr($transactionResult.put('transactionHistory', $transactionHistory)) $util.toJson($transactionResult)

Sekarang arahkan ke bagian Kueri AWS AppSync konsol dan jalankan mutasi TransferMoney sebagai berikut:

mutation write { transferMoney( transactions: [ {savingAccountNumber: "1", checkingAccountNumber: "1", amount: 7.5}, {savingAccountNumber: "2", checkingAccountNumber: "2", amount: 6.0}, {savingAccountNumber: "3", checkingAccountNumber: "3", amount: 3.3} ]) { savingAccounts { accountNumber } checkingAccounts { accountNumber } transactionHistory { transactionId } } }

Kami mengirim 2 transaksi perbankan dalam satu mutasi. Gunakan konsol DynamoDB untuk memvalidasi data yang muncul di tabel SavingAccounts, CheckingAccounts, dan TransactionHistory.

TransactGetItems - Ambil Akun

Untuk mengambil detail dari rekening tabungan dan rekening giro dalam satu permintaan transaksional, kami akan melampirkan resolver ke operasi Query.getAccounts GraphQL pada skema kami. Pilih Lampirkan, pergi ke VTL Unit Resolvers, lalu pada layar berikutnya, pilih sumber TransactTutorial data yang sama yang dibuat di awal tutorial. Konfigurasikan template sebagai berikut:

Templat Pemetaan Permintaan

#set($savingAccountsTransactGets = []) #foreach($savingAccountNumber in ${ctx.args.savingAccountNumbers}) #set($savingAccountKey = {}) $util.qr($savingAccountKey.put("accountNumber", $util.dynamodb.toString($savingAccountNumber))) #set($savingAccountTransactGet = {"table": "savingAccounts", "key": $savingAccountKey}) $util.qr($savingAccountsTransactGets.add($savingAccountTransactGet)) #end #set($checkingAccountsTransactGets = []) #foreach($checkingAccountNumber in ${ctx.args.checkingAccountNumbers}) #set($checkingAccountKey = {}) $util.qr($checkingAccountKey.put("accountNumber", $util.dynamodb.toString($checkingAccountNumber))) #set($checkingAccountTransactGet = {"table": "checkingAccounts", "key": $checkingAccountKey}) $util.qr($checkingAccountsTransactGets.add($checkingAccountTransactGet)) #end #set($transactItems = []) $util.qr($transactItems.addAll($savingAccountsTransactGets)) $util.qr($transactItems.addAll($checkingAccountsTransactGets)) { "version" : "2018-05-29", "operation" : "TransactGetItems", "transactItems" : $util.toJson($transactItems) }

Templat Pemetaan Respon

#if ($ctx.error) $util.appendError($ctx.error.message, $ctx.error.type, null, $ctx.result.cancellationReasons) #end #set($savingAccounts = []) #foreach($index in [0..2]) $util.qr($savingAccounts.add(${ctx.result.items[$index]})) #end #set($checkingAccounts = []) #foreach($index in [3..4]) $util.qr($checkingAccounts.add($ctx.result.items[$index])) #end #set($transactionResult = {}) $util.qr($transactionResult.put('savingAccounts', $savingAccounts)) $util.qr($transactionResult.put('checkingAccounts', $checkingAccounts)) $util.toJson($transactionResult)

Simpan resolver dan navigasikan ke bagian Kueri konsol. AWS AppSync Untuk mengambil akun tabungan dan memeriksa akun, jalankan kueri berikut:

query getAccounts { getAccounts( savingAccountNumbers: ["1", "2", "3"], checkingAccountNumbers: ["1", "2"] ) { savingAccounts { accountNumber username balance } checkingAccounts { accountNumber username balance } } }

Kami telah berhasil menunjukkan penggunaan transaksi DynamoDB menggunakan. AWS AppSync