Melakukan transaksi DynamoDB di AWS AppSync - AWS AppSync

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

Melakukan transaksi DynamoDB di AWS AppSync

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:

  • Melewati daftar kunci dalam satu kueri dan mengembalikan hasil dari tabel

  • Membaca catatan dari satu atau beberapa tabel dalam satu kueri

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

  • Menjalankan 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 IAM kebijakan di atas. Konfigurasi panggilan transaksi terhadap tabel dilakukan dalam kode 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.

Kita akan memiliki dua tabel yang disebut savingAccountsdan checkingAccounts, keduanya dengan accountNumber sebagai kunci partisi, dan transactionHistorytabel dengan transactionId kunci partisi. Anda dapat menggunakan CLI perintah di bawah ini untuk membuat tabel Anda. Pastikan untuk mengganti region dengan wilayah Anda.

Dengan CLI

aws dynamodb create-table --table-name savingAccounts \ --attribute-definitions AttributeName=accountNumber,AttributeType=S \ --key-schema AttributeName=accountNumber,KeyType=HASH \ --provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5 \ --table-class STANDARD --region region aws dynamodb create-table --table-name checkingAccounts \ --attribute-definitions AttributeName=accountNumber,AttributeType=S \ --key-schema AttributeName=accountNumber,KeyType=HASH \ --provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5 \ --table-class STANDARD --region region aws dynamodb create-table --table-name transactionHistory \ --attribute-definitions AttributeName=transactionId,AttributeType=S \ --key-schema AttributeName=transactionId,KeyType=HASH \ --provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5 \ --table-class STANDARD --region region

Di AWS AppSync konsol, di Sumber data, buat sumber data DynamoDB baru dan beri nama. TransactTutorial Pilih savingAccountssebagai tabel (meskipun tabel tertentu tidak masalah saat menggunakan transaksi). Pilih untuk membuat peran baru dan sumber data. Anda dapat meninjau konfigurasi sumber data untuk melihat nama peran yang dihasilkan. Di IAM konsol, Anda dapat menambahkan kebijakan in-line yang memungkinkan sumber data berinteraksi dengan semua tabel.

Ganti region dan accountID dengan Region 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.

Awas

TransactWriteItemstidak didukung saat digunakan dengan deteksi dan resolusi konflik. Pengaturan ini harus dinonaktifkan untuk mencegah kemungkinan kesalahan.

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 }

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. Pilih sumber TransactTutorial data dan pilih Buat.

Sekarang gunakan kode berikut:

import { util } from '@aws-appsync/utils' export function request(ctx) { const { savingAccounts, checkingAccounts } = ctx.args const savings = savingAccounts.map(({ accountNumber, ...rest }) => { return { table: 'savingAccounts', operation: 'PutItem', key: util.dynamodb.toMapValues({ accountNumber }), attributeValues: util.dynamodb.toMapValues(rest), } }) const checkings = checkingAccounts.map(({ accountNumber, ...rest }) => { return { table: 'checkingAccounts', operation: 'PutItem', key: util.dynamodb.toMapValues({ accountNumber }), attributeValues: util.dynamodb.toMapValues(rest), } }) return { version: '2018-05-29', operation: 'TransactWriteItems', transactItems: [...savings, ...checkings], } } export function response(ctx) { if (ctx.error) { util.error(ctx.error.message, ctx.error.type, null, ctx.result.cancellationReasons) } const { savingAccounts: sInput, checkingAccounts: cInput } = ctx.args const keys = ctx.result.keys const savingAccounts = sInput.map((_, i) => keys[i]) const sLength = sInput.length const checkingAccounts = cInput.map((_, i) => keys[sLength + i]) return { savingAccounts, checkingAccounts } }

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 tiga rekening tabungan dan tiga rekening giro dalam satu mutasi.

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

TransactWriteItems - Transfer uang

Lampirkan resolver ke transferMoney mutasi dengan kode berikut. Untuk setiap transfer, kami membutuhkan pengubah sukses untuk rekening giro dan tabungan, dan kami perlu melacak transfer dalam transaksi.

import { util } from '@aws-appsync/utils' export function request(ctx) { const transactions = ctx.args.transactions const savings = [] const checkings = [] const history = [] transactions.forEach((t) => { const { savingAccountNumber, checkingAccountNumber, amount } = t savings.push({ table: 'savingAccounts', operation: 'UpdateItem', key: util.dynamodb.toMapValues({ accountNumber: savingAccountNumber }), update: { expression: 'SET balance = balance - :amount', expressionValues: util.dynamodb.toMapValues({ ':amount': amount }), }, }) checkings.push({ table: 'checkingAccounts', operation: 'UpdateItem', key: util.dynamodb.toMapValues({ accountNumber: checkingAccountNumber }), update: { expression: 'SET balance = balance + :amount', expressionValues: util.dynamodb.toMapValues({ ':amount': amount }), }, }) history.push({ table: 'transactionHistory', operation: 'PutItem', key: util.dynamodb.toMapValues({ transactionId: util.autoId() }), attributeValues: util.dynamodb.toMapValues({ from: savingAccountNumber, to: checkingAccountNumber, amount, }), }) }) return { version: '2018-05-29', operation: 'TransactWriteItems', transactItems: [...savings, ...checkings, ...history], } } export function response(ctx) { if (ctx.error) { util.error(ctx.error.message, ctx.error.type, null, ctx.result.cancellationReasons) } const tInput = ctx.args.transactions const tLength = tInput.length const keys = ctx.result.keys const savingAccounts = tInput.map((_, i) => keys[tLength * 0 + i]) const checkingAccounts = tInput.map((_, i) => keys[tLength * 1 + i]) const transactionHistory = tInput.map((_, i) => keys[tLength * 2 + i]) return { savingAccounts, checkingAccounts, transactionHistory } }

Sekarang, navigasikan ke bagian Kueri AWS AppSync konsol dan jalankan transferMoneymutasi 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 tiga transaksi perbankan dalam satu mutasi. Gunakan konsol DynamoDB untuk memvalidasi bahwa data muncul di,, dan tabel savingAccounts. checkingAccountstransactionHistory

TransactGetItems - Ambil akun

Untuk mengambil detail dari tabungan dan rekening giro dalam satu permintaan transaksional, kami akan melampirkan resolver ke operasi Query.getAccounts GraphQL pada skema kami. Pilih Lampirkan, pilih sumber TransactTutorial data yang sama yang dibuat di awal tutorial. Gunakan kode berikut:

import { util } from '@aws-appsync/utils' export function request(ctx) { const { savingAccountNumbers, checkingAccountNumbers } = ctx.args const savings = savingAccountNumbers.map((accountNumber) => { return { table: 'savingAccounts', key: util.dynamodb.toMapValues({ accountNumber }) } }) const checkings = checkingAccountNumbers.map((accountNumber) => { return { table: 'checkingAccounts', key: util.dynamodb.toMapValues({ accountNumber }) } }) return { version: '2018-05-29', operation: 'TransactGetItems', transactItems: [...savings, ...checkings], } } export function response(ctx) { if (ctx.error) { util.error(ctx.error.message, ctx.error.type, null, ctx.result.cancellationReasons) } const { savingAccountNumbers: sInput, checkingAccountNumbers: cInput } = ctx.args const items = ctx.result.items const savingAccounts = sInput.map((_, i) => items[i]) const sLength = sInput.length const checkingAccounts = cInput.map((_, i) => items[sLength + i]) return { savingAccounts, checkingAccounts } }

Simpan resolver dan navigasikan ke bagian Kueri konsol. AWS AppSync Untuk mengambil rekening tabungan dan giro, 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