כשתתחילו לשלב את Cloud Functions בפרויקט, הקוד שלכם עשוי להתרחב כך שיכיל הרבה פונקציות עצמאיות. יכול להיות שיש יותר מדי פונקציות מתאימים במידה סבירה לקובץ יחיד, או שצוותים שונים עשויים לפרוס קבוצות שונות של פונקציות, דבר שעלול לגרום לכך שצוות אחד יחליף או ימחק בטעות תפקידים של צוות אחר. ב-Cloud Functions יש דרכים שונות לארגן את כדי שיהיה קל יותר לנווט בפונקציות ולתחזק אותן.
ארגון פונקציות ב-codebases
אפשר להשתמש במאפיין codebase
של אובייקט הגדרת הפונקציות ב-
firebase.json
כדי לנהל אוסף גדול של פונקציות
מאגרים או חבילות משנה בתוך הגדרת מונורפו אחת של מאגר:
# 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.
}
הנכס codebase
נתמך ב-Firebase CLI גרסה 10.7.1 ואילך.
ניהול של כמה מאגרים
בעזרת הנכס codebase
אפשר לנהל יותר בקלות את הניהול של מספר
מאגרים. נבחן מקרה שבו יש לכם שני מאגרים שונים
שפורסים פונקציות באותו פרויקט Firebase:
$ tree .
├── repoA
│ ├── firebase.json
│ └── functions
│ ├── index.js
│ └── package.json
└── repoB
├── firebase.json
└── functions
├── index.js
└── package.json
בלי הערות Codebase, ה-CLI של Firebase היה מנחה אתכם למחוק פונקציות שהוגדרו במאגר האחר בזמן הפריסה:
$ (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)
כדי למנוע את הבעיה הזו, אפשר להוסיף הערה ייחודית לגבי קוד הבסיס בקטע ההגדרות של הפונקציות ב-firebase.json
בכל מאגר פרויקטים:
# repoA/firebase.json
"functions": {
"codebase": "repo-a"
}
# repoB/firebase.json
"functions": {
"codebase": "repo-b"
}
עם הערת Codebase, ב-CLI של Firebase לא מופיעה יותר בקשה למחוק מוגדרות מחוץ למאגר המיידי שלכם:
$ (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!
ניהול חבילות מקור מרובות (מונורפו)
בעזרת הנכס codebase
אפשר לפשט את הניהול של מקורות מרובים
חבילות במאגר אחד. נבחן מקרה שבו יש ספרייה של פרויקט ב-Firebase עם הגדרות פונקציות שמפוזרות בכמה חבילות משנה:
$ tree .
├── firebase.json
├── teamA
│ ├── index.js
│ └── package.json
└── teamB
├── index.js
└── package.json
ההגדרה הזו מתאימה לתרחישים הבאים לדוגמה:
- יש לכם הגדרת מונורפו עם צוותים שונים שמנהלים את הגדרות הפונקציות שלהם בחבילה מבודדת.
- יש לכם פונקציה עם תלות חיצונית כבדה והפעלה ראשונית ממושכת, ואתם רוצים לבודד את הפונקציה הזו מפונקציות אחרות שרגישות לזמן אחזור.
כדי לתמוך בהגדרת Monrepo בצורה הזו, צריך להגדיר כמה הגדרות של פונקציות
ב-firebase.json
:
"functions": [
{
"source": "teamA",
"codebase": "team-a"
},
{
"source": "teamB",
"codebase": "team-b"
},
]
בעזרת ההגדרות האלה, ה-CLI של Firebase פורס פונקציות מכל החבילות בפקודת פריסה אחת:
$ 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)...
...
אפשר גם לפרוס קוד בסיס (codebase) ספציפי:
$ 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)...
...
כתיבת פונקציות במספר קבצים
בתחילת העבודה עם Cloud Functions, ייתכן בקובץ יחיד:
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!")
לפעמים קשה לנהל את זה בכמה פונקציות. במקום זאת, שתהיה אפשרות לשמור את כל הלוגיקה של כל פונקציה בקובץ נפרד ולהשתמש את קובץ המקור כרשימה של פעולות ייצוא:
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 *
ההגדרה הזו מבוססת על המבנה של ספריית פרויקט כמו:
my-project
├── firebase.json
└── functions
├── fn_impl
│ ├── __init__.py
│ ├── foo.py
│ └── bar.py
├── main.py
└── requirements.txt
fn_impl
: יכול להיות כל שם
__init__.py
: שדה חובה, אבל יכול להיות ריק
קיבוץ פונקציות
בפרויקטים רבים, אפשר להפריד פונקציות לקבוצות לוגיות לפרוס ולתחזק יחד. לדוגמה, נניח שיש לכם קבוצה של פונקציות המשמשות לדיווח על מדדים:
metrics.js
const functions = require('firebase-functions/v1'); exports.usageStats = functions.https.onRequest((request, response) => { // ... }); exports.nightlyReport = functions.https.onRequest((request, response) => { // ... });
אפשר להוסיף את הפונקציות האלה לקבוצה כשמייצאים אותן לקובץ index.js
:
index.js
// Export both functions from metrics.js in the "metrics" group: // - metrics-usageStats // - metrics-nightlyReport exports.metrics = require('./metrics');
כשפונקציות יפורסמו, שם הקבוצה שלהן יופיע כתחילית של השם שלהן. לדוגמה, הפונקציות יהיו בשמות metrics-usageStats
ו-metrics-nightlyReport
.
כשפורסים פונקציות, אפשר להגביל את הפעולה לקבוצה אחת:
firebase deploy --only functions:metrics
השלבים הבאים
למידע נוסף על Cloud Functions, ראו: