Backend mit Amazon Web Services

In unserem zweiten Artikel  dieser Serie werden wir erneut ein Backend zum Speichern und Abfragen von Daten erstellen. Als Cloud-Anbieter werden jetzt die Amazon Web Services (AWS) verwendet.

Im Gegensatz zu der Azure-Implementierung unseres Backends werden wir bei AWS den REST-Service nicht selber implementieren. Stattdessen werden wir bestimmte AWS-Services verwenden, welche uns eine Servless-Implementierung des kompletten Backends ermöglicht. Bei Servless müssen wir uns keine Gedanken um etwaige Dienste machen, die wir Verwalten und mit Code deploymen müssen. All dieser administrative Overhead wird uns von AWS abgenommen.

Architekturübersicht

Für unseren servless REST-Backend werden für von AWS folgende Services verwenden:

  • API-Gateway: Stellt uns einen REST-Service-Endpunkt zur Verfügung.
  • Lambda Functions: Verarbeitet die Anfragen vom REST-Service.
  • DynamoDB: Speichert die strukturierten Daten als JSON.
  • IAM Roles: Stellt uns eine Rechteverwaltung für den Zugriff auf die Daten bereit.
  • CloudWatch Logs: Speichert die von den Lambda Function erzeugten Logs (z.B. Fehler).
Systemarchitektur des Backends in der AWS-Cloud

Aufsetzen der DynamoDB

Die DynamoDB ist eine klassische NoSQL-Datenbank, wobei sich Amazon bei der Benennung der Sache in der AWS-Konsole eher an die klassischen Begriffe einer relationalen Datenbank orientiert hat. Daher legen wir eine neue Tabelle an und vergeben einen Primärschlüssel.

Ein Entscheidender Unterschied zu der Azure Cosmos-DB besteht darin, dass wir keine DynamoDB-Instanz erstellen müssen. AWS stellt den Service bereit und ermöglicht den Entwickler nur die Anlage von Tabellen und Daten. Um sicherzustellen, dass nicht jede Anwendung alle Tabellen des von AWS bereitgestellten DynamoDB-Service verwenden kann, müssen wir IAM-Rollen anlegen, welche den Zugriff auf die Tabellen und die erlaubten Operationen steuert.

Einrichten der Zugriffsberechtigungen für die DynamoDB-Tabelle

Implementierung der Lambda Functions

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.

Erstellung einer Lambda Function
import boto3
import json
import shared
import uuid
from datetime import datetime, timezone
from decimal import Decimal
from botocore.exceptions import ClientError
 
def lambda_handler(event, context):
    taskTable = boto3.resource('dynamodb').Table("task")
    body = json.loads(event['body'])
     
    newTask = {
        'id': str(uuid.uuid4()),
        'name': body['name'],
        'name_search': body['name'].lower(),
        'priority': Decimal(body['priority']),
        'description': body['description'],
        'description_search': body['description'].lower(),
        'created_at': datetime.now(timezone.utc).strftime('%Y-%m-%dT%H:%M:%S.%f%Z')
    }
     
    try:
        response = taskTable.put_item(Item = newTask)
 
    except ClientError as err:
        print(err.response['Error']['Message'])
        return shared.respond(err)
         
    else:
        return shared.respond(None, newTask)

Konfiguration des API-Gateways

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.

Deployment der Komponenten

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.