Tổ chức nhiều hàm


Khi bạn tích hợp Cloud Functions vào dự án của mình, mã có thể mở rộng thành chứa nhiều hàm độc lập. Có thể bạn có quá nhiều hàm khớp một cách hợp lý trong một tệp, hoặc các nhóm khác nhau có thể triển khai các nhóm khác nhau hàm, tạo ra nguy cơ một nhóm ghi đè hoặc vô tình xoá chức năng của nhóm khác. Cloud Functions cung cấp những cách thức khác nhau để sắp xếp để giúp điều hướng và duy trì các hàm của bạn dễ dàng hơn.

Sắp xếp các hàm trong cơ sở mã

Bạn có thể sử dụng thuộc tính codebase của đối tượng cấu hình hàm trong firebase.json để quản lý một tập hợp lớn gồm các hàm trên nhiều kho lưu trữ hoặc gói con trong một thiết lập monorepo kho lưu trữ duy nhất:

# 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.
}

Thuộc tính codebase được hỗ trợ trong Firebase CLI phiên bản 10.7.1 trở lên.

Quản lý nhiều kho lưu trữ

Thuộc tính codebase có thể giúp đơn giản hoá việc quản lý nhiều kho lưu trữ mới. Hãy cùng tìm hiểu trường hợp bạn có hai kho lưu trữ khác nhau triển khai các hàm cho cùng một dự án Firebase:

$  tree .
├── repoA
│   ├── firebase.json
│   └── functions
│       ├── index.js
│       └── package.json
└── repoB
    ├── firebase.json
    └── functions
        ├── index.js
        └── package.json

Nếu không có chú thích cơ sở mã, Firebase CLI có thể đã nhắc bạn xoá các hàm được xác định trong kho lưu trữ khác tại thời điểm triển khai:

$ (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)

Bạn có thể tránh sự cố này bằng cách thêm chú thích cơ sở mã duy nhất trong phần cấu hình các hàm của firebase.json trong mỗi kho lưu trữ dự án:

# repoA/firebase.json
"functions": {
  "codebase": "repo-a"
}

# repoB/firebase.json
"functions": {
  "codebase": "repo-b"
}

Với chú thích cơ sở mã, Firebase CLI sẽ không còn nhắc bạn xoá nữa các hàm được xác định bên ngoài kho lưu trữ tức thì:

$ (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!

Quản lý nhiều gói nguồn (monorepo)

Thuộc tính codebase có thể giúp đơn giản hoá việc quản lý nhiều nguồn trong một kho lưu trữ duy nhất. Hãy cùng tìm hiểu một trường hợp mà bạn dùng Firebase thư mục dự án có định nghĩa hàm được trải rộng trên một số gói con:

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

Chế độ thiết lập này phù hợp với các trường hợp sử dụng sau:

  • Bạn thiết lập monorepo và có các nhóm khác nhau quản lý định nghĩa chức năng của riêng họ trong một gói riêng.
  • Bạn có một hàm có phần phụ thuộc lớn bên ngoài và quá trình khởi chạy chạy trong thời gian dài, đồng thời muốn tách biệt hàm đó với các hàm khác có nhạy cảm về độ trễ.

Để hỗ trợ thiết lập monrepo như thế này, hãy xác định cấu hình nhiều hàm trong firebase.json:

"functions": [
  {
    "source": "teamA",
    "codebase": "team-a"
  },
  {
    "source": "teamB",
    "codebase": "team-b"
  },
]

Với cấu hình này, Giao diện dòng lệnh (CLI) của Firebase sẽ triển khai các hàm từ tất cả các gói trong một lệnh triển khai:

$ 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)...
...

Bạn cũng có thể triển khai một cơ sở mã cụ thể:

$ 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)...
...

Viết hàm trong nhiều tệp

Khi bắt đầu với Cloud Functions, bạn có thể ưu tiên trong một tệp duy nhất:

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!")

Bạn có thể gặp khó khăn khi quản lý việc này bằng nhiều chức năng. Thay vào đó, bạn có thể đặt tất cả logic cho mỗi hàm trong tệp riêng và sử dụng tệp nguồn làm danh sách tệp xuất:

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;

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 *

Chế độ thiết lập này giả định cấu trúc thư mục dự án như sau:

my-project
├── firebase.json
└── functions
    ├── fn_impl
    │   ├── __init__.py
    │   ├── foo.py
    │   └── bar.py
    ├── main.py
    └── requirements.txt

fn_impl: Có thể dùng bất kỳ tên nào

__init__.py: Bắt buộc, nhưng có thể để trống

Hàm nhóm

Trong nhiều dự án, các hàm có thể được tách thành các nhóm logic được triển khai và duy trì cùng nhau. Ví dụ: bạn có thể có một nhóm hàm dùng để báo cáo chỉ số:

metric.js


const functions = require('firebase-functions');
exports.usageStats = functions.https.onRequest((request, response) => {
  // ...
});
exports.nightlyReport = functions.https.onRequest((request, response) => {
  // ...
});

Bạn có thể đặt các hàm này vào một nhóm khi xuất chúng trong index.js tệp:

index.js


// Export both functions from metrics.js in the "metrics" group:
//  - metrics-usageStats
//  - metrics-nightlyReport
exports.metrics = require('./metrics');

Khi được triển khai, các hàm sẽ có tiền tố là tên nhóm, vì vậy trong ví dụ này, các hàm sẽ được đặt tên là metrics-usageStatsmetrics-nightlyReport.

Khi triển khai các chức năng, bạn có thể giới hạn thao tác trong một nhóm:


firebase deploy --only functions:metrics

Các bước tiếp theo

Để tìm hiểu thêm về Cloud Functions, hãy xem: