Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.
AWS AppSync supporta l'utilizzo di operazioni di transazione Amazon DynamoDB su una o più tabelle in una singola regione. Le operazioni supportate sono TransactGetItems
e TransactWriteItems
. Utilizzando queste funzionalità in AWS AppSync, puoi eseguire attività come:
-
Passare un elenco di chiavi in una singola query e restituire i risultati da una tabella
-
Leggere i record da una o più tabelle in una singola query
-
Scrittura dei record nelle transazioni su una o più tabelle in qualsiasi all-or-nothing modo
-
Esecuzione di transazioni quando vengono soddisfatte alcune condizioni
Autorizzazioni
Come altri resolver, è necessario creare un'origine dati in AWS AppSync e creare un ruolo o utilizzarne uno esistente. Poiché le operazioni di transazione richiedono autorizzazioni diverse sulle tabelle DynamoDB, è necessario concedere ai ruoli configurati le autorizzazioni per le azioni di lettura o scrittura:
{ "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/*" ] } ] }
Nota
I ruoli sono legati alle fonti di dati in AWS AppSync e i resolver sui campi vengono richiamati su un'origine dati. Le origini dati configurate per il recupero con DynamoDB hanno solo una tabella specificata per semplificare le configurazioni. Pertanto, quando si esegue un'operazione di transazione su più tabelle in un singolo resolver, che è una delle attività più avanzate, è necessario concedere il ruolo sull'accesso all'origine dati a tutte le tabelle con cui interagirà il resolver. Questa operazione può essere eseguita nel campo Risorse della politica di cui sopra. IAM La configurazione delle chiamate di transazione rispetto alle tabelle viene eseguita nel codice del resolver, che descriveremo di seguito.
Origine dati
Per semplicità, useremo la stessa origine dati per tutti i resolver usati in questo tutorial.
Avremo due tabelle chiamate savingAccountse checkingAccounts, entrambe con la chiave di partizione accountNumber
come chiave di partizione e una transactionHistorytabella con transactionId
come chiave di partizione. Puoi usare CLI i comandi seguenti per creare le tue tabelle. Assicurati di sostituirla region
con la tua regione.
Con 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
Nella AWS AppSync console, in Sorgenti dati, crea una nuova origine dati DynamoDB e assegnale un nome. TransactTutorial Seleziona savingAccountscome tabella (anche se la tabella specifica non ha importanza quando si utilizzano le transazioni). Scegli di creare un nuovo ruolo e la fonte di dati. Puoi rivedere la configurazione dell'origine dati per vedere il nome del ruolo generato. Nella IAM console, puoi aggiungere una policy in linea che consente all'origine dati di interagire con tutte le tabelle.
Sostituisci region
e accountID
con la tua regione e l'ID dell'account:
{
"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/*"
]
}
]
}
Transazioni
Per questo esempio, il contesto è una classica transazione bancaria, in cui useremo TransactWriteItems
per:
-
Trasferire denaro dai conti di deposito ai conti correnti
-
Generare nuovi record di transazione per ogni transazione
Quindi, useremo TransactGetItems
per recuperare i dettagli dai conti di deposito ai conti correnti.
avvertimento
TransactWriteItems
non è supportato se utilizzato per il rilevamento e la risoluzione dei conflitti. Queste impostazioni devono essere disabilitate per evitare possibili errori.
Definiamo il nostro schema GraphQL come segue:
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 - Compila gli account
Al fine di trasferire denaro tra gli account, abbiamo bisogno di popolare la tabella con i dettagli. Per farlo, useremo l'operazione GraphQL Mutation.populateAccounts
.
Nella sezione Schema, fai clic su Allega accanto all'Mutation.populateAccounts
operazione. Scegli l'origine TransactTutorial
dati e scegli Crea.
Ora usa il seguente codice:
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 }
}
Salva il resolver e vai alla sezione Query della AWS AppSync console per popolare gli account.
Eseguire la mutazione seguente:
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
}
}
}
Abbiamo popolato tre conti di risparmio e tre conti correnti in un'unica mutazione.
Utilizza la console DynamoDB per verificare che i dati vengano visualizzati sia nelle tabelle che nelle tabelle. savingAccountscheckingAccounts
TransactWriteItems - Trasferisci denaro
Collega un resolver alla transferMoney
mutazione con il seguente codice. Per ogni trasferimento, abbiamo bisogno di un modificatore di successo sia per il conto corrente che per il conto di risparmio e dobbiamo tenere traccia del trasferimento nelle transazioni.
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 }
}
Ora, vai alla sezione Query della AWS AppSync console ed esegui la transferMoneymutazione come segue:
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
}
}
}
Abbiamo inviato tre transazioni bancarie in un'unica mutazione. Utilizza la console DynamoDB per verificare che i dati vengano visualizzati nelle savingAccountstabelle, e. checkingAccountstransactionHistory
TransactGetItems - Recupera gli account
Per recuperare i dettagli dai conti di risparmio e correnti in un'unica richiesta transazionale, collegheremo un resolver all'operazione Query.getAccounts
GraphQL sul nostro schema. Seleziona Allega, scegli la stessa fonte di TransactTutorial
dati creata all'inizio del tutorial. Eseguire il seguente codice:
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 }
}
Salva il resolver e vai alle sezioni Query della console. AWS AppSync Per recuperare i conti di risparmio e i conti correnti, esegui la seguente query:
query getAccounts {
getAccounts(
savingAccountNumbers: ["1", "2", "3"],
checkingAccountNumbers: ["1", "2"]
) {
savingAccounts {
accountNumber
username
balance
}
checkingAccounts {
accountNumber
username
balance
}
}
}
Abbiamo dimostrato con successo l'uso delle transazioni DynamoDB utilizzando. AWS AppSync