Bootstrap Helpers
Tổng quan
Gói @nx/core cung cấp ba tiện ích bootstrap chuẩn hóa cách mỗi dịch vụ BANA khởi chạy và cách migration cơ sở dữ liệu được thực thi. Các helper này đóng gói vòng đời ứng dụng IGNIS, xử lý lỗi đồng nhất và đảm bảo mọi gói tuân theo cùng trình tự khởi tạo.
| Helper | Mục đích | Nguồn |
|---|---|---|
bootstrapApplication | Khởi chạy một HTTP service | src/helpers/bootstraps/application.ts |
bootstrapMigration | Chạy các quy trình seed/migration cơ sở dữ liệu | src/helpers/bootstraps/migration.ts |
createMigrationProcessLoader | Import động các tệp quy trình migration | src/helpers/migration/process-loader.ts |
MigrationHelper | Thực thi các pha cleanup và migrate với theo dõi trạng thái | src/helpers/migration/helper.ts |
bootstrapApplication
Tạo, khởi tạo, boot và khởi chạy một ứng dụng IGNIS. Khi thành công, nó tùy chọn in banner ASCII. Khi thất bại, nó ghi log lỗi và thoát process với mã 1.
Chữ ký
bootstrapApplication(opts: {
ApplicationClass: new (opts: {
scope: string;
config: IApplicationConfigs;
}) => DefaultApplication;
config: IApplicationConfigs;
options?: { bannerPath?: string };
}): Promise<void>Tham số
| Tham số | Kiểu | Bắt buộc | Mô tả |
|---|---|---|---|
ApplicationClass | Constructor của DefaultApplication | Có | Lớp ứng dụng để khởi tạo |
config | IApplicationConfigs | Có | Host server, port, đường dẫn cơ sở, tùy chọn boot |
options.bannerPath | string | Không | Đường dẫn tuyệt đối đến tệp banner ASCII được in sau khi khởi chạy thành công |
Trình tự Vòng đời
Cách sử dụng
Mỗi điểm khởi đầu gói (src/index.ts) tuân theo cùng mẫu:
// packages/sale/src/index.ts
import { bootstrapApplication } from '@nx/core';
import { resolve } from 'node:path';
import { appConfig, Application } from './application';
bootstrapApplication({
ApplicationClass: Application,
config: appConfig,
options: { bannerPath: resolve(process.cwd(), 'resources/banner.txt') },
});bootstrapMigration
Tạo một instance ứng dụng tối thiểu đủ để kết nối cơ sở dữ liệu, đăng ký MigrationRepository, và chạy tất cả quy trình migration thông qua MigrationHelper.
Chữ ký
bootstrapMigration(opts: {
ApplicationClass: new (opts: {
scope: string;
config: IApplicationConfigs;
}) => DefaultApplication;
getMigrationProcesses: () => Promise<TMigrationProcess[]>;
}): Promise<void>Tham số
| Tham số | Kiểu | Bắt buộc | Mô tả |
|---|---|---|---|
ApplicationClass | Constructor của DefaultApplication | Có | Lớp ứng dụng (cùng lớp dùng để phục vụ) |
getMigrationProcesses | () => Promise<TMigrationProcess[]> | Có | Hàm trả về mảng định nghĩa quy trình migration |
Trình tự Vòng đời
Cách sử dụng
Mỗi điểm khởi đầu migration của gói (src/migrate.ts) tuân theo mẫu này:
// packages/sale/src/migrate.ts
import { bootstrapMigration } from '@nx/core';
import { Application } from './application';
import { getMigrationProcesses } from './migrations/processes/migration-process';
bootstrapMigration({
ApplicationClass: Application,
getMigrationProcesses,
})
.then(() => {
process.exit(0);
})
.catch(err => {
console.error('Cannot migrate database schema', err);
process.exit(1);
});createMigrationProcessLoader
Hàm factory trả về một hàm bất đồng bộ để import động các tệp quy trình migration. Mỗi tệp phải export một TMigrationProcess dưới dạng default export. Các tệp không import được hoặc thiếu default export sẽ bị bỏ qua im lặng.
Chữ ký
createMigrationProcessLoader(opts: {
seedPaths: string[];
importFn: (path: string) => Promise<any>;
}): () => Promise<TMigrationProcess[]>Tham số
| Tham số | Kiểu | Bắt buộc | Mô tả |
|---|---|---|---|
seedPaths | string[] | Có | Danh sách có thứ tự tên tệp migration (không có phần mở rộng) |
importFn | (path: string) => Promise<any> | Có | Hàm import động giải quyết đường dẫn tệp |
Cách sử dụng
// packages/payment/src/migrations/processes/migration-process.ts
import { createMigrationProcessLoader } from '@nx/core';
export const getMigrationProcesses = createMigrationProcessLoader({
seedPaths: [
'payment-0001-seed-vnpay-qr-mms-configuration',
'payment-0002-seed-vnpay-phone-pos-configuration',
],
importFn: path => import(`../processes/${path}.js`),
});Các gói không có dữ liệu seed truyền mảng rỗng:
// packages/sale/src/migrations/processes/migration-process.ts
import { createMigrationProcessLoader } from '@nx/core';
export const getMigrationProcesses = createMigrationProcessLoader({
seedPaths: [],
importFn: path => import(`../processes/${path}.js`),
});TMigrationProcess
Định nghĩa kiểu cho một quy trình migration đơn lẻ.
Định nghĩa Kiểu
type TMigrationProcess<
ExtraOptionsType extends { alwaysRun?: boolean } = { alwaysRun?: boolean },
> = {
name: string;
cleanFn?: (opts: { context: BaseApplication }) => ValueOrPromise<void>;
migrateFn: (opts: { context: BaseApplication }) => ValueOrPromise<void>;
options?: ExtraOptionsType;
};Các Trường
| Trường | Kiểu | Bắt buộc | Mô tả |
|---|---|---|---|
name | string | Có | Định danh migration duy nhất, được lưu trong bảng Migration |
cleanFn | (opts) => void | Không | Hàm dọn dẹp được gọi trước migration (ví dụ: xóa dữ liệu cũ) |
migrateFn | (opts) => void | Có | Logic migration (seed dữ liệu, thay đổi schema, v.v.) |
options.alwaysRun | boolean | Không | Khi true, chạy lại ngay cả khi đã được ghi nhận là SUCCESS trước đó |
Viết một Quy trình Migration
// packages/payment/src/migrations/processes/payment-0001-seed-vnpay-qr-mms-configuration.ts
import { TMigrationProcess } from '@nx/core';
const process: TMigrationProcess = {
name: 'payment-0001-seed-vnpay-qr-mms-configuration',
migrateFn: async ({ context }) => {
const repository = context.get({ key: 'repositories.ConfigurationRepository' });
await repository.create({
data: {
key: 'VNPAY_QR_MMS',
value: JSON.stringify({ /* provider config */ }),
},
});
},
};
export default process;MigrationHelper
Điều phối toàn bộ quy trình migration: dọn dẹp tiếp theo là migration. Nó theo dõi trạng thái của mỗi migration (SUCCESS hoặc FAIL) trong bảng cơ sở dữ liệu Migration và hỗ trợ các hook vòng đời.
Quy trình Làm việc
Các Hook Migration
Các hook cho phép mã bên ngoài quan sát hoặc mở rộng vòng đời migration:
type TMigrationHooks = {
beforeCleanup?: (opts: { context: BaseApplication; processes: TMigrationProcess[] }) => void;
afterCleanup?: (opts: { context: BaseApplication; processes: TMigrationProcess[] }) => void;
beforeMigration?: (opts: { context: BaseApplication; processes: TMigrationProcess[] }) => void;
afterMigration?: (opts: { context: BaseApplication; processes: TMigrationProcess[] }) => void;
onMigrationSuccess?: (opts: { name: string; process: TMigrationProcess; duration: number }) => void;
onMigrationError?: (opts: { name: string; process: TMigrationProcess; error: unknown }) => void;
};| Hook | Thời điểm | Nhận được |
|---|---|---|
beforeCleanup | Trước khi pha dọn dẹp bắt đầu | Ngữ cảnh ứng dụng, tất cả quy trình |
afterCleanup | Sau khi tất cả hàm dọn dẹp hoàn thành | Ngữ cảnh ứng dụng, tất cả quy trình |
beforeMigration | Trước khi pha migration bắt đầu | Ngữ cảnh ứng dụng, tất cả quy trình |
afterMigration | Sau khi tất cả hàm migration hoàn thành | Ngữ cảnh ứng dụng, tất cả quy trình |
onMigrationSuccess | Sau khi một quy trình đơn lẻ thành công | Tên quy trình, định nghĩa quy trình, thời lượng (ms) |
onMigrationError | Sau khi một quy trình đơn lẻ thất bại | Tên quy trình, định nghĩa quy trình, lỗi |
Tất cả hook được bọc trong try/catch nội bộ. Hook thất bại sẽ ghi log cảnh báo nhưng không dừng migration.
Theo dõi Trạng thái
MigrationHelper sử dụng MigrationRepository (được đăng ký tự động bởi bootstrapMigration) để lưu trữ kết quả của mỗi quy trình:
| Trạng thái | Ý nghĩa |
|---|---|
SUCCESS | Migration hoàn thành không có lỗi |
FAIL | Migration ném ra lỗi |
UNKNOWN | Trạng thái ban đầu trước khi thực thi |
Trong các lần chạy tiếp theo, các quy trình có trạng thái SUCCESS sẽ bị bỏ qua trừ khi options.alwaysRun được đặt thành true.
Áp dụng trong Các Gói
Mỗi gói backend trong BANA sử dụng các helper này. Bảng dưới đây cho thấy mẫu áp dụng trên tất cả các gói:
| Gói | index.ts | migrate.ts | Đường dẫn Seed |
|---|---|---|---|
@nx/sale | bootstrapApplication | bootstrapMigration | [] |
@nx/identity | bootstrapApplication | bootstrapMigration | (identity seeds) |
@nx/commerce | bootstrapApplication | bootstrapMigration | (commerce seeds) |
@nx/inventory | bootstrapApplication | bootstrapMigration | (inventory seeds) |
@nx/finance | bootstrapApplication | bootstrapMigration | (finance seeds) |
@nx/payment | bootstrapApplication | bootstrapMigration | payment-0001-*, payment-0002-* |
@nx/signal | bootstrapApplication | N/A (stateless) | N/A |
Tài liệu Liên quan
- Tham chiếu IGNIS Bootstrapping -- Giao diện vòng đời ứng dụng và tùy chọn boot
- Khái niệm IGNIS Application -- Tạo và cấu hình ứng dụng
- DefaultApplication -- Lớp cơ sở được sử dụng bởi
ApplicationClass - Database Migrations -- Chi tiết schema và bảng migration