IBM Cloud Docs
Travailler avec des fonctions

Travailler avec des fonctions

Une fonction est un extrait de code sans état qui exécute des tâches au fur et à mesure qu'il est invoqué par les requêtes HTTP. Avec les fonctions IBM Code Engine, vous pouvez exécuter votre logique d'entreprise de manière évolutive et sans serveur. IBM Code Engine offrent un environnement d'exécution optimisé pour prendre en charge les scénarios de faible latence et d'extension rapide. Votre code de fonction peut être écrit dans un runtime géré qui inclut des versions spécifiques de Node.js ou Python.

Un bundle de code est une collection de fichiers qui représente votre code de fonction. Ce bundle de code est injecté dans le conteneur d'exécution. Votre bundle de code est créé par Code Engine et est stocké dans le registre de conteneur ou en ligne avec la fonction. Un bundle de code n'est pas une image de conteneur standard OCI (Open Container Initiative).

Avant de commencer

Vous ne savez pas quel type de charge de travail Code Engine créer? Voir Planification pour Code Engine.

Limitations de fonction

  • Pas de prise en charge de l'abonnement aux producteurs d'événements.
  • Pas de prise en charge de Terraform.

Comment faire en sorte que mon code soit exécuté en tant que composant de fonction Code Engine?

Que votre code existe en tant que source dans un fichier local ou dans un dépôt Git, ou que votre code soit un ensemble de codes existant situé dans un registre public ou privé, Code Engine vous offre un moyen rationalisé d'exécuter votre code en tant que fonction.

  • Si vous commencez avec un code source situé dans un dépôt Git, vous pouvez choisir de pointer vers l'emplacement de votre source, et Code Engine se chargera de construire le paquet de code à partir de votre source et de créer la fonction en une seule opération. Dans ce scénario, Code Engine télécharge votre code sur IBM Cloud® Container Registry. Pour en savoir plus, voir Création d'une fonction à partir du code source du référentiel.

  • Si vous commencez avec un code source sur une station de travail locale, vous pouvez choisir de pointer vers l'emplacement de votre source, et Code Engine se charge de construire l'image à partir de votre source et de créer la fonction avec une seule commande CLI. Dans ce scénario, Code Engine télécharge votre code sur IBM Cloud® Container Registry. Pour en savoir plus, voir Création de votre fonction à partir du code source local à l'aide de l'interface de ligne de commande.

  • Si vous commencez avec du code source, vous pouvez également exécuter votre code source en ligne. Dans ce scénario, vous collez votre code source lorsque vous créez votre fonction. Pour plus d'informations, voir Création de votre fonction avec du code en ligne.

Après avoir créé et exécuté votre fonction, vous pouvez également la mettre à jour en utilisant l' une des méthodes précédentes, indépendamment de la façon dont vous l'avez créée ou mise à jour précédemment.

Que se passe-t-il lorsque j'appelle ma fonction?

Lorsqu'une fonction est appelée (démarrée), l'instance de fonction correspondante est initialisée avec les paramètres de conteneur Runtime et de ressource configurés. Le processus de la première initialisation est appelé démarrage à froid.

Pour réduire le temps d'attente de démarrage à froid, Code Engine optimise l'appel en préchauffant certains environnements d'exécution avec des configurations d'UC et de mémoire spécifiques. Les combinaisons préchauffées pour les fonctions comprennent les durées d'exécution Node.js et Python ainsi que la combinaison par défaut de CPU et de mémoire pour les fonctions, à savoir 0.25 vCPU x 1 Go de mémoire. En outre, le système est conçu pour améliorer la réutilisation des instances de fonction qui sont déjà initialisées. Par conséquent, une instance de fonction est maintenue active une fois l'appel terminé pour permettre les appels suivants en réutilisant la même instance et en réutilisant l'état de l'instance à la fin du dernier appel. La réutilisation d'une instance de fonction n'est pas garantie.

Puis-je garder mon instance de fonction en vie plus longtemps?

Avec Code Engine, votre fonction augmente et baisse automatiquement en fonction de la charge de travail. Lorsque vous créez votre fonction avec la combinaison d'UC et de mémoire par défaut, votre fonction est injectée dans un conteneur "préchauffé", qui est optimisé pour être utilisé. Lorsque vous créez une fonction avec une combinaison d'UC et de mémoire autre que la combinaison par défaut, votre fonction est injectée dans un nouveau conteneur. Par défaut, ce conteneur n'est conservé actif que pendant un court laps de temps après la fin de la fonction. Pour plus d'informations, voir Combinaisons d'UC et de mémoire prises en charge pour les fonctions.

Vous pouvez modifier la durée pendant laquelle votre conteneur est maintenu actif à l'aide de l'option --scale-down-delay dans l'interface de ligne de commande ou de l'option Délai de mise à l'échelle dans la console. Notez que tout en conservant votre conteneur actif réduit les temps de démarrage à froid pour toute exécution ultérieure de votre fonction, vous êtes également facturé pour la durée d'existence du conteneur de fonction personnalisée.

Demandes et réponses

Les fonctions sont invoquées à l'aide du protocole HTTP. Lorsque vous invoquez votre fonction, vous pouvez spécifier les paramètres de la demande personnalisée, le corps et les en-têtes de la demande personnalisée, ainsi que la méthode HTTP. Les paramètres de demande sont mis à la disposition du code de fonction en tant que paramètres d'entrée. Le code de fonction peut définir le corps de la réponse, les en-têtes de réponse et le code de réponse, qui sont renvoyés à l'appelant à partir du noeud final des fonctions.

Exemple 1: Génération d'une réponse HTML à partir d'une fonction

L'exemple suivant montre comment générer une réponse HTML à partir d'une fonction.

  function main(params) {
      var msg = 'You did not tell me who you are.';
      if (params.name) {
          msg = `Hello, ${params.name}!`
       } else {
          msg = `Hello, FaaS on CodeEngine!`
      }
      return {
          headers: { 'Content-Type': 'text/html; charset=utf-8' },
          body: `<html><body><h3>${msg}</h3></body></html>`
       }
  }

  module.exports.main = main;

Exemple 2: Définition d'un code de réponse et d'un en-tête de réponse

Votre fonction peut définir un code de réponse et des indicateurs d'en-tête spécifiques. L'exemple suivant illustre comment vous pouvez définir un code de réponse et un en-tête de réponse pour ajouter une redirection vers un autre site URL.

function main(params) {
    return {
        headers: { location: 'https://cloud.ibm.com/docs/codeengine' },
        statusCode: 302
    }
}

Exemple 3: Génération d'une réponse en texte clair à partir d'une fonction

L'exemple suivant montre comment générer une réponse en texte clair à partir d'une fonction.

function main(params) {
    var msg = 'You did not tell me who you are.';
    if (params.name !== "") {
        msg = `Hello, ${params.name}!`
    }
    return {
        headers: { 'Content-Type': 'text/plain;charset=utf-8' },
        body: `${msg}`
    }
}

Traitement et débogage des erreurs

Les appels de fonction peuvent renvoyer des erreurs système ou d'application. Par exemple, les erreurs système indiquent que le code de fonction ne s'est pas exécuté correctement, tandis que les erreurs d'application indiquent un problème dans le code de fonction lui-même.

Lorsqu'une erreur système se produit, un code de réponse HTTP similaire aux codes suivants est renvoyé.

Codes de réponse HTTP
Code Description
409 Les ressources requises par la fonction n'ont pas été satisfaites.
413 Le contenu de la demande dépasse le maximum défini.
414 L'URI d'appel est trop long.
416 La fonction a généré une réponse qui dépasse le maximum défini.
422 Le code de fonction n'est pas valide et ne peut pas être traité. Consultez les journaux de la plateforme pour des détails.
424 Le code de fonction n'a pas pu être exécuté. Réessayez ultérieurement.
429 Vous avez dépassé votre quota de ressources, impossible de planifier la fonction.
431 Les en-têtes de demande dépassent le maximum défini.
500 Erreur de serveur interne.
502 Passerelle incorrecte.
503 Fonction actuellement indisponible, veuillez réessayer plus tard.
507 Mémoire insuffisante pour charger la fonction.

Si Code Engine peut exécuter le code des fonctions, il répond à l'appel avec l'un des codes de statut suivants.

Codes d'état
Code Description
200 Appel de fonction accepté, la fonction sera exécutée en différé.
202 Appel de fonction accepté, la fonction sera exécutée de manière asynchrone.
299 La fonction a dépassé la limite d'exécution spécifiée ou maximale et a été abandonnée.

