Şimdi tablonuzda oyun öğesi sahibi olduğunuza göre ilerleme durumundaki bir oyunda bir oyuncunun hamle yapmasını nasıl simüle edebileceğinizi öğrenebilirsiniz.
Bu işlemle başa çıkmanın iki yolu vardır. İlk yolda GetItem (ÖğeyiAl) API’sini kullanarak öğeyi elde edersiniz. Sonra, oyuncu tarafından yapılan hamleye göre oyun öğesini uygulamanızda güncellersiniz. Son olarak, PutItem (ÖğeKoy) API’sini kullanarak varolan nesneyi DynamoDB’de değiştirirsiniz. Bu seçeneğin işe yaramasına rağmen DynamoDB tablonuza birden fazla istek yapılmasını gerektirir ve oyun öğenizi getirme ve yeniden yazma süreçleri arasında değişikliklerin üzerine yazma riski oluşturur.
Bu işlem ile başa çıkmanın ikinci yolu ise DynamoDB’de UpdateItem (ÖğeGüncelle) API çağrısını kullanmaktır. UpdateItem (ÖğeGüncelle) API’si ile DynamoDB öğenizi yerinde tek bir istek ile güncelleyebilirsiniz. Değişmesini istediğiniz öğeyi, öznitelikleri ve öğelere uygulamak istediğiniz koşulları belirtirsiniz. Veri tabanınıza birden fazla çağrı gerektirmediği için bir nesne üzerinde değişiklik yapmak amacıyla tercih edilen yol budur.
scripts/ dizininde aşağıdaki içeriklere sahip olan performMove.js isimli bir dosya vardır.
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 })
Bu betik biraz karmaşık olduğu için adım adım ilerleyelim.
Önceki betik gibi AWS SDK’yi içe aktarır ve bir DynamoDB Document Client bulut sunucusu oluşturursunuz.
Sonra, performMove (Hamleyap) denilen bir yöntem tanımlarsınız. Bu yöntem, bir kullanıcı bir hamle yapma isteğinde bulunduğunda uygulamanızda kullanılacak olan iç yönteme benzerdir. Betik bir UpdateItem (ÖğeGüncelle) API çağrısı için parametreleri derler. Önce, oyundaki iki özniteliği değiştirir -- hamle yapan son kullanıcı ve değişen yığındaki öğe sayısı.
UpdateItem (ÖğeGüncelle) API parametreleri sonra oyunun mevcut durumu hakkında bazı onaylama işlemleri yapar. Öğenin istediğiniz durumda olduğunu onaylamak için öğe güncellenmeden önce Koşul İfadesi değerlendirilir. Koşul ifadenizde aşağıdaki üç onaylamayı yaparsınız:
- Hamle yapmak isteyen kullanıcı oyundaki iki kullanıcıdan biridir;
- Mevcut sıra hamle yapma isteğinde bulunan kullanıcıya aittir;
- Değiştirilen yığının mevcut değeri değiştirildiği durumdan daha yüksektir.
Son olarak parametreler ALL_NEW (HEPSİ_YENİ) için ReturnValue (DönüşDeğeri) belirtir yani DynamoDB tüm öğeyi, öğenin değerleri güncellendikten sonra geri gönderir. Sonrasında uygulamanız bir kazanan olup olmadığını görmek için oyunu değerlendirebilir.
Dosyanın sonunda bu yöntemin uygulamanızda nasıl çağrıldığının bir örneği vardır. Aşağıdaki komut ile betiği yürütebilirsiniz.
Terminalinizde aşağıdaki çıktıları görmeniz gerekir:
Updated game: { heap2: 4,
heap1: 3,
heap3: 5,
gameId: '5b5ee7d8',
user2: 'theseconduser',
user1: 'myfirstuser',
lastMoveBy: 'theseconduser' }
Yazmanın başarılı olduğunu ve oyunun güncellendiğini görebilirsiniz.
Betiği terminalinizde yeniden çalıştırmayı deneyin. Aşağıdaki çıktıları görmeniz gerekir:
Koşullu örnekleriniz bu sefer başarısız oldu. İstekte bulunan kullanıcı --theseconduser (ikincikullanıcı) -- hamle yapan en son kullanıcıydı. Dahası, değiştirilen yığın -- yığın1 -- çoktan 3 değerine sahipti yani kullanıcı bir şey değiştirmedi. Bu yüzden istek reddedildi