وقتی Cloud Functions را در پروژهتان ادغام میکنید، کد شما میتواند گسترش یابد تا شامل توابع مستقل زیادی شود. ممکن است توابع زیادی داشته باشید که بهطور منطقی در یک فایل جا نمیشوند، یا تیمهای مختلف ممکن است گروههای مختلفی از توابع را مستقر کنند، که خطر بازنویسی یا حذف تصادفی توابع تیم دیگر را ایجاد میکند. Cloud Functions روشهای مختلفی برای سازماندهی کد شما ارائه میدهد تا پیمایش و نگهداری توابع شما آسانتر شود.
سازماندهی توابع در پایگاههای کد
میتوانید از ویژگی 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» نسخه ۱۰.۷.۱ و بالاتر پشتیبانی میشود.
مدیریت کردن چند مخزن
ویژگی codebase میتواند به سادهسازی مدیریت چندین مخزن کمک کند. بیایید موردی را بررسی کنیم که در آن دو مخزن مختلف دارید
که توابع را در یک پروژه Firebase مستقر میکنند:
$ tree .
├── repoA
│ ├── firebase.json
│ └── functions
│ ├── index.js
│ └── package.json
└── repoB
├── firebase.json
└── functions
├── index.js
└── package.json
بدون حاشیهنویسیهای پایگاه کد، واسط خط فرمان 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"
}
با حاشیهنویسی پایگاه کد، واسط خط فرمان 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"
},
]
با این پیکربندی، واسط خط فرمان 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)...
...
همچنین میتوانید پایگاه کد خاصی را مستقر کنید:
$ 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;
پایتون
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، به این مقاله مراجعه کنید: