In diesem Modul stellen Sie eine Amazon DynamoDB-Datenbank bereit und lernen, wie Sie DynamoDB zum Speichern von Informationen über Ihr rundenbasiertes Spiel verwenden können.

Veranschlagte Zeit für das Modul: 30 Minuten


Bei Amazon DynamoDB handelt es sich um eine vollständig verwaltete NoSQL-Datenbank von AWS. Sie bietet Antwortzeiten im einstelligen Millisekundenbereich und eine nahezu unendliche Skalierbarkeit. DynamoDB wird von einer Vielzahl von Anwendungen und Branchen genutzt, vom Amazon.com-Einkaufswagen über den Geolokalisierungsdienst von Lyft bis hin zu einer Vielzahl von Online-Spielen.

Die gesamte Interaktion mit DynamoDB erfolgt über HTTPS unter Verwendung von AWS Identity and Access Management (IAM) zur Authentifizierung und Autorisierung. Normalerweise verwenden Sie das AWS SDK für die Sprache Ihrer Wahl, um mit DynamoDB zu interagieren. Wenn Sie AWS-Berechnungsoptionen für Ihre Anwendung verwenden, wie z. B. Amazon Elastic Compute Cloud (Amazon EC2) oder AWS Lambda, kann Ihre Anwendung die AWS-Zugangsdaten in Ihrer Berechnungsumgebung verwenden, um Anfragen an DynamoDB zu stellen.

In den folgenden Schritten stellen Sie zunächst eine DynamoDB-Datenbank bereit. Dann lernen Sie, wie Sie mit Ihrer DynamoDB-Datenbank mit Hilfe des AWS SDK für JavaScript in Node.js interagieren können.


  • Schritt 1. Einrichten einer Amazon DynamoDB-Datenbank

    Richten wir zunächst eine DynamoDB-Datenbank ein Eine Datenbank in DynamoDB wird auch als Tabelle bezeichnet.

    Wenn Sie eine DynamoDB-Tabelle erstellen, müssen Sie das/die Attribut(e) angeben, aus dem/denen der Primärschlüssel Ihrer Tabelle besteht. Jeder Datensatz, den Sie in Ihre DynamoDB-Tabelle schreiben, wird als Element bezeichnet, und jedes Element muss den Primärschlüssel Ihrer Tabelle enthalten.

    DynamoDB-Datenmodellierung und Primärschlüsseldesign ist ein wichtiges Thema. Ihr Spiel hat jedoch ein einfaches Zugriffsmuster, das keine fortgeschrittene Datenmodellierung erfordert, so dass dieses Tutorial keine fortgeschrittenen Themen der DynamoDB-Datenmodellierung behandelt. Weitere Einzelheiten zur Datenmodellierung in DynamoDB finden Sie in den Tutorials zum Entwurf einer Datenbank für eine mobile Anwendung mit Amazon DynamoDB oder zur Datenmodellierung für eine Spielanwendung mit Amazon DynamoDB.

    In Ihrer Anwendung verwenden Sie DynamoDB als einfachen Schlüssel-Wertspeicher. Jedes Spiel hat ein gameId-Attribut, das jedes Spiel eindeutig identifiziert. Das gameId-Attribut wird als Primärschlüssel für Ihre Tabelle verwendet.

    Im Verzeichnis scripts/ gibt es eine Datei namens create-table.sh, die Ihre DynamoDB-Tabelle mit Hilfe der AWS-Befehlszeilenschnittstelle (AWS CLI) erstellt. Der Inhalt der Datei lautet wie folgt:
     

    aws dynamodb create-table \
      --table-name turn-based-game \
      --attribute-definitions '[
        {
          "AttributeName": "gameId",
          "AttributeType": "S"
        }
      ]' \
      --key-schema '[
        {
          "AttributeName": "gameId",
          "KeyType": "HASH"
        }
      ]' \
      --provisioned-throughput '{
        "ReadCapacityUnits": 5,
        "WriteCapacityUnits": 5
      }'

    Zuerst gibt es der Tabelle einen Namen, der auf einem rundenbasierten Spiel basiert. Dann deklariert es die Attribute, die im Primärschlüssel der Tabelle verwendet werden. In diesem Beispiel verwenden Sie einen einfachen Primärschlüssel, sodass Sie nur ein einziges Attribut, gameId, deklarieren, das den String-Datentyp besitzt. Als Nächstes geben Sie Ihr Primärschlüsselschema an, indem Sie angeben, dass das Attribut gameId als Hash-Schlüssel Ihrer Tabelle verwendet werden soll.

    Abschließend geben Sie die Anzahl der Lese- und Schreibkapazitätseinheiten an, die Sie für Ihre Tabelle wünschen. DynamoDB besitzt einen On-Demand-Preismodus, bei dem Sie für jede Lese- und Schreibanforderung an Ihre Tabelle bezahlen. Der bereitgestellte Durchlaufmodus passt jedoch in das kostenlose AWS-Kontingent, sodass Sie ihn hier verwenden können.

    Erstellen Sie Ihre Tabelle, indem Sie den folgenden Befehl in Ihrem Terminal ausführen:

    bash scripts/create-table.sh

    Sie sollten die folgende Ausgabe in Ihrem Terminal sehen:

    {
        "TableDescription": {
            "AttributeDefinitions": [
                {
                    "AttributeName": "gameId",
                    "AttributeType": "S"
                }
            ],
            "TableName": "turn-based-game",
            "KeySchema": [
                {
                    "AttributeName": "gameId",
                    "KeyType": "HASH"
                }
            ],
            "TableStatus": "CREATING",
            "CreationDateTime": 1574086642.07,
            "ProvisionedThroughput": {
                "NumberOfDecreasesToday": 0,
                "ReadCapacityUnits": 5,
                "WriteCapacityUnits": 5
            },
            "TableSizeBytes": 0,
            "ItemCount": 0,
            "TableArn": "arn:aws:dynamodb:us-east-1:955617200811:table/turn-based-game",
            "TableId": "c62cb86a-211e-4a50-a160-4a616c8f3445"
        }
    }
  • Schritt 2. Speichern Sie ein Beispiel für ein Spielobjekt in Ihrer Tabelle

    Nun, da Sie Ihre Tabelle erstellt haben, können Sie Elemente zu ihr hinzufügen. Jedes Spiel wird durch ein einzelnes Element in der Tabelle dargestellt.

    Das Schema der einzelnen Spielgegenstände lautet wie folgt:

    Jedes Spiel enthält eine GameId, die eine eindeutige Kennung für das Spiel ist. Die Attribute User1und User2speichern die Benutzernamen der beiden Benutzer, die das Spiel spielen. Die Attribute Heap1, Heap2und Heap3speichern die Anzahl der Objekte in jedem der drei Haufen. Abschließend gibt das Attribut LastMoveByden Spieler an, der den letzten Zug gemacht hat.

    Im Verzeichnis scripts/ gibt es eine Datei createGame.js, die ein Beispielspiel zu Ihrer Tabelle hinzufügt. Der Inhalt der Datei lautet wie folgt:

    const AWS = require('aws-sdk')
    const documentClient = new AWS.DynamoDB.DocumentClient()
    
    const params = {
      TableName: 'turn-based-game',
      Item: {
        gameId: '5b5ee7d8',
        user1: 'myfirstuser',
        user2: 'theseconduser',
        heap1: 5,
        heap2: 4,
        heap3: 5,
        lastMoveBy: 'myfirstuser'
      }
    }
    
    documentClient.put(params).promise()
      .then(() => console.log('Game added successfully!'))
      .catch((error) => console.log('Error adding game', error))

    Sie importieren das AWS SDK und legen dann eine Instance des DynamoDB Document Client an. Der Document Client ist eine übergeordnete Abstraktion über die Low-Level-API von DynamoDB und erleichtert die Arbeit mit DynamoDB-Elementen. Nach der Erstellung des Clients stellt das Skript die Parameter für einen PutItem-API-Aufruf zusammen, einschließlich des Tabellennamens und der Attribute des Elements. Anschließend ruft es die put()-Methode im Document Client auf und protokolliert Informationen über Erfolg oder Misserfolg.

    Sie können das Skript zum Einfügen eines Spiels in Ihre Tabelle ausführen, indem Sie den folgenden Befehl in Ihrem Terminal ausführen:

    node scripts/createGame.js

    Sie sollten die folgende Ausgabe in Ihrem Terminal sehen:

    Game added successfully!

    Hinweis: Wenn Sie den Befehl zu schnell ausführen, erhalten Sie möglicherweise die Fehlermeldung, dass die Tabelle noch nicht verfügbar ist. Warten Sie in dem Fall eine Minute und versuchen Sie den Befehl erneut.

    Prima! Sie haben nun ein einzelnes Spiel zu Ihrer Tabelle hinzugefügt. Im nächsten Schritt lernen Sie, wie Sie diesen Spielgegenstand aktualisieren können, um einen Benutzer zu simulieren, der einen Zug macht.

  • Schritt 3. Aktualisieren Sie einen Spielgegenstand in Ihrer Tabelle

    Jetzt, wo Sie einen Spielgegenstand in Ihrer Tabelle haben, können Sie lernen, wie Sie einen Spieler simulieren können, der einen Zug in einem laufenden Spiel macht.

    Es gibt zwei Möglichkeiten, wie Sie diesen Vorgang handhaben können. Bei der ersten rufen Sie das Element über die GetItem-API ab. Danach aktualisieren Sie den Spielgegenstand in Ihrer Anwendung entsprechend dem Zug des Spielers. Abschließend ersetzen Sie das vorhandene Element in DynamoDB unter Verwendung der PutItem-API. Obwohl diese Option funktioniert, erfordert sie mehrere Anfragen an Ihre DynamoDB-Tabelle und birgt das Risiko, dass alle Änderungen, die zwischen dem Abrufen und dem Neuschreiben Ihres Spielelements vorgenommen wurden, überschrieben werden.

    Die zweite Möglichkeit, diesen Vorgang zu handhaben, ist die Verwendung des UpdateItem-API-Aufrufs in DynamoDB. Mit der UpdateItem-API können Sie Ihr vorhandenes DynamoDB-Element mit einer einzigen Anfrage aktualisieren. Sie geben das zu ändernde Element, die zu ändernden Attribute und die Bedingungen an, die für das Element geltend gemacht werden sollen. Dies ist die bevorzugte Art und Weise, eine Änderung an einem Gegenstand vorzunehmen, da es nicht erforderlich ist, Ihre Datenbank mehrfach aufzurufen.

    Im Verzeichnis scripts/ gibt es eine Datei namens performMove.js, die den folgenden Inhalt besitzt:

    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 })

    Dieses Skript ist ein wenig kompliziert, also gehen wir es Schritt für Schritt durch.

    Wie im vorherigen Skript importieren Sie das AWS SDK und erstellen eine DynamoDB Document Client-Instanz.

    Danach definieren Sie eine Methode namens performMove. Diese Methode ähnelt einer internen Methode, die in Ihrer Anwendung verwendet werden würde, wenn ein Benutzer einen Umzug anfordert. Das Skript stellt die Parameter für einen UpdateItem-API-Aufruf zusammen. Zunächst werden zwei Attribute der Partie geändert: der letzte Benutzer, der einen Zug gemacht hat, sowie die Anzahl der Elemente im geänderten Haufen.

    Die UpdateItem-API-Parameter machen anschließend einige Aussagen über den aktuellen Stand des Spiels. Die ConditionExpression wird vor der Aktualisierung des Elements ausgewertet, um zu bestätigen, dass sich das Element in dem von Ihnen gewünschten Zustand befindet. Sie stellen die folgenden drei Behauptungen in Ihrem Bedingungsausdruck auf:

    1. Dass der Benutzer, der einen Zug ausführen möchte, einer der beiden Benutzer in der Partie ist;
    2. Dass der aktuelle Zug dem Benutzer gehört, der den Zug ausführen möchte;
    3. Dass der zu ändernde Haufen einen höheren aktuellen Wert hat als der Wert, auf den er geändert wird.

    Abschließend geben die Parameter einen ReturnValue von ALL_NEW an, was bedeutet, dass DynamoDB das gesamte Element zurückgibt, nachdem seine Werte aktualisiert wurden. Sobald Sie dies besitzen, kann Ihre Anwendung das Spiel auswerten, um einen möglichen Gewinner zu ermitteln.

    Am Ende der Datei finden Sie ein Beispiel dafür, wie diese Methode in Ihrer Anwendung aufgerufen wird. Sie können das Skript mit dem folgenden Befehl ausführen:

    node scripts/performMove.js

    Sie sollten die folgende Ausgabe in Ihrem Terminal sehen:

    Updated game:  { heap2: 4,
      heap1: 3,
      heap3: 5,
      gameId: '5b5ee7d8',
      user2: 'theseconduser',
      user1: 'myfirstuser',
      lastMoveBy: 'theseconduser' }

    Sie können sehen, dass das Schreiben erfolgreich war und das Spiel aktualisiert wurde.

    Versuchen Sie, das Skript erneut in Ihrem Terminal auszuführen. Sie sollten die folgende Ausgabe sehen:

    Error updating item:  The conditional request failed

    Ihre bedingten Anforderungen sind diesmal gescheitert. Der anfordernde Benutzer – theseconduser – war der letzte Spieler, der sich bewegt hat. Außerdem hatte der geänderte Haufen – Heap1 – bereits einen Wert von 3, was bedeutet, dass der Benutzer keine Änderungen vorgenommen hat. Aus diesem Grund wurde die Anfrage abgelehnt.


In diesem Modul haben Sie eine Amazon DynamoDB-Datenbank zur Speicherung Ihrer Spieldaten bereitgestellt. Sie haben bei der Modellierung Ihrer Daten etwas über Primärschlüssel in DynamoDB gelernt. Nachdem Sie eine Tabelle erstellt haben, haben Sie gelernt, wie man Elemente in eine Tabelle einfügt, um den anfänglichen Spielstand zu speichern. Abschließend haben Sie erfahren, wie Sie Elemente in Ihren Daten aktualisieren können, um zu vermeiden, dass Sie in einer einzigen Anfrage mehrere Anfragen an DynamoDB stellen.

Im nächsten Modul lernen Sie die Verwendung des Amazon Simple Notification Service (Amazon SNS) zum Versenden von SMS-Nachrichten, um Ihre Benutzer über wichtige Ereignisse in ihrem Spiel zu informieren.