Exercise : Ajouter une logique à l’application de fonction
Reprenons notre exemple d’engrenage et ajoutons la logique au service de température. Plus précisément, nous allons recevoir les données d’une requête HTTP.
Conditions de la fonction
Tout d’abord, nous devons définir certaines conditions pour notre logique :
- Les températures comprises entre 0 et 25 degrés doivent être marquées avec OK.
- Les températures comprises entre 25 et 50 degrés doivent être marquées avec ATTENTION.
- Les températures supérieures à 50 degrés doivent indiquer DANGER.
Ajouter une fonction à votre application de fonction
Comme nous l’avons vu dans l’unité précédente, Azure fournit des modèles qui facilitent la génération de fonctions. Dans cette unité, vous utilisez le modèle HttpTrigger
pour implémenter le service de température.
Dans l’exercice précédent, vous avez déployé votre application de fonction et l’avez ouverte. Si elle n’est pas déjà ouverte, vous pouvez l’ouvrir à partir de la page d’accueil en sélectionnant Toutes les ressources, puis sélectionnez votre application de fonction dont le nom ressemble à escalator-functions-xxx.
Dans l’écran Application de fonction, sous l’onglet Fonctions, sélectionnez Créer dans le portail Azure. Le volet Créer une fonction s’affiche.
Sous Sélectionner un modèle, sélectionnez Déclencheur HTTP, puis Suivant.
Pour Nom de la fonction maintenez HttpTrigger1. En outre, conservez le Niveau d’autorisation Fonction, et enfin sélectionnez Créer. La fonction HttpTrigger1 est créée et s’affiche dans le volet Fonction HttpTrigger1.
Sélectionnez l’onglet Code + Test. L’éditeur de code s’ouvre et affiche le contenu du fichier de code index.js de votre fonction. Le code par défaut que le modèle HTTP a généré est montré dans l’extrait de code suivant.
module.exports = async function (context, req) { context.log('JavaScript HTTP trigger function processed a request.'); const name = (req.query.name || (req.body && req.body.name)); const responseMessage = name ? "Hello, " + name + ". This HTTP triggered function executed successfully." : "This HTTP triggered function executed successfully. Pass a name on the query string or in the request body for a personalized response."; context.res = { // status: 200, /* Defaults to 200 */ body: responseMessage }; }
Votre fonction s’attend à ce qu’un nom soit passé via la chaîne de requête HTTP ou dans le cadre du corps de la requête. La fonction répond en retournant le message Hello, <name>. Cette fonction déclenchée par HTTP s’est correctement exécutée., répétant ainsi le nom qui a été envoyé dans la demande.
Dans la liste déroulante de fichiers sources, sélectionnez function.json pour voir la configuration de la fonction, qui doit ressembler au code suivant.
{ "bindings": [ { "authLevel": "function", "type": "httpTrigger", "direction": "in", "name": "req", "methods": [ "get", "post" ] }, { "type": "http", "direction": "out", "name": "res" } ] }
Ce fichier de configuration déclare que la fonction s’exécute quand elle reçoit une requête HTTP. La liaison de sortie déclare que la réponse est envoyée comme réponse HTTP.
Dans la section Détails du modèle, dans le champ Nouvelle fonction, entrez DriveGearTemperatureService. Conservez le Niveau d’autorisation défini sur Fonction, puis sélectionnez Créer pour créer la fonction. Le volet Vue d’ensemble de votre fonction DriveGearTemperatureService s’affiche.
Dans le menu Fonction, sélectionnez Code + Test. L’éditeur de code s’ouvre avec le contenu du fichier de code run.ps1. Le code par défaut que le modèle a généré automatiquement est repris dans l’extrait de code suivant.
using namespace System.Net # Input bindings are passed in via param block. param($Request, $TriggerMetadata) # Write to the Azure Functions log stream. Write-Host "PowerShell HTTP trigger function processed a request." # Interact with query parameters or the body of the request. $name = $Request.Query.Name if (-not $name) { $name = $Request.Body.Name } $body = "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response." if ($name) { $body = "Hello, $name. This HTTP triggered function executed successfully." } # Associate values to output bindings by calling 'Push-OutputBinding'. Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ StatusCode = [HttpStatusCode]::OK Body = $body })
Notre fonction s’attend à ce qu’un nom soit transmis par le biais de la chaîne de requête HTTP ou en tant que partie intégrante du corps de la demande. Les fonctions HTTP doivent générer une réponse en écrivant dans leur liaison de sortie, qui est établie dans PowerShell Functions avec l’applet de commande
Push-OutputBinding
. Cette fonction retourne le message Hello $name, répétant ainsi le nom qui a été envoyé dans la demande.Dans la liste déroulante source, sélectionnez function.json pour afficher la configuration de la fonction, qui doit se présenter de la façon suivante.
{ "bindings": [ { "authLevel": "function", "type": "httpTrigger", "direction": "in", "name": "Request", "methods": [ "get", "post" ] }, { "type": "http", "direction": "out", "name": "Response" } ] }
Cette configuration déclare que la fonction s’exécute quand elle reçoit une requête HTTP. La liaison de sortie déclare que la réponse est envoyée comme réponse HTTP.
Tester la fonction
Conseil
cURL est un outil de ligne de commande qui permet d’envoyer ou de recevoir des fichiers. Il est intégré à Linux, macOS et Windows 10 et peut être téléchargé pour la plupart des autres systèmes d’exploitation. cURL prend en charge de nombreux protocoles comme HTTP, HTTPS, FTP, FTPS, SFTP, LDAP, TELNET, SMTP, POP3, etc. Pour plus d'informations, consultez les liens suivants :
Pour tester la fonction, vous pouvez envoyer une requête HTTP à l’URL de la fonction en utilisant cURL sur la ligne de commande.
Développez le cadre Journaux en bas du volet de la fonction de déclencheur. Sélectionnez Journaux du système de fichiers dans la liste déroulante en haut du cadre Journaux. Le cadre des journaux doit commencer à accumuler des notifications de trace toutes les minutes.
Pour rechercher l’URL de point de terminaison de la fonction, à partir de la barre de commandes, sélectionnez Obtenir l’URL de la fonction, comme illustré dans l’image suivante. Enregistrez ce lien en sélectionnant l’icône Copier dans le Presse-papiers à la fin de l’URL. Stockez ce lien dans le Bloc-notes ou dans une application similaire pour une utilisation ultérieure.
Ouvrez une invite de commandes et exécutez cURL pour envoyer une requête HTTP à l’URL de la fonction. N’oubliez pas d’utiliser l’URL que vous avez copiée à l’étape précédente.
curl "<your-https-url>"
Conseil
Vous devez placer l’URL entre guillemets pour éviter les problèmes liés aux caractères spéciaux dans l’URL.
Si vous êtes sur Windows, exécutezcURL
à partir de l’invite de commandes. PowerShell a une commande curl, mais il s’agit d’un alias pour Invoke-WebRequest, qui n’est pas identique àcURL
.La réponse doit ressembler à celle-ci :
This HTTP triggered function executed successfully. Pass a name on the query string or in the request body for a personalized response.
Passez maintenant un nom dans la requête. Pour ce faire, vous devez ajouter un paramètre de chaîne de requête nommé
name
à l’URL. L’exemple suivant ajoute le paramètre de chaîne de requêtename=Azure
.curl "<your-https-url>&name=Azure"
La réponse doit ressembler à celle-ci :
Hello, Azure. This HTTP triggered function executed successfully.
La fonction s’est exécutée correctement et a retourné le nom que vous avez transmis dans la requête.
Sécuriser les déclencheurs HTTP
Les déclencheurs HTTP vous permettent d’utiliser des clés API pour bloquer les appelants inconnus en imposant la fourniture d’une clé dans le cadre de la requête. Quand vous créez une fonction, vous sélectionnez le niveau d’autorisation. Par défaut, le niveau est défini sur Fonction, qui exige une clé API spécifique à la fonction. Il peut également être défini sur Admin afin d’utiliser une clé « maîtresse » globale, ou Anonyme pour indiquer qu’aucune clé n’est requise. Vous pouvez aussi modifier le niveau d’autorisation via les propriétés de la fonction après que celle-ci a été créée.
Dans la mesure où vous avez spécifié Function quand vous avez créé cette fonction, vous devez fournir la clé quand vous envoyez la requête HTTP. Vous pouvez l’envoyer en tant que paramètre de chaîne de requête nommé code
. Vous pouvez également utiliser la méthode préférée et la transmettre en tant qu’en-tête HTTP nommé x-functions-key
.
Pour trouver les clés de fonction, ouvrez le menu Code + Test en sélectionnant le nom de votre fonction (par exemple, HttpTriger1) sous l’onglet Functions du menu Vue d’ensemble. Sélectionnez ensuite l’onglet Clé de fonction.
Par défaut, la valeur de la clé de fonction est masquée. Affichez la valeur de clé de fonction par défaut en sélectionnant Afficher la valeur. Copiez le contenu du champ Valeur dans le Presse-papiers, puis stockez cette clé dans le Bloc-notes ou une application similaire pour l’utiliser ultérieurement.
Pour tester la fonction avec la clé de fonction, ouvrez une invite de commandes et exécutez cURL pour envoyer une requête HTTP à l’URL de la fonction. Remplacez
<your-function-key>
par la valeur de clé de fonction que vous avez enregistrée, et remplacez<your-https-url>
par l’URL de votre fonction.curl --header "Content-Type: application/json" --header "x-functions-key: <your-function-key>" --request POST --data "{\"name\": \"Azure Function\"}" <your-https-url>
Passez en revue la commande cURL et vérifiez que ses valeurs sont les suivantes :
- Elle a ajouté une valeur d’en-tête
Content-Type
de typeapplication/json
. - Elle a passé la clé de fonction comme valeur d’en-tête
x-functions-key
. - Elle a utilisé une demande
POST
. - Elle a passé la fonction Azure avec l’URL de votre fonction.
- Elle a ajouté une valeur d’en-tête
Consultez les journaux.
Le volet Code + Test doit ouvrir une session affichant la sortie du fichier journal (vérifiez que Journaux du système de fichiers est sélectionné dans la liste déroulante en haut du volet Journaux). Le fichier journal est mis à jour avec l’état de votre demande, qui doit ressembler à ceci :
```output
2022-02-16T22:34:10.473 [Information] Executing 'Functions.HttpTrigger1' (Reason='This function was programmatically called via the host APIs.', Id=4f503b35-b944-455e-ba02-5205f9e8b47a)
2022-02-16T22:34:10.539 [Information] JavaScript HTTP trigger function processed a request.
2022-02-16T22:34:10.562 [Information] Executed 'Functions.HttpTrigger1' (Succeeded, Id=4f503b35-b944-455e-ba02-5205f9e8b47a, Duration=114ms)
```
```output
2022-02-16T21:07:11.340 [Information] INFORMATION: PowerShell HTTP trigger function processed a request.
2022-02-16T21:07:11.449 [Information] Executed 'Functions.DriveGearTemperatureService' (Succeeded, Id=25e2edc3-542f-4629-a152-cf9ed99680d8, Duration=1164ms)
```
Ajouter la logique métier à la fonction
Ajoutons la logique à la fonction pour vérifier les relevés de température qu’elle reçoit et leur définir un état.
Notre fonction attend un tableau de relevés de température. L’extrait de code JSON suivant est un exemple de corps de la demande que nous envoyons à notre fonction. Le nom du tableau peut être légèrement différent pour JavaScript ou PowerShell. Toutefois, chaque entrée du tableau a un ID, un timestamp et une température.
{
"Readings": [
{
"driveGearId": 1,
"timestamp": 1534263995,
"temperature": 23
},
{
"driveGearId": 3,
"timestamp": 1534264048,
"temperature": 45
},
{
"driveGearId": 18,
"timestamp": 1534264050,
"temperature": 55
}
]
}
Remplaçons le code par défaut de notre fonction par le code suivant qui met en œuvre notre logique métier.
Dans le volet de la fonction HttpTrigger1, ouvrez le fichier index.js et remplacez son contenu par le code suivant. Après avoir apporté ce changement, dans la barre de commandes, sélectionnez Enregistrer pour enregistrer les mises à jour dans le fichier.
module.exports = function (context, req) {
context.log('Drive Gear Temperature Service triggered');
if (req.body && req.body.readings) {
req.body.readings.forEach(function(reading) {
if(reading.temperature<=25) {
reading.status = 'OK';
} else if (reading.temperature<=50) {
reading.status = 'CAUTION';
} else {
reading.status = 'DANGER'
}
context.log('Reading is ' + reading.status);
});
context.res = {
// status: 200, /* Defaults to 200 */
body: {
"readings": req.body.readings
}
};
}
else {
context.res = {
status: 400,
body: "Please send an array of readings in the request body"
};
}
context.done();
};
La logique que nous avons ajoutée est simple. Nous effectuons une itération au sein du tableau et définissons l’état sur OK, Attention ou Danger, en fonction de la valeur du champ de température. Nous renvoyons ensuite le tableau de relevés avec un champ d’état ajouté à chaque entrée.
Remarquez les instructions Log
lorsque vous développez Journaux au bas du volet. Quand la fonction s’exécute, ces instructions ajoutent des messages dans la fenêtre Journaux.
Tester notre logique métier
Nous allons utiliser la fonctionnalité Tester/exécuter dans Développeur>Code + test pour tester notre fonction.
Sous l’onglet Code + Test ,sélectionnez Tester/Exécuter. Sous l’onglet Entrée, remplacez le contenu de la zone de texte Corps par le code suivant pour créer notre exemple de demande.
{ "readings": [ { "driveGearId": 1, "timestamp": 1534263995, "temperature": 23 }, { "driveGearId": 3, "timestamp": 1534264048, "temperature": 45 }, { "driveGearId": 18, "timestamp": 1534264050, "temperature": 55 } ] }
Ouvrez le fichier run.ps1 et remplacez son contenu par le code suivant. Après avoir apporté ce changement, dans la barre de commandes, sélectionnez Enregistrer pour enregistrer les mises à jour dans le fichier.
using namespace System.Net
param($Request, $TriggerMetadata)
Write-Host "Drive Gear Temperature Service triggered"
$readings = $Request.Body.Readings
if ($readings) {
foreach ($reading in $readings) {
if ($reading.temperature -le 25) {
$reading.Status = "OK"
}
elseif ($reading.temperature -le 50) {
$reading.Status = "CAUTION"
}
else {
$reading.Status = "DANGER"
}
Write-Host "Reading is $($reading.Status)"
}
$status = [HttpStatusCode]::OK
$body = $readings
}
else {
$status = [HttpStatusCode]::BadRequest
$body = "Please send an array of readings in the request body"
}
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
StatusCode = $status
Body = $body
})
La logique que nous avons ajoutée est simple. Nous effectuons une itération au sein du tableau et définissons l’état sur OK, Attention ou Danger, en fonction de la valeur du champ de température. Nous renvoyons ensuite le tableau de relevés avec un champ d’état ajouté à chaque entrée.
Notez les appels à l’applet de commande Write-Host
. Quand la fonction s’exécute, ces instructions ajoutent des messages dans la fenêtre Journaux.
Tester la logique métier
Nous allons utiliser la fonctionnalité Tester/exécuter dans Développeur>Code + test pour tester notre fonction.
Sous l’onglet Code + Test ,sélectionnez Tester/Exécuter. Sous l’onglet Entrée, remplacez le contenu de la zone de texte Corps par le code suivant pour créer notre exemple de demande.
{ "Readings": [ { "driveGearId": 1, "timestamp": 1534263995, "temperature": 23 }, { "driveGearId": 3, "timestamp": 1534264048, "temperature": 45 }, { "driveGearId": 18, "timestamp": 1534264050, "temperature": 55 } ] }
Sélectionnez Exécuter. L’onglet Sortie affiche le code de réponse HTTP et le contenu. Pour voir les messages des journaux, ouvrez l’onglet Journaux dans le contrôle suspendu en bas du volet (s’il n’est pas déjà ouvert). L’image suivante montre un exemple de réponse dans le volet de sortie ainsi que des messages dans le volet Journaux.
L’onglet Sortie montre qu’un champ d’état a été ajouté à chaque relevé.
Dans le menu Développeur à gauche, sélectionnez Surveiller pour vérifier si la requête a été journalisée dans Application Insights. Le volet Surveiller apparaît pour votre fonction.
L’onglet Appels du volet affiche les Traces d’appel pour chacun de vos appels de fonction. Sélectionnez la valeur Date(UTC) pour l’un des appels et affichez les détails sur l’exécution de votre fonction.