À mesure que vous intégrez Cloud Functions à votre projet, votre code peut s'étendre pour contenir de nombreuses fonctions indépendantes. Il se peut que vous ayez trop de fonctions pour les faire tenir dans un seul fichier ou que différentes équipes déploient différents groupes de fonctions, ce qui crée un risque qu'une équipe écrase ou supprime accidentellement les fonctions d'une autre équipe. Cloud Functions propose différentes façons d'organiser votre code pour faciliter la navigation et la maintenance de vos fonctions.
Organiser les fonctions dans les codebases
Vous pouvez utiliser la propriété codebase
de l'objet de configuration des fonctions dans firebase.json
pour gérer une grande collection de fonctions dans plusieurs dépôts ou sous-packages au sein d'une configuration monorepo à dépôt unique :
# firebase.json
"functions": {
"codebase": "my-codebase"
# NOTE: Codebase must be less than 63 characters and can contain only
# lowercase letters, numeric characters, underscores, and dashes.
}
La propriété codebase
est compatible avec la CLI Firebase v10.7.1 et versions ultérieures.
Gérer plusieurs dépôts
La propriété codebase
peut simplifier la gestion de plusieurs dépôts. Examinons un cas où vous disposez de deux dépôts différents qui déploient des fonctions dans le même projet Firebase :
$ tree .
├── repoA
│ ├── firebase.json
│ └── functions
│ ├── index.js
│ └── package.json
└── repoB
├── firebase.json
└── functions
├── index.js
└── package.json
Sans annotations de code, la CLI Firebase vous aurait invité à supprimer les fonctions définies dans l'autre dépôt au moment du déploiement :
$ (cd repoA && firebase deploy --only functions)
...
i functions: preparing functions directory for uploading...
✔ functions: functions folder uploaded successfully
The following functions are found in your project but do not exist in your local source code:
fn1FromRepoB
fn2FromRepoB
...
? Would you like to proceed with deletion? Selecting no will continue the rest of the deployments. (y/N)
Pour éviter ce problème, ajoutez une annotation de code unique dans la section de configuration des fonctions du fichier firebase.json
de chaque dépôt de projet :
# repoA/firebase.json
"functions": {
"codebase": "repo-a"
}
# repoB/firebase.json
"functions": {
"codebase": "repo-b"
}
Grâce à l'annotation de code, la CLI Firebase ne vous invite plus à supprimer les fonctions définies en dehors de votre dépôt immédiat :
$ (cd repoA && firebase deploy --only functions)
...
i functions: preparing functions directory for uploading...
✔ functions: functions folder uploaded successfully
# Gleefully ignores functions from repoB
i functions: creating Node.js 16 function fnFromRepoA (us-central1)...
✔ Deploy Complete!
Gérer plusieurs packages sources (monorepo)
La propriété codebase
peut simplifier la gestion de plusieurs packages sources dans un même dépôt. Prenons l'exemple d'un répertoire de projet Firebase dont les définitions de fonctions sont réparties dans plusieurs sous-packages :
$ tree .
├── firebase.json
├── teamA
│ ├── index.js
│ └── package.json
└── teamB
├── index.js
└── package.json
Cette configuration convient aux cas d'utilisation suivants :
- Vous avez configuré un monorepo et différentes équipes gèrent leurs propres définitions de fonctions dans un package isolé.
- Vous disposez d'une fonction avec une forte dépendance externe et une initialisation de longue durée, et vous souhaitez isoler cette fonction des autres fonctions sensibles à la latence.
Pour prendre en charge une configuration de monorepo comme celle-ci, définissez plusieurs configurations de fonctions dans firebase.json
:
"functions": [
{
"source": "teamA",
"codebase": "team-a"
},
{
"source": "teamB",
"codebase": "team-b"
},
]
Avec cette configuration, la CLI Firebase déploie les fonctions de tous les packages en une seule commande de déploiement :
$ firebase deploy --only functions
i deploying functions
i functions: preparing codebase team-a for deployment
i functions: preparing codebase team-b for deployment
i functions: creating Node.js 16 function team-a:helloATeam(us-central1)...
i functions: creating Node.js 16 function team-b:helloBTeam(us-central1)...
...
Vous pouvez également déployer une codebase spécifique :
$ firebase deploy --only functions:team-b
i deploying functions
i functions: preparing codebase team-b for deployment
i functions: updating Node.js 16 function team-b:helloBTeam(us-central1)...
...
Écrire des fonctions dans plusieurs fichiers
Lorsque vous commencez à utiliser Cloud Functions, vous pouvez placer vos premières fonctions dans un seul fichier :
index.js
const functions = require('firebase-functions/v1');
exports.foo = functions.https.onRequest((request, response) => {
// ...
});
exports.bar = functions.https.onRequest((request, response) => {
// ...
});
main.py
from firebase_functions import https_fn
@https_fn.on_request()
def foo(req: https_fn.Request) -> https_fn.Response:
return https_fn.Response("Hello foo!")
@https_fn.on_request()
def bar(req: https_fn.Request) -> https_fn.Response:
return https_fn.Response("Hello bar!")
Cela peut devenir difficile à gérer avec plus de quelques fonctions. Vous pouvez plutôt placer toute la logique de chaque fonction dans son propre fichier et utiliser votre fichier source comme liste d'exportations :
Node.js
foo.js
const functions = require('firebase-functions/v1'); exports.foo = functions.https.onRequest((request, response) => { // ... });
bar.js
const functions = require('firebase-functions/v1'); exports.bar = functions.https.onRequest((request, response) => { // ... });
index.js
const foo = require('./foo'); const bar = require('./bar'); exports.foo = foo.foo; exports.bar = bar.bar;
Python
foo.py
from firebase_functions import https_fn
@https_fn.on_request()
def foo(req: https_fn.Request) -> https_fn.Response:
return https_fn.Response("Hello foo!")
bar.py
from firebase_functions import https_fn
@https_fn.on_request()
def bar(req: https_fn.Request) -> https_fn.Response:
return https_fn.Response("Hello foo!")
main.py
from fn_impl.foo import *
from fn_impl.bar import *
Cette configuration suppose une structure de répertoire de projet semblable à la suivante :
my-project
├── firebase.json
└── functions
├── fn_impl
│ ├── __init__.py
│ ├── foo.py
│ └── bar.py
├── main.py
└── requirements.txt
fn_impl
: peut avoir n'importe quel nom
__init__.py
: obligatoire, mais peut être vide
Fonctions de groupe
Dans de nombreux projets, les fonctions peuvent être séparées en groupes logiques qui doivent être déployés et gérés ensemble. Par exemple, vous pouvez disposer d'un groupe de fonctions utilisées pour générer des métriques de reporting :
metrics.js
const functions = require('firebase-functions/v1'); exports.usageStats = functions.https.onRequest((request, response) => { // ... }); exports.nightlyReport = functions.https.onRequest((request, response) => { // ... });
Vous pouvez regrouper ces fonctions lorsque vous les exportez dans votre fichier index.js
:
index.js
// Export both functions from metrics.js in the "metrics" group: // - metrics-usageStats // - metrics-nightlyReport exports.metrics = require('./metrics');
Une fois déployées, les fonctions seront précédées du nom de leur groupe. Dans cet exemple, les fonctions seront donc nommées metrics-usageStats
et metrics-nightlyReport
.
Lorsque vous déployez des fonctions, vous pouvez limiter l'action à un seul groupe :
firebase deploy --only functions:metrics
Étapes suivantes
Pour en savoir plus sur Cloud Functions, consultez :