A medida que integres Cloud Functions en tu proyecto, tu código podría expandirse para contener muchas funciones independientes. Es posible que tenga demasiadas funciones para caber razonablemente en un solo archivo, o diferentes equipos pueden implementar diferentes grupos de funciones, creando el riesgo de que un equipo sobrescriba o borre accidentalmente las funciones de otro equipo. Cloud Functions ofrece diferentes formas de organizar su código para facilitar la navegación y el mantenimiento de sus funciones.
Organizar funciones en bases de código.
Puedes usar la propiedad codebase
del objeto de configuración de funciones en firebase.json
para administrar una gran colección de funciones en múltiples repositorios o subpaquetes dentro de una configuración monorepo de un único repositorio:
# 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 propiedad codebase
es compatible con Firebase CLI v10.7.1 y versiones posteriores.
Administrar múltiples repositorios
La propiedad codebase
puede ayudar a simplificar la gestión de múltiples repositorios. Examinemos un caso en el que tiene dos repositorios diferentes que implementan funciones en el mismo proyecto de Firebase:
$ tree .
├── repoA
│ ├── firebase.json
│ └── functions
│ ├── index.js
│ └── package.json
└── repoB
├── firebase.json
└── functions
├── index.js
└── package.json
Sin las anotaciones de la base de código, Firebase CLI le habría solicitado que eliminara las funciones definidas en el otro repositorio en el momento de la implementación:
$ (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)
Puedes evitar este problema agregando una anotación de base de código única en la sección de configuración de funciones de firebase.json
en cada repositorio de proyecto:
# repoA/firebase.json
"functions": {
"codebase": "repo-a"
}
# repoB/firebase.json
"functions": {
"codebase": "repo-b"
}
Con la anotación de la base de código, Firebase CLI ya no le solicita que elimine funciones definidas fuera de su repositorio inmediato:
$ (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!
Administrar múltiples paquetes fuente (monorepo)
La propiedad codebase
puede ayudar a simplificar la administración de múltiples paquetes fuente en un único repositorio. Examinemos un caso en el que tiene un directorio de proyecto de Firebase con definiciones de funciones distribuidas en varios subpaquetes:
$ tree .
├── firebase.json
├── teamA
│ ├── index.js
│ └── package.json
└── teamB
├── index.js
└── package.json
Esta configuración se adapta a los siguientes casos de uso:
- Tiene una configuración monorepo y diferentes equipos administran sus propias definiciones de funciones en un paquete aislado.
- Tiene una función con una gran dependencia externa y una inicialización de larga duración, y desea aislar esa función de otras funciones sensibles a la latencia.
Para admitir una configuración de monrepo como esta, defina configuraciones de funciones múltiples en firebase.json
:
"functions": [
{
"source": "teamA",
"codebase": "team-a"
},
{
"source": "teamB",
"codebase": "team-b"
},
]
Con esta configuración, Firebase CLI implementa funciones de todos los paquetes en un solo comando de implementación:
$ 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)...
...
También puedes implementar una base de código específica:
$ 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)...
...
Escribir funciones en múltiples archivos.
Al comenzar con Cloud Functions, puede colocar sus primeras funciones en un solo archivo:
index.js
const functions = require('firebase-functions');
exports.foo = functions.https.onRequest((request, response) => {
// ...
});
exports.bar = functions.https.onRequest((request, response) => {
// ...
});
principal.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!")
Esto puede resultar difícil de gestionar con más de unas pocas funciones. En su lugar, puedes poner toda tu lógica para cada función en su propio archivo y usar tu archivo fuente como una lista de exportaciones:
Nodo.js
foo.js
const functions = require('firebase-functions'); exports.foo = functions.https.onRequest((request, response) => { // ... });
bar.js
const functions = require('firebase-functions'); 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;
Pitón
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!")
principal.py
from fn_impl.foo import *
from fn_impl.bar import *
Esta configuración asume una estructura de directorio de proyecto como la siguiente:
my-project
├── firebase.json
└── functions
├── fn_impl
│ ├── __init__.py
│ ├── foo.py
│ └── bar.py
├── main.py
└── requirements.txt
fn_impl
: puede tener cualquier nombre
__init__.py
: obligatorio, pero puede estar vacío
Funciones de grupo
En muchos proyectos, las funciones se pueden separar en grupos lógicos que deben implementarse y mantenerse juntos. Por ejemplo, es posible que tenga un grupo de funciones utilizadas para informar métricas:
metrics.js
const functions = require('firebase-functions'); exports.usageStats = functions.https.onRequest((request, response) => { // ... }); exports.nightlyReport = functions.https.onRequest((request, response) => { // ... });
Puede poner estas funciones en un grupo al exportarlas en su archivo index.js
:
index.js
// Export both functions from metrics.js in the "metrics" group: // - metrics-usageStats // - metrics-nightlyReport exports.metrics = require('./metrics');
Cuando se implementen, las funciones tendrán el prefijo del nombre de su grupo, por lo que en este ejemplo las funciones se denominarían metrics-usageStats
y metrics-nightlyReport
.
Al implementar funciones, puede limitar la acción a un solo grupo:
firebase deploy --only functions:metrics
Próximos pasos
Para obtener más información sobre Cloud Functions, consulte:
- Manejo de dependencias .
- Administrar la implementación de funciones y las opciones de tiempo de ejecución .