Introduction
Une équipe de commandes doit accepter des commandes JSON et renvoyer des totaux calculés. Vous allez relier des routes de santé, d'écriture et de lecture à une application Lambda fournie, tester des requêtes valides et rejetées et vérifier les éléments DynamoDB stockés avant le nettoyage.
Terminez d'abord Exposer une fonction Lambda avec une API HTTP et Lire et écrire dans DynamoDB depuis Lambda. Ce nouvel environnement fournit l'application, le rôle et des tables distinctes.
Lien avec les certifications
| Certification | Tâche de l’examen | Pratique |
|---|---|---|
| Solutions Architect – Associate (SAA-C03) | Tâche 2.1 | Validation des requêtes API, réponses et données métier persistées. |
| Developer – Associate (DVA-C02) | Tâche 1.1, Tâche 3.2 | Validation des requêtes API, réponses et données métier persistées. |
| DevOps Engineer – Professional (DOP-C02) | Tâche 3.2 | Pratique des fondamentaux : Validation des requêtes API, réponses et données métier persistées. |
Vue d’ensemble du laboratoire

Préparer le backend des commandes
Dans cette étape, vous allez inspecter le contrat de requête fourni, autoriser la fonction à accéder à sa table de commandes et déployer le backend. L'application calcule en centimes entiers : quantité × 250 + 100 centimes de frais de traitement. Utilisez AWS View en haut pour comparer les requêtes aux données stockées.
Accédez à l'espace de travail et lisez l'application :
cd /home/labex/project
cat app.py
handler reçoit le format de charge utile HTTP 2.0. POST /orders attend exactement deux champs JSON : un id en minuscules de 2 à 40 caractères, commençant par une lettre et composé de lettres, chiffres ou traits d'union, ainsi qu'un entier quantity de 1 à 10. Le code rejette les autres formes avant PutItem. GET /orders?id=... lit l'enregistrement stocké avec GetItem. Chaque réponse contient un statut HTTP et un corps JSON. Vous n'avez pas à réécrire cette application fournie.
Lisez l'inventaire des tables préparées :
aws dynamodb list-tables --query TableNames
Attendez-vous à obtenir labex-a02-orders et labex-a02-reference. Seule la table de commandes appartient au travail métier de cette API. Lisez son ARN dans une variable du shell :
TABLE_ARN=$(aws dynamodb describe-table \
--table-name labex-a02-orders \
--query Table.TableArn \
--output text)
echo "$TABLE_ARN"
Le rôle d'exécution contrôle l'accès sortant à la base. Utilisez un heredoc pour créer un fichier de politique. Le marqueur JSON sans guillemets permet à $TABLE_ARN de se développer en l'ARN qui vient d'être lu ; il ne contient pas d'identifiants d'accès :
cat > orders-policy.json <<JSON
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": ["dynamodb:PutItem", "dynamodb:GetItem"],
"Resource": "$TABLE_ARN"
}]
}
JSON
Attachez cette politique intégrée nommée au rôle d'exécution préparé :
aws iam put-role-policy \
--role-name labex-a02-execution \
--policy-name OrdersData \
--policy-document file://orders-policy.json
Empaquetez le code fourni avec app.py à la racine de l'archive :
zip orders.zip app.py
Lisez l'ARN du rôle préparé :
ROLE_ARN=$(aws iam get-role \
--role-name labex-a02-execution \
--query Role.Arn \
--output text)
echo "$ROLE_ARN"
Déployez la fonction avec un délai maximal de dix secondes. L'application lit TABLE_NAME dans son environnement, en séparant le choix de table du code source :
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}'
Attendez-vous à obtenir le nom de fonction, app.handler et labex-a02-orders. Dans AWS View, inspectez la carte Function et confirmez que la table de commandes contient encore zéro élément. Déployer le code et accorder l'accès aux données ne crée pas de commande.
Relier les routes de santé et de commandes
Dans cette étape, vous allez configurer une intégration pour trois routes et accorder à chaque route la permission d'invoquer la fonction.
Créez une API HTTP et enregistrez son identifiant :
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
Créez le stage littéral $default avec déploiement automatique :
aws apigatewayv2 create-stage \
--api-id "$API_ID" \
--stage-name '$default' \
--auto-deploy \
--query '{Stage:StageName,AutoDeploy:AutoDeploy}'
Lisez l'ARN du backend et créez l'intégration payload 2.0. Sa méthode POST invoque Lambda ; chaque route cliente conserve sa propre méthode HTTP :
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"
Reliez le point de terminaison public de santé à cette intégration :
aws apigatewayv2 create-route \
--api-id "$API_ID" \
--route-key 'GET /health' \
--target "integrations/$INTEGRATION_ID" \
--authorization-type NONE \
--query RouteKey \
--output text
Reliez la route d'écriture JSON :
aws apigatewayv2 create-route \
--api-id "$API_ID" \
--route-key 'POST /orders' \
--target "integrations/$INTEGRATION_ID" \
--authorization-type NONE \
--query RouteKey \
--output text
Reliez la route de lecture des commandes stockées :
aws apigatewayv2 create-route \
--api-id "$API_ID" \
--route-key 'GET /orders' \
--target "integrations/$INTEGRATION_ID" \
--authorization-type NONE \
--query RouteKey \
--output text
La politique de base de données du rôle d'exécution ne permet pas à API Gateway d'invoquer la fonction. Lisez l'identifiant du compte, puis ajoutez trois autorisations d'invocation précises. Chaque instruction utilise l'identifiant d'API, le $default littéral, la méthode cliente et le chemin de route ; \$ conserve le signe dollar dans une chaîne développée par le shell :
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
Construisez l'adresse d'API préparée de l'espace de travail avec votre identifiant généré. Cette adresse traite les requêtes dans l'espace de travail et n'est pas un nom d'hôte public AWS :
API_URL="http://127.0.0.1:8081/api/$API_ID"
echo "$API_URL"
Testez la route de santé. curl -i inclut les en-têtes de réponse HTTP :
curl -i "$API_URL/health"
Attendez-vous à obtenir HTTP 200 et {"healthy": true}. Dans AWS View, confirmez que les trois clés de route ont NONE, que le stage a AutoDeploy activé et que l'invocation de santé a renvoyé 200. La table de commandes doit rester vide, car cette requête vérifie la santé au lieu de stocker une commande.

Tester les commandes valides et les requêtes rejetées
Dans cette étape, vous allez créer deux commandes, lire leurs résultats stockés et vérifier les échecs avant qu'ils puissent affecter les données métier.
Une requête HTTP comprend une méthode, un chemin, des en-têtes et un corps facultatif. -X POST choisit la méthode d'écriture, -H fournit Content-Type: application/json et --data envoie la chaîne JSON. Créez une commande avec une quantité de 2 :
curl -i -X POST "$API_URL/orders" -H 'Content-Type: application/json' --data '{"id":"order-one","quantity":2}'
Attendez-vous à obtenir HTTP 201 Created et un corps contenant order-one, la quantité 2 et total_cents: 600 (2 × 250 + 100). Le statut indique au client qu'une commande a été stockée ; le corps présente le résultat calculé.
Créez une deuxième commande avec une quantité différente :
curl -i -X POST "$API_URL/orders" -H 'Content-Type: application/json' --data '{"id":"order-two","quantity":5}'
Attendez-vous à obtenir HTTP 201 et total_cents: 1350. Lisez les deux commandes via l'API avec leur paramètre de requête :
curl -i "$API_URL/orders?id=order-one"
curl -i "$API_URL/orders?id=order-two"
Les deux réponses doivent être HTTP 200 avec les mêmes identifiant, quantité et total que la réponse de création correspondante. Le gestionnaire de lecture récupère l'état DynamoDB au lieu de recalculer le total à partir d'une nouvelle quantité cliente.
Inspectez indépendamment le premier élément stocké avec la CLI :
aws dynamodb get-item \
--table-name labex-a02-orders \
--key '{"id":{"S":"order-one"}}' \
--consistent-read \
--query Item
L'élément typé contient quantity: {"N":"2"} et total_cents: {"N":"600"}. Dans AWS View, comparez les deux enregistrements réels de la table avec les réponses d'invocation POST et GET.
Une requête JSON syntaxiquement valide peut néanmoins violer le contrat métier. Envoyez une quantité négative :
curl -i -X POST "$API_URL/orders" -H 'Content-Type: application/json' --data '{"id":"bad-negative","quantity":-1}'
Attendez-vous à obtenir HTTP 400 Bad Request et Use an id and an integer quantity from 1 to 10. Un nombre encodé comme chaîne JSON est aussi rejeté :
curl -i -X POST "$API_URL/orders" -H 'Content-Type: application/json' --data '{"id":"bad-type","quantity":"2"}'
Enfin, testez un corps JSON mal formé :
curl -i -X POST "$API_URL/orders" -H 'Content-Type: application/json' --data '{not-json'
Les deux dernières requêtes renvoient aussi HTTP 400. Leurs événements réels de gestionnaire peuvent apparaître dans CloudWatch Logs, mais la table doit toujours contenir uniquement les deux commandes valides. La validation des requêtes a lieu dans l'application fournie avant PutItem ; une route d'API correspondante ne valide pas à elle seule son corps.
Un identifiant de lecture valide peut ne correspondre à aucune commande stockée. Interrogez-en un qui n'a pas été créé :
curl -i "$API_URL/orders?id=missing-order"
Attendez-vous à obtenir HTTP 404 avec Order not found. Cela diffère d'une requête invalide 400 : l'identifiant a le format attendu, mais aucun élément n'existe. Observez AWS View en haut et inspectez les réponses réelles 201, 200, 400 et 404 ; développez Show logs d'une invocation pour comparer son entrée à son résultat. Cette inspection manuelle de l'interface complète les contrôles indépendants en lecture seule des enregistrements distants et des exécutions réelles.

Faites défiler jusqu'à la carte DynamoDB tables pour comparer ces champs dans votre environnement.
Ces réponses 400 testent la validation de l’application : la requête atteint Lambda, qui rejette les données avant l’écriture. Le rejet JWT étudié ensuite arrête la requête dans API Gateway avant Lambda. Comparez le journal d’exécution et les éléments stockés pour identifier la limite qui a rejeté la requête.
Retirer l'API et les ressources de commandes de l'exercice
Dans cette étape, vous allez supprimer les ressources de l'API en conservant la table de référence sans rapport, les journaux et le rôle d'exécution préparé.
Votre inventaire comprend l'identifiant d'API dans api-id.txt, labex-a02-orders-api, son groupe de journaux /aws/lambda/labex-a02-orders-api, labex-a02-orders et la politique intégrée du rôle OrdersData. Supprimez d'abord l'API, y compris ses routes, son intégration et son stage par défaut :
aws apigatewayv2 delete-api --api-id "$API_ID"
Retirez la fonction et sa politique d'invocation :
aws lambda delete-function --function-name labex-a02-orders-api
Supprimez le groupe de journaux distinct de la fonction :
aws logs delete-log-group --log-group-name /aws/lambda/labex-a02-orders-api
Supprimez la table de commandes de l'exercice et ses données :
aws dynamodb delete-table \
--table-name labex-a02-orders \
--query TableDescription.TableName \
--output text
Retirez uniquement la politique de données que vous avez ajoutée au rôle préparé :
aws iam delete-role-policy --role-name labex-a02-execution --policy-name OrdersData
Lisez les inventaires avec succès pour prouver la suppression. Des erreurs d'authentification ou de réseau ne sont pas des preuves de suppression :
aws apigatewayv2 get-apis --query 'Items[].Name'
aws lambda list-functions --query 'Functions[].FunctionName'
aws dynamodb list-tables --query TableNames
Les deux premières listes doivent être vides ; la liste des tables doit contenir uniquement labex-a02-reference. Confirmez que son élément d'origine subsiste :
aws dynamodb get-item \
--table-name labex-a02-reference \
--key '{"id":{"S":"reference"}}' \
--query Item
Attendez-vous à obtenir message: {"S":"keep unchanged"}. Le rôle doit toujours conserver sa politique de journalisation sans rapport :
aws iam list-role-policies --role-name labex-a02-execution --query PolicyNames
Attendez-vous à trouver uniquement FunctionLogs. Dans AWS View, les enregistrements API, Function et d'invocation doivent avoir disparu, tandis que la table de référence et INFO platform reference keep unchanged subsistent. Gardez ces ressources préparées ; les identifiants de test et l'arrêt de la VM sont pris en charge après les contrôles de ressources.
Résumé
Vous avez relié trois routes HTTP à une application Lambda fournie avec une politique précise de base de données et des autorisations d'invocation d'API. Vous avez créé et récupéré des commandes avec différents totaux calculés, vérifié les éléments DynamoDB réels et distingué les réponses réussies, invalides et de commandes absentes. Vous avez ensuite retiré l'API et ses données, sa fonction, ses journaux et sa politique de l'exercice en conservant les ressources de référence.
Pour approfondir ce sujet, consultez la documentation AWS : Événements Lambda des HTTP API et formats de réponse; Routes HTTP API et paramètres de requête.