En tant que développeur d'une fonction, vous pouvez générer n'importe quel code d'état HTTP, même ceux énumérés précédemment. Par conséquent, un en-tête de réponse indique que le code de statut a été généré par le code de fonction.

Les fonctions Code Engine ajoutent les en-têtes de réponse suivants à la réponse d'appel de fonction.

Codes d'état
Code Description
x-faas-actionstatus Le code d'état HTTP défini par la logique du programme de fonction.
x-faas-activation-id ID unique permettant d'identifier l'appel de fonction.
x-faas-result Message success ou message d'erreur court renvoyé par le conteneur d'exécution.
x-faas-errormessage Un message d'erreur long avec des détails supplémentaires.
x-faas-prewarmed Message indiquant si l'appel a été effectué à froid ou si la fonction a été exécutée dans un conteneur existant (préchauffé). Les valeurs possibles sont false ou true.

Caractéristiques d'entrée/sortie des données de fonction

Pour exécuter votre fonction dans Code Engine, votre code doit implémenter un contrat d'exécution avec les caractéristiques suivantes.

  • Il doit pouvoir être appelé à partir d'un point de terminaison d'une application web publique, de sorte qu'il puisse être intégré à des pages web, puis invoqué à partir de n'importe quelle source d'événements Code Engine, d'un navigateur web ou de n'importe quel autre client capable de se connecter à l'adresse HTTPS.
  • Vous devez implémenter une procédure main comme point d'entrée. La procédure main peut recevoir des paramètres d'entrée sous la forme d'une structure de données au format JSON et peut renvoyer des paramètres de sortie, également sous la forme d'une structure de données au format JSON.
  • Peut recevoir un sous-chemin facultatif, de sorte que la fonction puisse implémenter différentes versions, en fonction du chemin spécifié. La procédure main de la fonction reçoit le chemin en tant que paramètre d'entrée __ce_path.
  • Peut recevoir des paramètres de requête facultatifs, qui peuvent être utilisés pour configurer la fonction lors de l'exécution. La procédure main de la fonction reçoit les paramètres sous forme de paires clé-valeur dans la structure de données d'entrée au format JSON.
  • Peut recevoir des en-têtes de demande, de sorte que le code client puisse spécifier des codages acceptés.
  • Peut recevoir un en-tête de demande de type de contenu facultatif.
  • Peut recevoir un contenu de demande (corps) facultatif, que la fonction traite lors de l'exécution. En fonction du type de contenu de demande sélectionné, la charge de données est transmise au point d'entrée principal de la fonction, sous forme codée en base 64 ou "dépliée" dans le cadre de la structure de données d'entrée JSON. Les caractères spéciaux dans les paires de valeurs de clés de l'entrée application/x-www-form-urlencoded sont des valeurs percent-encoded.
  • Peut définir un code d'état HTTP arbitraire (facultatif) qui est ensuite renvoyé au client qui l'invoque.
  • Peut définir des en-têtes de réponse arbitraires, tels qu'un emplacement de redirection, un codage de réponse ou des valeurs de cookie.
  • Peut renvoyer un corps de réponse arbitraire avec un codage binaire ou non binaire sélectionné ; par exemple, application/octet-stream, application/json, text/*, image/* ou audio/*. Si aucun en-tête de réponse content-type n'est défini, la valeur par défaut est text/plain.
  • Prend en charge les types de contenu de demande suivants: application/x-www-form-urlencoded (par défaut), text/plain, application/json, application/octet-stream, image/*, audio/*
  • Ne prend pas en charge l'en-tête de demande multipart/form-data.

Options de visibilité pour une fonction Code Engine

Avec Code Engine, vous pouvez déterminer le bon niveau de visibilité pour votre fonction en définissant les points de terminaison, ou les mappages de domaine de système qui sont disponibles pour recevoir des demandes.

Chaque fonction dispose d'une cartographie interne du domaine du système qui est visible par tous les composants au sein du même projet Code Engine, mais pas à l'extérieur du projet. En plus du mappage de domaine de système interne, vous choisissez de rendre la fonction visible sur l'Internet public ou sur le réseau privé IBM Cloud.

Pour une visibilité publique ou privée, la fonction est exposée sur un point de terminaison HTTPS. Pour plus de détails sur le certificat TLS utilisé, voir Certificats TLS pour les projets Code Engine.

Vous pouvez déployer votre fonction avec les niveaux de visibilité suivants:

Visibilité des fonctions
Paramètre Description
interne(projet) Une fonction avec ce paramètre peut recevoir des demandes de composants dans le même projet Code Engine. La définition d'un point de terminaison interne (projet) signifie que votre fonction n'est pas accessible depuis l'internet public et que l'accès au réseau n'est possible qu'à partir d'autres composants Code Engine fonctionnant dans le même projet Code Engine. Ce noeud final est toujours activé. Important: Une fonction ne peut pas appeler un autre travail ou une autre application à l'aide des routes internes.
public Une fonction dotée de ce paramètre est exposée à l'internet et à votre projet Code Engine. La définition d'un point de terminaison public signifie que votre fonction peut recevoir des requêtes de l'internet public ou des composants de votre projet Code Engine. Ce paramètre est la valeur par défaut.
private Une fonction dotée de ce paramètre est exposée au réseau privé IBM Cloud et à votre projet Code Engine. La définition d'un point de terminaison privé signifie que votre fonction n'est pas accessible depuis l'internet public et que l'accès au réseau n'est possible qu'à partir d'autres services IBM Cloud en utilisant des points de terminaison privés virtuels (VPE) ou des composants Code Engine fonctionnant dans le même projet.

Vous pouvez définir les paramètres de visibilité d'une fonction à partir de la console ou de l'interface de programmation lorsque vous créez, déployez ou mettez à jour votre fonction.

Déploiement de votre fonction avec un noeud final interne

Vous pouvez définir la visibilité du noeud final pour votre fonction à déployer avec un noeud final interne (projet). Lorsque vous définissez un noeud final interne (projet), votre fonction n'est pas accessible à partir de l'Internet public et l'accès au réseau n'est possible qu'à partir d'autres composants Code Engine qui s'exécutent dans le même projet Code Engine. Ce noeud final est toujours activé. Les fonctions restent accessibles par le biais de composants partagés et doivent donc être sécurisées.

Par exemple, si votre solution se compose de plusieurs fonctions au sein d'un projet, vous pouvez la configurer de manière à ce qu'une seule de ces fonctions soit visible depuis l'internet, afin qu'elle gère le trafic entrant. Cette fonction publique peut déléguer des tâches à d'autres fonctions de votre solution, de sorte qu'elles ne doivent pas être visibles sur l'internet.

Avec l'interface de ligne de commande, définissez la visibilité de noeud final pour votre fonction afin qu'elle soit déployée avec un noeud final de projet à l'aide de l'option --visibility=project sur la commande function create ou function update. Vous pouvez obtenir les URL disponibles pour votre fonction qui reflètent votre définition de noeud final à l'aide de la commande function get.

Dans la console, définissez la visibilité des noeuds finaux pour votre fonction à l'aide du paramètre Noeuds finaux lorsque vous créez votre fonction. Une fois votre fonction déployée, vous pouvez afficher et modifier ces paramètres de mappage de domaine système dans l'onglet Mappages de domaine de la page Fonctions.

Une fonction avec ce paramètre peut recevoir des demandes de composants dans le même projet Code Engine. Toutefois, une fonction ne peut pas appeler un autre travail ou une autre application à l'aide des routes internes.

Déployer votre fonction avec un point de terminaison public

Lorsque vous déployez une fonction, par défaut, la fonction peut recevoir des demandes de l'Internet public ou de composants dans le même projet Code Engine. Dans ce cas, la fonction est déployée avec un point final public.

Déployer votre fonction avec un point d'accès privé

Vous pouvez définir la visibilité de noeud final pour votre fonction à déployer avec un noeud final privé. Lorsque vous définissez un point de terminaison privé pour votre fonction, il n'est pas accessible depuis l'internet public et l'accès au réseau n'est possible qu'à partir d'autres services IBM Cloud de points de terminaison privés virtuels (VPE) ou de composants Code Engine fonctionnant dans le même projet (cluster-local).

Par exemple, si votre solution consiste en un composant qui s'exécute sur un cluster IBM Cloud Kubernetes Service Kubernetes au sein de votre propre point de terminaison privé virtuel et que vous souhaitez accéder à la fonction Code Engine depuis le réseau privé IBM Cloud, vous pouvez définir la visibilité de la fonction comme étant privée. Lorsque la visibilité de la fonction est définie comme privée, la fonction n'est pas accessible via l'internet public. La fonction reste accessible à partir d'autres fonctions du projet.

Vous pouvez créer votre fonction avec un noeud final privé de sorte que la fonction soit exposée uniquement via le réseau privé IBM Cloud et non sur l'Internet externe. La fonction est toujours accessible par le biais de composants partagés à partir du réseau interne et le point de terminaison de la fonction doit être sécurisé.

Avec l'interface de ligne de commande, définissez la visibilité de noeud final pour votre fonction de sorte qu'elle soit déployée avec un noeud final privé à l'aide de l'option --visibility=private sur la commande function create ou function update. Vous pouvez obtenir les URL disponibles pour votre fonction qui reflètent votre définition de noeud final à l'aide de la commande function get.

Dans la console, définissez la visibilité des noeuds finaux pour votre fonction à l'aide du paramètre Noeuds finaux lorsque vous créez votre fonction. Une fois votre fonction déployée, vous pouvez afficher et modifier ces paramètres de mappage de domaine système dans l'onglet Mappages de domaine de la page Fonctions.

Pour plus d'informations sur la connexion sur les réseaux privés, voir Utilisation de nœuds finaux privés virtuels avec Code Engine.

Options de création de fonctions

Découvrez les options que vous pouvez spécifier lorsque vous créez votre fonction. Notez que les options peuvent varier entre la console et l'interface de ligne de commande.

Mémoire et UC

Lorsque vous déployez votre fonction, vous pouvez spécifier la quantité de mémoire et de CPU que votre fonction peut consommer. Ces montants peuvent varier selon que votre fonction est gourmande en calcul, en mémoire ou équilibrée.

Par défaut, votre fonction se voit attribuer 4 G de mémoire et 1.0 vCPU. Pour plus d'informations sur les autres combinaisons de mémoire et d'UC prises en charge, voir Combinaisons de mémoire et d'UC prises en charge pour les fonctions.

Création et exécution de votre fonction à l'aide de variables d'environnement

Vous pouvez définir des variables d'environnement sous la forme de paires clé-valeur qui peuvent être utilisées par votre fonction au moment de l'exécution.

Vous pouvez définir des variables d'environnement lorsque vous créez votre fonction ou lorsque vous mettez à jour une fonction existante à l'aide de l'interface de programmation.

Pour plus d'informations sur la définition de variables d'environnement, voir Utilisation de variables d'environnement.

Code Engine injecte automatiquement certaines variables d'environnement dans la fonction. Pour plus d'informations sur les variables d'environnement injectées automatiquement, voir Variables d'environnement injectées automatiquement.

Création et exécution de votre fonction lors de l'utilisation de secrets et de cartes de configuration

Dans Code Engine, les secrets et les cartes de configuration peuvent être consommés par votre fonction en utilisant des variables d'environnement.

Les secrets et les mappes de configuration sont des paires clé-valeur. Lorsqu'elles sont mappées à des variables d'environnement, les relations NAME=VALUE sont définies de telle sorte que le nom de la variable d'environnement correspond à la "clé" de chaque entrée de ces mappes, et la valeur de la variable d'environnement est la "valeur" de cette clé.

Votre fonction peut utiliser des variables d'environnement pour référencer entièrement une carte de configuration (ou un secret) ou référencer des clés individuelles dans une carte de configuration (ou un secret).

Pour plus d'informations, voir Référencement de secrets à l'aide de variables d'environnement et Référencement de mappes de configuration à l'aide de variables d'environnement.

Remarques relatives aux quotas de fonctions

Lorsque vous utilisez des applications, des fonctions et des travaux par lots, ces ressources s'exécutent dans le contexte d'un projet Code Engine. Les quotas de ressources sont définis par projet et des limites s'appliquent aux applications, aux fonctions et aux travaux par lots.

Pour plus d'informations sur les limites dans Code Engine, voir Limites et quotas pour Code Engine.

Etapes suivantes

Maintenant que vous connaissez les concepts clés de l'utilisation des fonctions Code Engine, êtes-vous prêt à créer et à utiliser des fonctions? Voir les rubriques suivantes.

Pour plus d'informations sur l'utilisation des fonctions, voir les rubriques suivantes.