Ora che hai inserito una voce di gioco nella tabella, puoi imparare a simulare un giocatore che effettua una mossa per un gioco in corso.
Puoi gestire questa operazione in due modi. Nel primo, recuperi la voce utilizzando l'API GetItem. Quindi, aggiorni la voce di gioco nell'applicazione in base alla mossa compiuta dal giocatore. Infine, sostituisci la voce esistente in DynamoDB utilizzando l'API PutItem. Sebbene questa opzione funzioni, sono necessarie più richieste alla tabella DynamoDB e rischi di sovrascrivere eventuali modifiche apportate tra il recupero e la riscrittura della voce di gioco.
Il secondo modo per gestire l'operazione consiste nell'utilizzare la chiamata API UpdateItem in DynamoDB. Con l'API UpdateItem puoi aggiornare la voce DynamoDB sul posto con una sola richiesta. Specifichi la voce e gli attributi da modificare e le eventuali condizioni che desideri asserire sulla voce. Questo è il modo preferito per apportare una modifica a una voce perché non sono richieste chiamate multiple al database.
Nella directory scripts/, è presente un file denominato performMove.js con i contenuti seguenti:
const AWS = require('aws-sdk')
const documentClient = new AWS.DynamoDB.DocumentClient()
const performMove = async ({ gameId, user, changedHeap, changedHeapValue }) => {
if (changedHeapValue < 0 ) {
throw new Error('Cannot set heap value below 0')
}
const params = {
TableName: 'turn-based-game',
Key: {
gameId: gameId
},
UpdateExpression: `SET lastMoveBy = :user, ${changedHeap} = :changedHeapValue`,
ConditionExpression: `(user1 = :user OR user2 = :user) AND lastMoveBy <> :user AND ${changedHeap} > :changedHeapValue`,
ExpressionAttributeValues: {
':user': user,
':changedHeapValue': changedHeapValue,
},
ReturnValues: 'ALL_NEW'
}
try {
const resp = await documentClient.update(params).promise()
console.log('Updated game: ', resp.Attributes)
} catch (error) {
console.log('Error updating item: ', error.message)
}
}
performMove({ gameId: '5b5ee7d8', user: 'theseconduser', changedHeap: 'heap1', changedHeapValue: 3 })
Questo script è un po' complicato, quindi procediamo con un passo alla volta.
Come lo script precedente, importi l'SDK AWS e crei un'istanza del client per documenti DynamoDB.
Quindi definisci un metodo denominato performMove. Questo metodo è simile a uno interno che verrebbe utilizzato nell'applicazione quando un utente richiede di effettuare una mossa. Lo script assembla i parametri per una chiamata API UpdateItem. Prima, cambia due attributi nel gioco, l'ultimo utente che effettua una mossa e il numero di elementi nell'heap modificato.
I parametri dell'API UpdateItem fanno quindi alcune asserzioni sullo stato attuale del gioco. La ConditionExpression viene valutata prima dell'aggiornamento della voce per confermare che questa si trova nello stato desiderato. Nell'espressione di condizione fai le tre asserzioni seguenti:
- L'utente che richiede di effettuare una mossa è uno dei due utenti nel gioco;
- Il turno attuale appartiene all'utente che richiede di effettuare la mossa;
- L'heap che viene modificato presenta un valore attuale superiore rispetto a quello in cui viene modificato.
Infine, i parametri affermano un ReturnValue di ALL_NEW, che significa che DynamoDB restituisce l'intera voce dopo l'aggiornamento dei rispettivi valori. Una volta ottenuto ciò, l'applicazione può valutare il gioco per verificare l'eventuale presenza di un vincitore.
In fondo al file è riportato un esempio di come questo metodo viene chiamato nell'applicazione. Puoi eseguire lo script con il comando seguente:
Dovresti visualizzare l'output seguente nel terminale:
Updated game: { heap2: 4,
heap1: 3,
heap3: 5,
gameId: '5b5ee7d8',
user2: 'theseconduser',
user1: 'myfirstuser',
lastMoveBy: 'theseconduser' }
Puoi vedere che la scrittura ha avuto esito positivo e che il gioco è stato aggiornato.
Prova a eseguire di nuovo lo script nel terminale. Dovresti visualizzare l'output seguente:
Questa volta le richieste condizionali hanno avuto esito negativo. L'utente che effettua la richiesta -- theseconduser -- è stato il giocatore più recente a effettuare la mossa. Inoltre, l'heap modificato -- heap1 -- aveva già un valore di 3, a significare che l'utente non ha modificato nulla. Per questo motivo la richiesta è stata rifiutata.