Les documents Firebase pour l'espace de noms functions.https
Montrent que la fonction accepte un objet express.Request
Et un objet express.Response
. Nulle part cela ne mentionne que vous pouvez passer un objet serveur express à functions.https.onRequest
. Cependant, j'ai constaté que les gens l'ont fait sans indication claire des commentateurs que cela ne devrait pas être fait (sauf une personne dans le fil # 101 du problème de dépôt functions-samples
)
voir:
firebase-functions
https://github.com/firebase/firebase-functions/issues/27functions-samples
Pour le middleware https://github.com/firebase/functions-samples/blob/master/authorized-https-endpoint/functions/index.jsMes questions sont alors:
Clarification pour 1 et 2: dans Lambda, toutes les ressources en dehors de la fonction exportée sont utilisées pour toutes les invocations ultérieures de la même instance Lambda alors que cette instance de fonction est "à chaud". Cela signifie que le temps de réponse de la fonction n'est pas affecté négativement par un code d'initialisation complexe que vous pourriez avoir à l'avance car il est effectué une fois par instance "chaude". Dans cet exemple, il n'aurait alors pas besoin d'initialiser un serveur ExpressJS à chaque appel, une seule fois alors que la fonction est "chaude". Je suis curieux de savoir si les fonctions cloud font de même?
Toujours dans Lambda, l'existence du serveur ExpressJS ne prolonge pas le temps d'exécution de la fonction (quand il revient c'est fait), je suis également curieux de savoir comment les fonctions cloud sont implémentées ici. Fait-il simplement la même chose que Lambda, ou (parce qu'il peut gérer différemment les objets existants) fait-il autre chose?
functions.https.onRequest
Ne spécifie pas que vous pouvez y passer un objet serveur ExpressJS, alors comment cela fonctionne-t-il? Y a-t-il alors deux points finaux? Quelqu'un peut-il expliquer ce qui se passe ici?Clarification pour 3: j'ai vu des gens faire ce qui suit:
// './functions/index.js'
var functions = require("firebase-functions");
const express = require("express");
// setup ExpressJS Server
const expressRouter = new express.Router();
expressRouter.get("*", (req, res) => {
res.send(`Hello from Express in Cloud Functions for Firebase`);
});
// Cloud Function
exports.express = functions.https.onRequest(expressRouter);
Et je souhaite savoir comment cela fonctionne étant donné que l'API Cloud Functions spécifie uniquement l'acceptation des paramètres functions.https.onRequest(request, response)
modélisés d'après l'API ExpressJS.
Ces paramètres sont basés sur les objets Express Request et Response - firebase.google.com/docs/functions/http-events
Étant donné que toutes les questions se rapportent à l'extrait de code unique et à ce cas d'utilisation, j'ai pensé qu'il serait préférable de répondre ensemble.
Merci d'avance :)
Tout cela fonctionne parce que sous les couvertures, une application Express n'est en fait qu'une fonction qui prend une demande et une réponse HTTP Node.js et agit sur elles avec un sucre automatique tel que le routage. Vous pouvez donc transmettre sans problème un routeur ou une application Express à un gestionnaire de fonctions cloud, car les objets req
et res
d'Express sont compatibles avec les versions standard de Node.js. Fondamentalement, c'est une application "double Express" où une application en appelle une autre.
En ce qui concerne le cycle de vie des fonctions et l'état partagé: les fonctions sont générées dans des instances de calcul éphémères qui peuvent survivre pour traiter plusieurs demandes, mais pas. Vous ne pouvez pas régler ou garantir si une fonction sera invoquée ou non dans la même instance de calcul d'une invocation à la suivante.
Vous pouvez créer des ressources (telles qu'une application Express) en dehors de l'invocation de la fonction et elle sera exécutée lorsque les ressources de calcul seront augmentées pour cette fonction. Cela survivra aussi longtemps que l'instance le fera; cependant, le CPU/réseau est limité à zéro entre les invocations, vous ne pouvez donc pas faire de "travail" en dehors du cycle de vie d'une invocation de fonction. Une fois la promesse résolue (ou que vous avez répondu à la demande HTTP), vos ressources de calcul seront bloquées via la limitation et peut se terminer à tout moment.
Vous ne devez pas vous attendre à conserver une ressource au-delà de la durée de vie d'une fonction. Vous devez vous attendre à ce que le conteneur se nettoie complètement une fois que la promesse finale de la fonction a été résolue ou que la réponse HTTP a été entièrement envoyée. Il n'y a aucun état partagé entre les invocations de fonction. C'est la seule façon dont les fonctions cloud peuvent évoluer. Si vous avez besoin d'un état partagé, stockez-le dans la base de données et lisez-le à chaque appel, en le protégeant avec une transaction si nécessaire.
Je ne sais pas ce que vous demandez dans la troisième question. Cela semble en quelque sorte sans rapport avec les deux premières questions - peut-être que ce devrait être sa propre question? Pour autant que je sache, il n'y a qu'un seul point de terminaison pour votre backend.