Didacticiel : création d’une API REST avec une intégration Lambda sans proxy
Dans cette présentation, nous utilisons la console API Gateway pour créer une API qui permet à un client d’appeler des fonctions Lambda via l’intégration Lambda autre que de proxy (également désignée sous le nom d’intégration personnalisée). Pour en savoir plus sur AWS Lambda et les fonctions Lambda, consultez le Guide du développeur AWS Lambda.
Pour faciliter l’apprentissage, nous avons choisi une fonction Lambda simple avec une configuration d’API minimale pour vous guider à travers les étapes de création d’une API Amazon API Gateway avec l’intégration personnalisée Lambda. Lorsque nécessaire, nous décrivons un aspect de la logique. Pour un exemple plus détaillé de l’intégration personnalisée Lambda, consultez Didacticiel : création d’une API REST de calculatrice avec deux intégrations de service AWS et une intégration Lambda sans proxy.
Avant de créer l’API, configurez le backend Lambda en créant une fonction Lambda dans AWS Lambda, comme décrit ci-après.
Rubriques
Création d’une fonction Lambda pour l’intégration Lambda autre que de proxy
Note
La création de fonctions Lambda peut entraîner des frais sur votre compte AWS.
Au cours de cette étape, vous allez créer une fonction Lambda de type « Hello, World ! » pour l’intégration Lambda personnalisée. Tout au long de cette procédure, la fonction est appelée GetStartedLambdaIntegration
.
La mise en œuvre de cette fonction Lambda GetStartedLambdaIntegration
est la suivante :
Pour l’intégration personnalisée Lambda, API Gateway transmet les entrées à la fonction Lambda depuis le client en tant que corps de la demande d’intégration. L’objet event
du gestionnaire de la fonction Lambda correspond à l’entrée.
Notre fonction Lambda est simple. Elle analyse l’objet event
en entrée par rapport aux propriétés name
, city
, time
et day
. Elle renvoie ensuite un message d’accueil, en tant qu’objet JSON {"message":greeting}
, à l’appelant. Le message suit le modèle "Good
[morning|afternoon|day], [
. Il est supposé que l’entrée de la fonction Lambda est l’objet JSON suivant : name
|you] in
[city
|World]. Happy
day
!"
{ "city": "...", "time": "...", "day": "...", "name" : "..." }
Pour plus d’informations, consultez le Manuel du développeur AWS Lambda.
En outre, la fonction enregistre son exécution sur Amazon CloudWatch en appelant console.log(...)
. Cet aspect est précieux pour suivre les appels lors du débogage de la fonction. Pour permettre à la fonction GetStartedLambdaIntegration
d’enregistrer l’appel, définissez un rôle IAM avec les politiques appropriées pour que la fonction Lambda puisse créer les flux CloudWatch et ajouter des entrées de journal aux flux. La console Lambda vous guide tout au long de la création des rôles et politiques IAM requis.
Si vous configurez l’API sans utiliser la console API Gateway, par exemple en important une API depuis un fichier OpenAPI
Par rapport à GetStartedLambdaProxyIntegration
, la fonction Lambda pour l’intégration de proxy Lambda, la fonction GetStartedLambdaIntegration
Lambda pour l’intégration personnalisée Lambda prend uniquement les entrées du corps de la requête d’intégration d’API Amazon API Gateway. La fonction peut renvoyer une sortie sous forme d’un objet JSON, d’une chaîne, d’un nombre, d’une valeur booléenne ou même d’un blob binaire. La fonction Lambda de l’intégration de proxy Lambda, en revanche, peut accepter les entrées de toutes données de la demande, mais doit renvoyer en sortie un objet JSON particulier. La fonction GetStartedLambdaIntegration
pour l’intégration personnalisée Lambda peut avoir comme entrées les paramètres de la demande d’API, à condition qu’API Gateway mappe les paramètres de la demande d’API au corps de demande d’intégration avant de transférer la demande du client au backend. Pour que cela se produise, le développeur de l’API doit créer un modèle de mappage et le configurer sur la méthode de l’API lors de la création de l’API.
Maintenant, créez la fonction Lambda GetStartedLambdaIntegration
.
Pour créer la fonction Lambda GetStartedLambdaIntegration
pour l’intégration personnalisée Lambda
Ouvrez la console AWS Lambda à l’adresse https://console.aws.amazon.com/lambda/
. -
Effectuez l’une des actions suivantes :
-
Si la page de bienvenue s’affiche, choisissez Get Started Now (Commencer maintenant) puis Create function (Créer une fonction).
-
Si la liste Lambda > Functions (Fonctions) apparaît, choisissez Create function (Créer une fonction).
-
-
Choisissez Créer à partir de zéro.
-
Dans le volet Author from scratch (Créer à partir de zéro), procédez comme suit :
-
Dans Name (Nom), entrez
GetStartedLambdaIntegration
comme nom de la fonction Lambda. -
Pour Exécution, choisissez le dernier environnement d’exécution Node.js ou Python compatible.
Pour Architecture, conservez le paramètre par défaut.
-
Sous Permissions (Autorisations), développez Change default execution role (Modifier le rôle d’exécution par défaut). Dans la liste déroulante Rôle d’exécution, choisissez Créer un nouveau rôle à partir de modèles de politique AWS.
-
Pour Role name (Nom du rôle), indiquez le nom de votre rôle, par exemple
GetStartedLambdaIntegrationRole
. -
Pour Policy templates (Modèles de politique), choisissez Simple microservice permissions (Autorisations Microservice simples).
-
Sélectionnez Create function (Créer une fonction).
-
-
Dans le volet Configure function (Configurer la fonction), sous Function code (Code de la fonction), suivez les étapes suivantes :
-
Copiez le code de la fonction Lambda affiché au début de cette section et collez-le dans l’éditeur de code en ligne.
-
Acceptez les choix par défaut pour tous les autres champs de cette section.
-
Choisissez Deploy (Déployer).
-
-
Pour tester la fonction nouvellement créée, cliquez sur l’onglet Test.
-
Dans Event name (Nom de l’événement), saisissez
HelloWorldTest
. Pour JSON d’événement, remplacez le code par défaut par le code suivant.
{ "name": "Jonny", "city": "Seattle", "time": "morning", "day": "Wednesday" }
-
Sélectionnez Test pour appeler la fonction. La section Execution result: succeeded s’affiche. Développez Détails pour voir la sortie suivante.
{ "greeting": "Good morning, Jonny of Seattle. Happy Wednesday!" }
La sortie est également écrite dans CloudWatch Logs.
-
À titre d’exercice, vous pouvez utiliser la console IAM pour afficher le rôle IAM (GetStartedLambdaIntegrationRole
) créé dans le cadre de la création de la fonction Lambda. Deux politiques en ligne sont attachées à ce rôle IAM. L’une stipule les autorisations les plus élémentaires pour l’exécution Lambda. Cela permet d’appeler CloudWatch CreateLogGroup
pour toutes les ressources CloudWatch de votre compte dans la région où la fonction Lambda est créée. Cette politique permet également la création de flux CloudWatch et la journalisation des événements de la fonction Lambda GetStartedLambdaIntegration
.
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "logs:CreateLogGroup", "Resource": "arn:aws:logs:
region
:account-id
:*" }, { "Effect": "Allow", "Action": [ "logs:CreateLogStream", "logs:PutLogEvents" ], "Resource": [ "arn:aws:logs:region
:account-id
:log-group:/aws/lambda/GetStartedLambdaIntegration:*" ] } ] }
L’autre document de politique s’applique à l’appel d’un autre service AWS qui n’est pas utilisé dans cet exemple. Vous pouvez l’ignorer pour l’instant.
Associée au rôle IAM se trouve une entité de confiance, qui est lambda.amazonaws.com
. Voici la relation d’approbation :
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "lambda.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
La combinaison de cette relation d’approbation et de la politique en ligne permet à la fonction Lambda d’appeler une fonction console.log()
pour enregistrer les événements sur CloudWatch Logs.
Création d’une API avec l’intégration Lambda autre que de proxy
Avec la fonction Lambda (GetStartedLambdaIntegration
) créée et testée, vous êtes prêt à exposer la fonction via une API Amazon API Gateway. À des fins d’illustration, nous exposons la fonction Lambda avec une méthode HTTP générique. Nous utilisons le corps de la demande, une variable de chemin d’URL, une chaîne de requête et un en-tête pour recevoir les données d’entrée requises du client. Nous activons le validateur de demande API Gateway pour l’API afin de garantir que toutes les données requises sont correctement définies et spécifiées. Nous configurons un modèle de mappage pour qu’API Gateway transforme les données de la demande fournie par le client au format valide comme requis par la fonction Lambda du backend.
Pour créer une API avec une intégration Lambda autre que de proxy
-
Connectez-vous à la console API Gateway à l’adresse https://console.aws.amazon.com/apigateway
. -
Si vous utilisez API Gateway pour la première fois, vous voyez une page qui vous présente les fonctions du service. Sous REST API (API REST), choisissez Build (Création). Lorsque la fenêtre contextuelle Create Example API (Créer API exemple) s’affiche, cliquez sur OK.
Si ce n’est pas la première fois que vous utilisez API Gateway, choisissez Create API (Créer une API). Sous REST API (API REST), choisissez Build (Création).
Sous API name (Nom de l’API), saisissez
LambdaNonProxyAPI
.(Facultatif) Sous Description, entrez une description.
Laissez Type de point de terminaison d’API défini sur Régional.
Sélectionnez Create API (Créer une API).
Après avoir créé votre API, vous créez une ressource /{city}. Ceci est un exemple de ressource avec une variable de chemin qui accepte une entrée du client. Par la suite, vous mapperez cette variable de chemin avec l’entrée de la fonction Lambda à l’aide d’un modèle de mappage.
Pour créer une ressource
Choisissez Créer une ressource.
Maintenez Ressource proxy désactivée.
Conservez Chemin de la ressource sous la forme
/
.Sous Resource Name (Nom de la ressource), entrez
{city}
.Maintenez CORS (Partage des ressources entre origines multiples) désactivé.
Choisissez Créer une ressource.
Après avoir créé votre ressource /{city}, vous créez une méthode ANY
. Le verbe HTTP ANY
est un espace réservé pour une méthode HTTP valide qu’un client soumet au moment de l’exécution. Cet exemple montre que la méthode ANY
peut être utilisée pour l’intégration personnalisée Lambda aussi bien que pour l’intégration de proxy Lambda.
Pour créer une méthode ANY
Sélectionnez la ressource /{city}, puis choisissez Créer une méthode.
Pour Type de méthode, sélectionnez ANY.
Pour Type d’intégration, sélectionnez Fonction Lambda.
Maintenez Intégration proxy Lambda désactivée.
Pour Fonction Lambda, sélectionnez la Région AWS où vous avez créé votre fonction Lambda, puis entrez le nom de la fonction.
Choisissez Paramètres de requête de méthode.
À présent, vous allez activer un valideur de requête pour une variable de chemin d’URL, un paramètre de chaîne de requête et un en-tête afin de vous assurer que toutes les données requises sont définies. Dans cet exemple, vous créez un paramètre de chaîne de requête
time
et un en-têteday
.Pour Validateur de requête, sélectionnez Valider les paramètres de chaîne de requête et les en-têtes.
Choisissez Paramètres de chaîne de requête d’URL et procédez comme suit :
Sélectionnez Add query string (Ajouter une chaîne de requêtes).
Pour Nom, saisissez
time
.Activez Obligatoire.
Maintenez Mise en cache désactivée.
Choisissez En-têtes de requête HTTP et procédez comme suit :
Sélectionnez Add header.
Pour Nom, saisissez
day
.Activez Obligatoire.
Maintenez Mise en cache désactivée.
Choisissez Créer une méthode.
Après avoir activé un validateur de requête, vous configurez la requête d’intégration pour la méthode ANY
en ajoutant un modèle de mappage corporel pour transformer la requête entrante en une charge utile JSON, comme l’exige la fonction Lambda du backend.
Pour configurer la requête d’intégration
Dans l’onglet Requête d’intégration, sous Paramètres de requête d’intégration, choisissez Modifier.
Pour Transmission du corps de requête, sélectionnez Lorsqu’aucun modèle n’est défini (recommandé).
Choisissez Modèles de mappage.
Sélectionnez Add mapping template.
Pour Type de contenu, entrez
application/json
.Pour Corps du modèle, entrez le code suivant :
#set($inputRoot = $input.path('$')) { "city": "$input.params('city')", "time": "$input.params('time')", "day": "$input.params('day')", "name": "$inputRoot.callerName" }
Choisissez Enregistrer.
Test de l’appel de la méthode d’API
La console API Gateway fournit une installation de test qui vous permet de tester l’appel de l’API avant qu’elle ne soit déployée. Vous utilisez la fonctionnalité Test de la console pour tester l’API en soumettant la demande suivante :
POST /Seattle?time=morning day:Wednesday { "callerName": "John" }
Dans cette demande de test, vous allez définir ANY
sur POST
et {city}
sur Seattle
, attribuer Wednesday
comme valeur de l’en-tête day
et attribuer "John"
comme valeur de callerName
.
Pour tester la méthode ANY
-
Choisissez l’onglet Test. Vous devrez peut-être choisir la flèche droite pour afficher l’onglet.
-
Pour Type de méthode, sélectionnez
POST
. -
Pour Chemin, sous city, entrez
Seattle
. -
Pour Chaînes de requête, saisissez
time=morning
. -
Pour En-têtes, saisissez
day:Wednesday
. -
Pour Corps de la requête, saisissez
{ "callerName": "John" }
. -
Sélectionnez Test (Tester).
Vérifiez que la charge utile de la réponse retournée se présente comme suit :
{ "greeting": "Good morning, John of Seattle. Happy Wednesday!" }
Vous pouvez également consulter les journaux pour examiner comment API Gateway traite la demande et la réponse.
Execution log for request test-request Thu Aug 31 01:07:25 UTC 2017 : Starting execution for request: test-invoke-request Thu Aug 31 01:07:25 UTC 2017 : HTTP Method: POST, Resource Path: /Seattle Thu Aug 31 01:07:25 UTC 2017 : Method request path: {city=Seattle} Thu Aug 31 01:07:25 UTC 2017 : Method request query string: {time=morning} Thu Aug 31 01:07:25 UTC 2017 : Method request headers: {day=Wednesday} Thu Aug 31 01:07:25 UTC 2017 : Method request body before transformations: { "callerName": "John" } Thu Aug 31 01:07:25 UTC 2017 : Request validation succeeded for content type application/json Thu Aug 31 01:07:25 UTC 2017 : Endpoint request URI: https://lambda.us-west-2.amazonaws.com/2015-03-31/functions/arn:aws:lambda:us-west-2:123456789012:function:GetStartedLambdaIntegration/invocations Thu Aug 31 01:07:25 UTC 2017 : Endpoint request headers: {x-amzn-lambda-integration-tag=test-request, Authorization=****************************************************************************************************************************************************************************************************************************************************************************************************************************************338c72, X-Amz-Date=20170831T010725Z, x-amzn-apigateway-api-id=beags1mnid, X-Amz-Source-Arn=arn:aws:execute-api:us-west-2:123456789012:beags1mnid/null/POST/{city}, Accept=application/json, User-Agent=AmazonAPIGateway_beags1mnid, X-Amz-Security-Token=FQoDYXdzELL//////////wEaDMHGzEdEOT/VvGhabiK3AzgKrJw+3zLqJZG4PhOq12K6W21+QotY2rrZyOzqhLoiuRg3CAYNQ2eqgL5D54+63ey9bIdtwHGoyBdq8ecWxJK/YUnT2Rau0L9HCG5p7FC05h3IvwlFfvcidQNXeYvsKJTLXI05/yEnY3ttIAnpNYLOezD9Es8rBfyruHfJfOqextKlsC8DymCcqlGkig8qLKcZ0hWJWVwiPJiFgL7laabXs++ZhCa4hdZo4iqlG729DE4gaV1mJVdoAagIUwLMo+y4NxFDu0r7I0/EO5nYcCrppGVVBYiGk7H4T6sXuhTkbNNqVmXtV3ch5bOlh7 [TRUNCATED] Thu Aug 31 01:07:25 UTC 2017 : Endpoint request body after transformations: { "city": "Seattle", "time": "morning", "day": "Wednesday", "name" : "John" } Thu Aug 31 01:07:25 UTC 2017 : Sending request to https://lambda.us-west-2.amazonaws.com/2015-03-31/functions/arn:aws:lambda:us-west-2:123456789012:function:GetStartedLambdaIntegration/invocations Thu Aug 31 01:07:25 UTC 2017 : Received response. Integration latency: 328 ms Thu Aug 31 01:07:25 UTC 2017 : Endpoint response body before transformations: {"greeting":"Good morning, John of Seattle. Happy Wednesday!"} Thu Aug 31 01:07:25 UTC 2017 : Endpoint response headers: {x-amzn-Remapped-Content-Length=0, x-amzn-RequestId=c0475a28-8de8-11e7-8d3f-4183da788f0f, Connection=keep-alive, Content-Length=62, Date=Thu, 31 Aug 2017 01:07:25 GMT, X-Amzn-Trace-Id=root=1-59a7614d-373151b01b0713127e646635;sampled=0, Content-Type=application/json} Thu Aug 31 01:07:25 UTC 2017 : Method response body after transformations: {"greeting":"Good morning, John of Seattle. Happy Wednesday!"} Thu Aug 31 01:07:25 UTC 2017 : Method response headers: {X-Amzn-Trace-Id=sampled=0;root=1-59a7614d-373151b01b0713127e646635, Content-Type=application/json} Thu Aug 31 01:07:25 UTC 2017 : Successfully completed execution Thu Aug 31 01:07:25 UTC 2017 : Method completed with status: 200
Les journaux présentent la demande entrante avant le mappage et la demande d’intégration après le mappage. Lorsqu’un test échoue, les journaux sont utiles pour évaluer si l’entrée d’origine est correcte ou si le modèle de mappage fonctionne correctement.
Déploiement de l’API
L’appel du test est une simulation et possède ses limites. Par exemple, il contourne tout mécanisme d’autorisation activé sur l’API. Pour tester l’exécution de l’API en temps réel, vous devez d’abord déployer l’API. Pour déployer une API, vous créez une phase afin de créer un instantané de l’API à ce moment-là. Le nom de la phase définit également le chemin de base après le nom d’hôte par défaut de l’API. La ressource racine de l’API est ajoutée après le nom de la phase. Lorsque vous modifiez l’API, vous devez la redéployer vers une phase nouvelle ou existante pour que les modifications prennent effet.
Pour déployer l’API sur une phase
Sélectionnez Deploy API (Déployer une API).
Pour Étape, sélectionnez Nouvelle étape.
Sous Stage name (Nom de l’étape), entrez
test
.Note
L’entrée doit être du texte codé en UTF-8 (par exemple, non localisé).
(Facultatif) Sous Description, entrez une description.
Choisissez Deploy (Déployer).
Sous Détails de l’étape, choisissez l’icône de copie pour copier l’URL d’invocation de votre API. Le modèle général de l’URL de base de l’API est https://
. Par exemple, l’URL de base de l’API (api-id
.region
.amazonaws.com/stageName
beags1mnid
) créée dans la région us-west-2
et déployée sur la phase test
est https://beags1mnid.execute-api.us-west-2.amazonaws.com/test
.
Test de l’API dans une phase de déploiement
Il existe plusieurs façons de tester une API déployée. Pour les requêtes GET n’utilisant que les variables de chemin d’URL ou les paramètres de chaîne de requête, vous pouvez saisir l’URL de la ressource d’API dans un navigateur. Pour les autres méthodes, vous devez utiliser les utilitaires de test plus avancés de l’API REST, tels que POSTMAN
Pour tester l’API à l’aide de cURL
-
Ouvrez une fenêtre de terminal sur votre ordinateur local connecté à Internet.
-
Pour tester
POST /Seattle?time=evening
:Copiez la commande cURL suivante et collez-la dans la fenêtre du terminal.
curl -v -X POST \ 'https://beags1mnid.execute-api.us-west-2.amazonaws.com/test/Seattle?time=evening' \ -H 'content-type: application/json' \ -H 'day: Thursday' \ -H 'x-amz-docs-region: us-west-2' \ -d '{ "callerName": "John" }'
Vous devriez obtenir une réponse positive avec la charge utile suivante :
{"greeting":"Good evening, John of Seattle. Happy Thursday!"}
Si vous modifiez
POST
enPUT
dans la demande de cette méthode, vous obtenez la même réponse.
Nettoyage
Si vous n’avez plus besoin des fonctions Lambda que vous avez créées pour cette procédure, vous pouvez maintenant les supprimer. Vous pouvez également supprimer les ressources IAM associées.
Avertissement
Si vous avez l’intention d’effectuer les autres procédures de cette série, ne supprimez pas le rôle d’exécution Lambda, ni le rôle d’appel Lambda. Si vous supprimez une fonction Lambda sur laquelle vos API reposent, ces API ne fonctionneront plus. La suppression d’une fonction Lambda ne peut pas être annulée. Si vous souhaitez utiliser à nouveau cette fonction Lambda, vous devez la recréer.
Si vous supprimez une ressource IAM sur laquelle repose une fonction Lambda, cette fonction Lambda et les API reposant sur elle ne fonctionneront plus. La suppression d’une ressource IAM ne peut pas être annulée. Si vous souhaitez utiliser à nouveau cette ressource IAM, vous devez la recréer.
Pour supprimer la fonction Lambda
Connectez-vous à la AWS Management Console et ouvrez la console AWS Lambda à l’adresse https://console.aws.amazon.com/lambda/
. -
Dans la liste de fonctions, choisissez GetStartedLambdaIntegration, Actions, puis Supprimer la fonction. A l’invite, sélectionnez à nouveau Delete.
Pour supprimer les ressources IAM associées
Ouvrez la console IAM à l’adresse https://console.aws.amazon.com/iam/
. -
Dans le volet Details, sélectionnez Roles.
-
Dans la liste des rôles, choisissez GetStartedLambdaIntegrationRole, Actions du rôle, puis Supprimer le rôle. Suivez les étapes de la console pour supprimer le rôle.