Didacticiel : création d'une API CRUD avec Lambda et DynamoDB - Amazon API Gateway

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Didacticiel : création d'une API CRUD avec Lambda et DynamoDB

Dans ce didacticiel, vous créez une API serverless qui crée, lit, met à jour et supprime des éléments d'une table DynamoDB. DynamoDB est un service de base de données NoSQL entièrement géré offrant des performances rapides et prévisibles avec une scalabilité simple. Ce tutoriel dure environ 30 minutes, et vous pouvez le suivre dans l'offre gratuite AWS.

Tout d'abord, vous créez une table DynamoDB à l'aide de la console DynamoDB. Vous créez ensuite une fonction Lambda à l'aide de la AWS Lambda console. Ensuite, vous créez une API HTTP à l'aide de la console API Gateway. Enfin, vous testez votre API.

Lorsque vous appelez votre API HTTP, API Gateway achemine la requête vers votre fonction Lambda. La fonction Lambda interagit avec DynamoDB et renvoie une réponse à API Gateway. API Gateway vous renvoie ensuite une réponse.

Présentation de l'API HTTP que vous créez dans ce didacticiel.

Pour effectuer cet exercice, vous avez besoin d'un AWS compte et d'un AWS Identity and Access Management utilisateur disposant d'un accès à la console. Pour plus d’informations, consultez Prérequis pour démarrer avec API Gateway.

Dans ce tutoriel, vous utiliserez l AWS Management Console. Pour un AWS SAM modèle qui crée cette API et toutes les ressources associées, consultez template.yaml.

Étape 1 : création d'une table DynamoDB

Vous utilisez une table DynamoDB afin de stocker les données de votre API.

Chaque élément a un ID unique, que nous utilisons en tant que clé de partition pour la table.

Pour créer une table DynamoDB
  1. Ouvrez la console DynamoDB à l'adresse https://console.aws.amazon.com/dynamodb/.

  2. Choisissez Create table (Créer une table).

  3. Sous Table name (Nom de la table), saisissez http-crud-tutorial-items.

  4. Pour Clé de partition, saisissez id.

  5. Choisissez Créer un tableau.

Étape 2 : création d'une fonction Lambda

Vous utilisez une fonction Lambda pour le backend de votre API. Cette fonction Lambda crée, lit, met à jour et supprime des éléments de DynamoDB. La fonction utilise des événements d'API Gateway afin de déterminer l'interaction avec DynamoDB. Pour plus de simplicité, ce didacticiel utilise une seule fonction Lambda. Il est recommandé de créer des fonctions distinctes pour chaque route.

Pour créer une fonction Lambda
  1. Connectez-vous à la console Lambda à l'adresse https://console.aws.amazon.com/lambda/.

  2. Choisissez Créer une fonction.

  3. Sous Function name (Nom de la fonction), saisissez http-crud-tutorial-function.

  4. Pour Exécution, choisissez le dernier environnement d’exécution Node.js ou Python compatible.

  5. Sous Permissions (Autorisations), choisissez Change default execution role (Modifier le rôle d'exécution par défaut).

  6. Sélectionnez Créer un nouveau rôle à partir de modèles de AWS politique.

  7. Sous Role name (Nom du rôle), saisissez http-crud-tutorial-role.

  8. Sous Policy templates (Modèles de stratégie), choisissez Simple microservice permissions. Cette stratégie accorde à la fonction Lambda l'autorisation d'interagir avec DynamoDB.

    Note

    Ce didacticiel utilise une stratégie gérée pour plus de simplicité. Il est recommandé de créer votre propre stratégie IAM afin d'accorder les autorisations minimales requises.

  9. Choisissez Créer une fonction.

  10. Ouvrez la fonction Lambda dans l'éditeur de code de la console et remplacez son contenu par le code suivant. Choisissez Deploy (Déployer) afin de mettre à jour votre fonction.

Node.js
import { DynamoDBClient } from "@aws-sdk/client-dynamodb"; import { DynamoDBDocumentClient, ScanCommand, PutCommand, GetCommand, DeleteCommand, } from "@aws-sdk/lib-dynamodb"; const client = new DynamoDBClient({}); const dynamo = DynamoDBDocumentClient.from(client); const tableName = "http-crud-tutorial-items"; export const handler = async (event, context) => { let body; let statusCode = 200; const headers = { "Content-Type": "application/json", }; try { switch (event.routeKey) { case "DELETE /items/{id}": await dynamo.send( new DeleteCommand({ TableName: tableName, Key: { id: event.pathParameters.id, }, }) ); body = `Deleted item ${event.pathParameters.id}`; break; case "GET /items/{id}": body = await dynamo.send( new GetCommand({ TableName: tableName, Key: { id: event.pathParameters.id, }, }) ); body = body.Item; break; case "GET /items": body = await dynamo.send( new ScanCommand({ TableName: tableName }) ); body = body.Items; break; case "PUT /items": let requestJSON = JSON.parse(event.body); await dynamo.send( new PutCommand({ TableName: tableName, Item: { id: requestJSON.id, price: requestJSON.price, name: requestJSON.name, }, }) ); body = `Put item ${requestJSON.id}`; break; default: throw new Error(`Unsupported route: "${event.routeKey}"`); } } catch (err) { statusCode = 400; body = err.message; } finally { body = JSON.stringify(body); } return { statusCode, body, headers, }; };
Python
import json import boto3 from decimal import Decimal client = boto3.client('dynamodb') dynamodb = boto3.resource("dynamodb") table = dynamodb.Table('http-crud-tutorial-items') tableName = 'http-crud-tutorial-items' def lambda_handler(event, context): print(event) body = {} statusCode = 200 headers = { "Content-Type": "application/json" } try: if event['routeKey'] == "DELETE /items/{id}": table.delete_item( Key={'id': event['pathParameters']['id']}) body = 'Deleted item ' + event['pathParameters']['id'] elif event['routeKey'] == "GET /items/{id}": body = table.get_item( Key={'id': event['pathParameters']['id']}) body = body["Item"] responseBody = [ {'price': float(body['price']), 'id': body['id'], 'name': body['name']}] body = responseBody elif event['routeKey'] == "GET /items": body = table.scan() body = body["Items"] print("ITEMS----") print(body) responseBody = [] for items in body: responseItems = [ {'price': float(items['price']), 'id': items['id'], 'name': items['name']}] responseBody.append(responseItems) body = responseBody elif event['routeKey'] == "PUT /items": requestJSON = json.loads(event['body']) table.put_item( Item={ 'id': requestJSON['id'], 'price': Decimal(str(requestJSON['price'])), 'name': requestJSON['name'] }) body = 'Put item ' + requestJSON['id'] except KeyError: statusCode = 400 body = 'Unsupported route: ' + event['routeKey'] body = json.dumps(body) res = { "statusCode": statusCode, "headers": { "Content-Type": "application/json" }, "body": body } return res

Étape 3 : création d'une API HTTP

L'API HTTP fournit un point de terminaison HTTP pour votre fonction Lambda. Au cours de cette étape, vous créez une API vide. Dans les étapes suivantes, vous configurez des itinéraires et des intégrations afin de connecter votre API et votre fonction Lambda.

Pour créer une API HTTP
  1. Connectez-vous à la console API Gateway à l'adresse https://console.aws.amazon.com/apigateway.

  2. Choisissez Create API (Créer une API). Ensuite, sous HTTP API (API HTTP), choisissez Build (Créer).

  3. Sous API name (Nom de l'API), saisissez http-crud-tutorial-api.

  4. Choisissez Suivant.

  5. Sous Configure routes (Configurer les itinéraires), choisissez Next (Suivant) afin d'ignorer la création d'itinéraires. Vous créerez des itinéraires ultérieurement.

  6. Consultez l'étape créée par API Gateway pour vous, puis choisissez Next (Suivant).

  7. Choisissez Créer.

Étape 4 : création d'itinéraires

Les itinéraires permettent d'envoyer les demandes d'API entrantes aux ressources backend. Les itinéraires se composent de deux parties : une méthode HTTP et un chemin de ressource (par exemple,, GET /items. Pour cet exemple d'API, nous créons quatre itinéraires :

  • GET /items/{id}

  • GET /items

  • PUT /items

  • DELETE /items/{id}

Pour créer des itinéraires
  1. Connectez-vous à la console API Gateway à l'adresse https://console.aws.amazon.com/apigateway.

  2. Choisissez votre API.

  3. Choisissez Itinéraires.

  4. Choisissez Créer.

  5. Pour Méthode, choisissez GET.

  6. Pour le chemin, saisissez /items/{id}. Le {id} à la fin du chemin est un paramètre de chemin d'accès qu'API Gateway extrait du chemin d'accès de la demande lorsqu'un client effectue une demande.

  7. Choisissez Créer.

  8. Répétez les étapes 4 à 7 pour GET /items, DELETE /items/{id} et PUT /items.

Votre API dispose d'itinéraires pour GET /items, GET /items/{id}, DELETE /items/{id} et PUT /items.

Étape 5 : création d'une intégration

Vous créez une intégration afin de connecter un itinéraire aux ressources backend. Pour cet exemple d'API, vous créez une intégration Lambda que vous utilisez pour tous les itinéraires.

Pour créer une intégration
  1. Connectez-vous à la console API Gateway à l'adresse https://console.aws.amazon.com/apigateway.

  2. Choisissez votre API.

  3. Choisissez Integrations (Intégrations).

  4. Choisissez Manage integrations (Gérer les intégrations), puis Create (Créer).

  5. Ignorez Attach this integration to a route (Attacher cette intégration à un itinéraire). Vous vous en occuperez ultérieurement.

  6. Sous Integration type (Type d'intégration), choisissez Lambda function (Fonction Lambda).

  7. Sous Lambda function (Fonction Lambda), saisissez http-crud-tutorial-function.

  8. Choisissez Créer.

Étape 6 : attachement de votre intégration aux itinéraires

Pour cet exemple d'API, vous utilisez la même intégration Lambda pour tous les itinéraires. Après que l'intégration a été attachée à l'ensemble des itinéraires de l'API, votre fonction Lambda est appelée lorsqu'un client appelle l'un de vos itinéraires.

Pour attacher des intégrations à des itinéraires
  1. Connectez-vous à la console API Gateway à l'adresse https://console.aws.amazon.com/apigateway.

  2. Choisissez votre API.

  3. Choisissez Integrations (Intégrations).

  4. Choisissez un itinéraire.

  5. Sous Choose an existing integration (Choisir une intégration existante), choisissez http-crud-tutorial-function.

  6. Choisissez Attach integration (Attacher l'intégration).

  7. Répétez les étapes 4 à 6 pour tous les itinéraires.

Tous les itinéraires indiquent qu'une AWS Lambda intégration est attachée.

La console s'affiche AWS Lambda sur tous les itinéraires pour indiquer que votre intégration est attachée.

Maintenant que vous disposez d'une API HTTP avec des itinéraires et des intégrations, vous pouvez tester votre API.

Étape 7 : test de votre API

Afin de vous assurer que votre API fonctionne, vous utilisez curl.

Pour obtenir l'URL pour appeler votre API
  1. Connectez-vous à la console API Gateway à l'adresse https://console.aws.amazon.com/apigateway.

  2. Choisissez votre API.

  3. Notez l'URL d'appel de votre API. Elle apparaît sous Invoke URL (Appeler l'URL) sur la page Details (Détails).

    Une fois que vous avez créé votre API, la console affiche l'URL d'appel de votre API.
  4. Copiez l'URL d'appel de votre API.

    L'URL complète se présente sous la forme https://abcdef123.execute-api.us-west-2.amazonaws.com.

Pour créer ou mettre à jour un élément
  • Utilisez la commande suivante afin de créer ou de mettre à jour un élément. La commande inclut un corps de demande et l'ID, le prix et le nom de l'élément.

    curl -X "PUT" -H "Content-Type: application/json" -d "{\"id\": \"123\", \"price\": 12345, \"name\": \"myitem\"}" https://abcdef123.execute-api.us-west-2.amazonaws.com/items
Pour obtenir tous les éléments
  • Utilisez la commande suivante afin de répertorier tous les éléments.

    curl https://abcdef123.execute-api.us-west-2.amazonaws.com/items
Pour obtenir un élément
  • Utilisez la commande suivante afin d'obtenir un élément par son ID.

    curl https://abcdef123.execute-api.us-west-2.amazonaws.com/items/123
Pour supprimer un article
  1. Utilisez la commande suivante afin de supprimer un élément.

    curl -X "DELETE" https://abcdef123.execute-api.us-west-2.amazonaws.com/items/123
  2. Obtenez tous les éléments afin de vérifier que l'élément a été supprimé.

    curl https://abcdef123.execute-api.us-west-2.amazonaws.com/items

Étape 8 : Nettoyage

Pour éviter des coûts inutiles, supprimez les ressources que vous avez créées dans le cadre de cet exercice de démarrage. Les étapes suivantes suppriment votre API HTTP, votre fonction Lambda, ainsi que les ressources associées.

Pour supprimer une table DynamoDB
  1. Ouvrez la console DynamoDB à l'adresse https://console.aws.amazon.com/dynamodb/.

  2. Sélectionnez votre table.

  3. Choisissez Supprimer la table.

  4. Confirmez votre choix et choisissez Delete (Supprimer).

Pour supprimer une API HTTP
  1. Connectez-vous à la console API Gateway à l'adresse https://console.aws.amazon.com/apigateway.

  2. Sur la page APIs (API) , sélectionnez une API. Choisissez Actions, puis Supprimer.

  3. Sélectionnez Delete.

Pour supprimer une fonction Lambda
  1. Connectez-vous à la console Lambda à l'adresse https://console.aws.amazon.com/lambda/.

  2. Sur la page Functions (Fonctions), sélectionnez une fonction. Choisissez Actions, puis Supprimer.

  3. Sélectionnez Delete.

Pour supprimer le groupe de journaux d'une fonction Lambda
  1. Dans la CloudWatch console Amazon, ouvrez la page Log groups.

  2. Sur la page Log groups (Groupes de journaux), sélectionnez le groupe de journaux de la fonction (/aws/lambda/http-crud-tutorial-function). Choisissez Actions, puis Supprimer le groupe de journaux.

  3. Sélectionnez Delete.

Pour supprimer le rôle d'exécution d'une fonction Lambda
  1. Dans la AWS Identity and Access Management console, ouvrez la page Rôles.

  2. Sélectionnez le rôle de la fonction, par exempl, http-crud-tutorial-role.

  3. Choisissez Supprimer le rôle.

  4. Choisissez Oui, supprimer.

Prochaines étapes : Automatiser avec AWS SAM ou AWS CloudFormation

Vous pouvez automatiser la création et le nettoyage des AWS ressources en utilisant AWS CloudFormation ou AWS SAM. Afin d'obtenir un exemple de modèle AWS SAM pour ce tutoriel, veuillez consulter template.yaml.

Pour des exemples AWS CloudFormation de modèles, voir les exemples AWS CloudFormation de modèles.