تنظيم وظائف متعددة


عندما تقوم بدمج وظائف السحابة في مشروعك، يمكن أن تتوسع التعليمات البرمجية الخاصة بك لتحتوي على العديد من الوظائف المستقلة. قد يكون لديك عدد كبير جدًا من الوظائف بحيث لا يمكن احتواؤها بشكل معقول في ملف واحد، أو قد تقوم فرق مختلفة بنشر مجموعات مختلفة من الوظائف، مما يؤدي إلى خطر قيام فريق واحد بالكتابة فوق وظائف فريق آخر أو حذفها عن طريق الخطأ. توفر Cloud Functions طرقًا مختلفة لتنظيم التعليمات البرمجية الخاصة بك لتسهيل التنقل في وظائفك وصيانتها.

تنظيم الوظائف في قواعد التعليمات البرمجية

يمكنك استخدام خاصية codebase لكائن تكوين الوظائف في firebase.json لإدارة مجموعة كبيرة من الوظائف عبر مستودعات متعددة أو حزم فرعية ضمن إعداد monorepo لمستودع تخزين واحد:

# 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 مدعومة في الإصدار 10.7.1 من Firebase CLI والإصدارات الأحدث.

إدارة مستودعات متعددة

يمكن أن تساعد خاصية 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!

إدارة حزم المصادر المتعددة (monorepo)

يمكن أن تساعد خاصية codebase في تبسيط إدارة حزم المصدر المتعددة في مستودع واحد. دعونا نتفحص حالة حيث يكون لديك دليل مشروع Firebase مع تعريفات الوظائف المنتشرة عبر عدة حزم فرعية:

$  tree .
├── firebase.json
├── teamA
│   ├── index.js
│   └── package.json
└── teamB
    ├── index.js
    └── package.json

يناسب هذا الإعداد حالات الاستخدام التالية:

  • لديك إعداد monorepo ولديك فرق مختلفة تدير تعريفات الوظائف الخاصة بها في حزمة معزولة.
  • لديك وظيفة ذات تبعية خارجية كبيرة وتهيئة طويلة الأمد، وتريد عزل هذه الوظيفة عن الوظائف الأخرى الحساسة لزمن الوصول.

لدعم إعداد 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');
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');
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;

بايثون

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');
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

الخطوات التالية

لمعرفة المزيد حول وظائف السحابة، راجع: