سازمان‌دهی چند تابع (نسل اول)

هم‌زمان با ادغام 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

این راه‌اندازی برای موارد استفاده زیر مناسب است:

  • راه‌اندازی monorepo دارید و تیم‌های مختلف تعاریف تابع خودشان را در بسته‌ای مجزا مدیریت می‌کنند.
  • تابعی دارید که وابستگی خارجی سنگینی دارد و مقداردهی اولیه آن طول می‌کشد، و می‌خواهید آن تابع را از دیگر توابع حساس به تأخیر جدا کنید.

برای پشتیبانی از تنظیمات monorepo مانند این، پیکربندی‌های چند تابع را در 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، به موارد زیر مراجعه کنید: