Einführung
Ein Bestellteam muss JSON-Bestellungen annehmen und berechnete Summen zurückgeben. Du verbindest Zustands-, Schreib- und Leserouten mit einer bereitgestellten Lambda-Anwendung, testest gültige und abgelehnte Anfragen und prüfst die gespeicherten DynamoDB-Datensätze vor der Bereinigung.
Schließe zuerst Eine Lambda-Funktion über eine HTTP-API zugänglich machen und Von Lambda aus in DynamoDB lesen und schreiben ab. Diese neue Umgebung stellt Anwendung, Rolle und separate Tabellen bereit.
Bezug zu Zertifizierungen
| Zertifizierung | Prüfungsaufgabe | Übung |
|---|---|---|
| Solutions Architect – Associate (SAA-C03) | Aufgabe 2.1 | API-Anfragevalidierung, Antworten und gespeicherte Geschäftsdaten. |
| Developer – Associate (DVA-C02) | Aufgabe 1.1, Aufgabe 3.2 | API-Anfragevalidierung, Antworten und gespeicherte Geschäftsdaten. |
| DevOps Engineer – Professional (DOP-C02) | Aufgabe 3.2 | Grundlagenübung: API-Anfragevalidierung, Antworten und gespeicherte Geschäftsdaten. |
Lab-Überblick

Das Bestell-Backend vorbereiten
In diesem Schritt prüfst du den bereitgestellten Anfragevertrag, erlaubst der Funktion Zugriff auf ihre Bestelltabelle und stellst das Backend bereit. Die Anwendung berechnet ganzzahlige Centbeträge: Menge × 250 + eine Bearbeitungsgebühr von 100 Cent. Verwende AWS View oben, um Anfragen mit gespeicherten Daten zu vergleichen.
Wechsle in den Arbeitsbereich und lies die Anwendung:
cd /home/labex/project
cat app.py
handler empfängt das HTTP-Payload-Format 2.0. POST /orders erwartet genau zwei JSON-Felder: eine kleingeschriebene id mit 2–40 Zeichen, die mit einem Buchstaben beginnt und Buchstaben, Ziffern oder Bindestriche verwendet, sowie eine ganzzahlige quantity von 1 bis 10. Der Code lehnt andere Strukturen vor PutItem ab. GET /orders?id=... liest den gespeicherten Datensatz mit GetItem. Jede Antwort enthält einen HTTP-Status und einen JSON-Inhalt. Du musst diese bereitgestellte Anwendung nicht umschreiben.
Lies den vorbereiteten Tabellenbestand:
aws dynamodb list-tables --query TableNames
Erwarte labex-a02-orders und labex-a02-reference. Nur die Bestelltabelle gehört zur fachlichen Arbeit dieser API. Lies ihren ARN in eine Shellvariable ein:
TABLE_ARN=$(aws dynamodb describe-table \
--table-name labex-a02-orders \
--query Table.TableArn \
--output text)
echo "$TABLE_ARN"
Die Ausführungsrolle steuert ausgehenden Datenbankzugriff. Erstelle mit einem Here-Dokument eine Richtliniendatei. Die Markierung JSON ohne Anführungszeichen erlaubt, $TABLE_ARN durch den gerade gelesenen ARN zu ersetzen; sie enthält keine Zugangsdaten:
cat > orders-policy.json <<JSON
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": ["dynamodb:PutItem", "dynamodb:GetItem"],
"Resource": "$TABLE_ARN"
}]
}
JSON
Füge diese benannte Inline-Richtlinie der vorbereiteten Ausführungsrolle hinzu:
aws iam put-role-policy \
--role-name labex-a02-execution \
--policy-name OrdersData \
--policy-document file://orders-policy.json
Verpacke den bereitgestellten Code mit app.py im Stamm des Archivs:
zip orders.zip app.py
Lies den ARN der vorbereiteten Rolle ein:
ROLE_ARN=$(aws iam get-role \
--role-name labex-a02-execution \
--query Role.Arn \
--output text)
echo "$ROLE_ARN"
Stelle die Funktion mit einem Zeitlimit von zehn Sekunden bereit. Die Anwendung liest TABLE_NAME aus ihrer Umgebung und hält damit die Tabellenauswahl vom Quellcode getrennt:
aws lambda create-function \
--function-name labex-a02-orders-api \
--runtime python3.12 \
--handler app.handler \
--role "$ROLE_ARN" \
--timeout 10 \
--environment '{"Variables":{"TABLE_NAME":"labex-a02-orders"}}' \
--zip-file fileb://orders.zip \
--query '{Name:FunctionName,Handler:Handler,Table:Environment.Variables.TABLE_NAME}'
Erwarte den Funktionsnamen, app.handler und labex-a02-orders. Prüfe in AWS View die Karte Function und bestätige, dass die Bestelltabelle weiterhin null Elemente hat. Code bereitzustellen und Datenzugriff zu gewähren erstellt keine Bestellung.
Zustands- und Bestellrouten zuordnen
In diesem Schritt konfigurierst du eine Integration für drei Routen und erlaubst jeder Route den Aufruf der Funktion.
Erstelle eine HTTP-API und speichere ihre ID:
API_ID=$(aws apigatewayv2 create-api \
--name labex-a02 \
--protocol-type HTTP \
--query ApiId \
--output text)
echo "$API_ID"
printf '%s\n' "$API_ID" > api-id.txt
Erstelle die wörtliche Stage $default mit automatischer Bereitstellung:
aws apigatewayv2 create-stage \
--api-id "$API_ID" \
--stage-name '$default' \
--auto-deploy \
--query '{Stage:StageName,AutoDeploy:AutoDeploy}'
Lies den Backend-ARN ein und erstelle die Integration mit Payload 2.0. Ihre Methode POST ruft Lambda auf; jede Clientroute hat weiterhin ihre eigene HTTP-Methode:
FUNCTION_ARN=$(aws lambda get-function-configuration \
--function-name labex-a02-orders-api \
--query FunctionArn \
--output text)
echo "$FUNCTION_ARN"
INTEGRATION_ID=$(aws apigatewayv2 create-integration \
--api-id "$API_ID" \
--integration-type AWS_PROXY \
--integration-method POST \
--integration-uri "$FUNCTION_ARN" \
--payload-format-version 2.0 \
--query IntegrationId \
--output text)
echo "$INTEGRATION_ID"
Ordne den öffentlichen Zustandsendpunkt dieser Integration zu:
aws apigatewayv2 create-route \
--api-id "$API_ID" \
--route-key 'GET /health' \
--target "integrations/$INTEGRATION_ID" \
--authorization-type NONE \
--query RouteKey \
--output text
Ordne die JSON-Schreibroute zu:
aws apigatewayv2 create-route \
--api-id "$API_ID" \
--route-key 'POST /orders' \
--target "integrations/$INTEGRATION_ID" \
--authorization-type NONE \
--query RouteKey \
--output text
Ordne die Leseroute für gespeicherte Bestellungen zu:
aws apigatewayv2 create-route \
--api-id "$API_ID" \
--route-key 'GET /orders' \
--target "integrations/$INTEGRATION_ID" \
--authorization-type NONE \
--query RouteKey \
--output text
Die Datenbankrichtlinie der Ausführungsrolle erlaubt API Gateway nicht den Aufruf der Funktion. Lies die Konto-ID ein und ergänze anschließend drei präzise Aufrufberechtigungen. Jedes Statement verwendet API-ID, wörtliches $default, Clientmethode und Routenpfad; \$ erhält das Dollarzeichen in einer erweiterten Shellzeichenkette:
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
echo "$ACCOUNT_ID"
aws lambda add-permission \
--function-name labex-a02-orders-api \
--statement-id ApiHealth \
--action lambda:InvokeFunction \
--principal apigateway.amazonaws.com \
--source-account "$ACCOUNT_ID" \
--source-arn "arn:aws:execute-api:us-east-1:$ACCOUNT_ID:$API_ID/\$default/GET/health" \
--query Statement \
--output text
aws lambda add-permission \
--function-name labex-a02-orders-api \
--statement-id ApiWriteOrder \
--action lambda:InvokeFunction \
--principal apigateway.amazonaws.com \
--source-account "$ACCOUNT_ID" \
--source-arn "arn:aws:execute-api:us-east-1:$ACCOUNT_ID:$API_ID/\$default/POST/orders" \
--query Statement \
--output text
aws lambda add-permission \
--function-name labex-a02-orders-api \
--statement-id ApiReadOrder \
--action lambda:InvokeFunction \
--principal apigateway.amazonaws.com \
--source-account "$ACCOUNT_ID" \
--source-arn "arn:aws:execute-api:us-east-1:$ACCOUNT_ID:$API_ID/\$default/GET/orders" \
--query Statement \
--output text
Bilde mit deiner erzeugten ID die vorbereitete API-Adresse des Arbeitsbereichs. Diese Adresse bedient Anfragen innerhalb des Arbeitsbereichs und ist kein öffentlicher AWS-Hostname:
API_URL="http://127.0.0.1:8081/api/$API_ID"
echo "$API_URL"
Teste die Zustandsroute. curl -i schließt die HTTP-Antwortheader ein:
curl -i "$API_URL/health"
Erwarte HTTP 200 und {"healthy": true}. Bestätige in AWS View, dass alle drei Routenschlüssel NONE verwenden, AutoDeploy für die Stage aktiviert ist und der Zustandsaufruf 200 zurückgegeben hat. Die Bestelltabelle sollte weiterhin leer sein, weil diese Anfrage den Zustand prüft, statt eine Bestellung zu speichern.

Gültige Bestellungen und abgelehnte Anfragen testen
In diesem Schritt erstellst du zwei Bestellungen, liest ihre gespeicherten Ergebnisse und prüfst Fehler, bevor sie Geschäftsdaten beeinflussen können.
Eine HTTP-Anfrage besteht aus Methode, Pfad, Headern und optionalem Inhalt. -X POST wählt die Schreibmethode, -H liefert Content-Type: application/json, und --data sendet die JSON-Zeichenkette. Erstelle eine Bestellung mit Menge 2:
curl -i -X POST "$API_URL/orders" -H 'Content-Type: application/json' --data '{"id":"order-one","quantity":2}'
Erwarte HTTP 201 Created und einen Inhalt mit order-one, Menge 2 und total_cents: 600 (2 × 250 + 100). Der Status teilt dem Client mit, dass eine Bestellung gespeichert wurde; der Inhalt meldet das berechnete Ergebnis.
Erstelle eine zweite Bestellung mit einer anderen Menge:
curl -i -X POST "$API_URL/orders" -H 'Content-Type: application/json' --data '{"id":"order-two","quantity":5}'
Erwarte HTTP 201 und total_cents: 1350. Lies beide Bestellungen über die API mit ihrem Abfrageparameter:
curl -i "$API_URL/orders?id=order-one"
curl -i "$API_URL/orders?id=order-two"
Beide Antworten sollten HTTP 200 mit derselben ID, Menge und Summe wie die entsprechende Erstellungsantwort enthalten. Der Lese-Handler ruft den DynamoDB-Zustand ab, statt die Summe aus einer neuen Clientmenge neu zu berechnen.
Prüfe das erste gespeicherte Element unabhängig mit der CLI:
aws dynamodb get-item \
--table-name labex-a02-orders \
--key '{"id":{"S":"order-one"}}' \
--consistent-read \
--query Item
Das typisierte Element enthält quantity: {"N":"2"} und total_cents: {"N":"600"}. Vergleiche in AWS View die beiden tatsächlichen Tabellendatensätze mit den POST- und GET-Aufrufantworten.
Eine syntaktisch gültige JSON-Anfrage kann trotzdem den fachlichen Vertrag verletzen. Sende eine negative Menge:
curl -i -X POST "$API_URL/orders" -H 'Content-Type: application/json' --data '{"id":"bad-negative","quantity":-1}'
Erwarte HTTP 400 Bad Request und Use an id and an integer quantity from 1 to 10. Eine als JSON-Zeichenkette kodierte Zahl wird ebenfalls abgelehnt:
curl -i -X POST "$API_URL/orders" -H 'Content-Type: application/json' --data '{"id":"bad-type","quantity":"2"}'
Teste abschließend einen fehlerhaft aufgebauten JSON-Inhalt:
curl -i -X POST "$API_URL/orders" -H 'Content-Type: application/json' --data '{not-json'
Die letzten beiden Anfragen geben ebenfalls HTTP 400 zurück. Ihre tatsächlichen Handler-Ereignisse können in CloudWatch Logs erscheinen, aber die Tabelle muss weiterhin nur die beiden gültigen Bestellungen enthalten. Die Anfragevalidierung findet in der bereitgestellten Anwendung vor PutItem statt; eine passende API-Route allein validiert ihren Inhalt nicht.
Eine gültige Lese-ID kann auf keine gespeicherte Bestellung verweisen. Frage eine ab, die noch nicht erstellt wurde:
curl -i "$API_URL/orders?id=missing-order"
Erwarte HTTP 404 mit Order not found. Dies unterscheidet sich von einer ungültigen Anfrage mit 400: Die ID hat das erwartete Format, aber kein Element existiert. Betrachte AWS View oben und prüfe die tatsächlichen Antworten 201, 200, 400 und 404; klappe Show logs eines Aufrufs auf, um seine Eingabe mit seinem Ergebnis zu vergleichen. Diese manuelle Oberflächenprüfung ergänzt die unabhängigen schreibgeschützten Prüfungen entfernter Datensätze und tatsächlicher Ausführungen.

Scrolle zur Karte DynamoDB tables, um diese Felder in deiner Umgebung zu vergleichen.
Diese 400-Antworten prüfen die Anwendungsvalidierung: Die Anfrage erreicht Lambda, das die Eingabe vor dem Schreiben ablehnt. Eine spätere JWT-Ablehnung stoppt die Anfrage im API Gateway vor Lambda. Vergleiche Ausführungsprotokoll und gespeicherte Elemente, um die ablehnende Grenze zu erkennen.
Die API und eigene Bestellressourcen entfernen
In diesem Schritt löschst du die Ressourcen der API und erhältst die unbeteiligte Referenztabelle, Logs und vorbereitete Ausführungsrolle.
Dein Bestand besteht aus der API-ID in api-id.txt, labex-a02-orders-api, ihrer Log-Gruppe /aws/lambda/labex-a02-orders-api, labex-a02-orders und der Inline-Rollenrichtlinie OrdersData. Lösche zuerst die API einschließlich ihrer Routen, Integration und Default-Stage:
aws apigatewayv2 delete-api --api-id "$API_ID"
Entferne die Funktion und ihre Aufrufrichtlinie:
aws lambda delete-function --function-name labex-a02-orders-api
Lösche die separate Funktions-Log-Gruppe:
aws logs delete-log-group --log-group-name /aws/lambda/labex-a02-orders-api
Lösche die eigene Bestelltabelle und ihre Daten:
aws dynamodb delete-table \
--table-name labex-a02-orders \
--query TableDescription.TableName \
--output text
Entferne ausschließlich die Datenrichtlinie, die du zur vorbereiteten Rolle hinzugefügt hast:
aws iam delete-role-policy --role-name labex-a02-execution --policy-name OrdersData
Rufe die Bestände erfolgreich ab, um die Löschung nachzuweisen. Authentifizierungs- oder Netzwerkfehler sind keine Löschungsnachweise:
aws apigatewayv2 get-apis --query 'Items[].Name'
aws lambda list-functions --query 'Functions[].FunctionName'
aws dynamodb list-tables --query TableNames
Die ersten beiden Listen sollten leer sein; die Tabellenliste sollte nur labex-a02-reference enthalten. Bestätige, dass ihr ursprüngliches Element erhalten bleibt:
aws dynamodb get-item \
--table-name labex-a02-reference \
--key '{"id":{"S":"reference"}}' \
--query Item
Erwarte message: {"S":"keep unchanged"}. Die Rolle sollte weiterhin ihre unbeteiligte Protokollierungsrichtlinie behalten:
aws iam list-role-policies --role-name labex-a02-execution --query PolicyNames
Erwarte nur FunctionLogs. In AWS View sollten API, Function und Aufrufeinträge verschwunden sein, während Referenztabelle und INFO platform reference keep unchanged erhalten bleiben. Behalte diese vorbereiteten Ressourcen; Testzugangsdaten und VM-Abschaltung werden nach den Ressourcenprüfungen behandelt.
Zusammenfassung
Du hast drei HTTP-Routen mit einer bereitgestellten Lambda-Anwendung verbunden, mit einer präzisen Datenbankrichtlinie und API-Aufrufberechtigungen. Du hast Bestellungen mit unterschiedlichen berechneten Summen erstellt und abgerufen, tatsächliche DynamoDB-Datensätze geprüft und erfolgreiche, ungültige und fehlende Bestellantworten unterschieden. Anschließend hast du die API und ihre eigenen Daten, Funktion, Logs und Richtlinie entfernt und Referenzressourcen erhalten.
Weitere Informationen bietet die AWS-Dokumentation: Lambda-Ereignisse und Antwortformate für HTTP-APIs; HTTP-API-Routen und Abfrageparameter.



