Các Thành phần Core
Tổng quan
Gói @nx/core cung cấp các lớp cơ sở thiết yếu, các helper và các thành phần hạ tầng mà tất cả dịch vụ backend đều kế thừa. Các thành phần này chuẩn hóa việc thiết lập ứng dụng, mẫu truy cập dữ liệu, giao tiếp giữa các dịch vụ, nhắn tin thời gian thực và kiến trúc hướng sự kiện.
Liên kết Nhanh
| Thành phần | Mô tả | Tham chiếu IGNIS |
|---|---|---|
| DefaultApplication | Lớp ứng dụng cơ sở với xác thực, CORS, Swagger và health check | Application |
| SoftDeletableRepository | Repository với mẫu xóa mềm (dấu thời gian deletedAt) | Repositories |
| BaseSocketEventService | Service cơ sở để phát sự kiện WebSocket thông qua WebSocketEmitter | WebSocket |
| IdentityNetworkService | HTTP client liên dịch vụ cho xác thực identity | Network Helper |
| Bootstrap Helpers | Các helper bootstrapApplication() và bootstrapMigration() cho điểm khởi đầu | Bootstrapping |
| RedisConnectionFactory | Quản lý kết nối Redis (chế độ đơn hoặc cluster) | Redis Helper |
| Event Bus | Trừu tượng hóa nhắn tin pub/sub với Redis Pub/Sub adapter | - |
Phân cấp Thành phần
Phân cấp Repository
BaseSocketEventService
Service cơ sở để phát sự kiện WebSocket thông qua WebSocketEmitter của IGNIS. Được sử dụng bởi @nx/signal để triển khai SignalEventService.
Nguồn: packages/core/src/base/service/base-socket-event.service.ts
| Phương thức | Chữ ký | Mô tả |
|---|---|---|
broadcast | broadcast<T>({ topic, data }): Promise<void> | Gửi đến tất cả client trong room mặc định |
sendToRoom | sendToRoom<T>({ room, topic, data }): Promise<void> | Gửi đến tất cả client trong một room cụ thể |
isReady | isReady(): boolean | Kiểm tra xem binding WebSocketEmitter có sẵn không |
emitter | get emitter(): WebSocketEmitter | Getter lazy cho emitter từ DI container |
Cách sử dụng:
import { BaseSocketEventService } from '@nx/core';
import { BaseApplication, inject } from '@venizia/ignis';
export class MyEventService extends BaseSocketEventService {
constructor(
@inject({ key: CoreBindings.APPLICATION_INSTANCE })
application: BaseApplication,
) {
super(application, {
scope: MyEventService.name,
emitterBindingKey: '@my-package/websocket-emitter',
});
}
async notifyOrderCreated(orderId: string) {
await this.broadcast({ topic: 'order:created', data: { orderId } });
}
}Xem IGNIS WebSocket Component để biết chi tiết cấu hình emitter.
Bootstrap Helpers
Các hàm helper chuẩn hóa điểm khởi đầu ứng dụng và migration trên tất cả các gói.
Nguồn: packages/core/src/helpers/bootstraps/
bootstrapApplication
Tạo và khởi chạy ứng dụng với hiển thị banner và tắt máy an toàn.
// packages/sale/src/index.ts
import { bootstrapApplication } from '@nx/core';
import { Application } from './application';
import { appConfig } from './common/app-config';
bootstrapApplication({
ApplicationClass: Application,
config: appConfig,
options: { bannerPath: resolve(__dirname, '../resources/banner.txt') },
});bootstrapMigration
Tạo ứng dụng ở chế độ migration và chạy các quy trình seed/migration.
// 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,
});createMigrationProcessLoader
Factory để tải các tệp quy trình migration từ một thư mục.
// packages/sale/src/migrations/processes/migration-process.ts
import { createMigrationProcessLoader } from '@nx/core';
export const getMigrationProcesses = createMigrationProcessLoader({
seedPaths: ['sale-0001-seed-order-statuses'],
importFn: path => import(`../processes/${path}.js`),
});Xem IGNIS Bootstrapping để biết vòng đời framework cơ bản.
RedisConnectionFactory
Factory tĩnh để tạo kết nối Redis ở chế độ đơn hoặc cluster.
Nguồn: packages/core/src/helpers/redis/redis-connection.factory.ts
| Phương thức | Chữ ký | Mô tả |
|---|---|---|
create | static create(opts: TRedisConnectionOptions): DefaultRedisHelper | Tạo RedisHelper (đơn) hoặc RedisClusterHelper (cluster) |
parseClusterNodes | static parseClusterNodes({ raw }): Array<{ host, port }> | Phân tích "host1:port1,host2:port2" thành mảng đối tượng node |
Chế độ đơn:
import { RedisConnectionFactory } from '@nx/core';
const redis = RedisConnectionFactory.create({
mode: 'single',
name: 'cache-redis',
host: 'localhost',
port: 6379,
password: 'secret',
database: 0,
maxRetry: 5,
autoConnect: false,
});Chế độ cluster:
const redis = RedisConnectionFactory.create({
mode: 'cluster',
name: 'cache-redis-cluster',
nodes: RedisConnectionFactory.parseClusterNodes({
raw: 'node1:6379,node2:6379,node3:6379',
}),
password: 'secret',
});Xem IGNIS Redis Helper để biết chi tiết API
RedisHelpervàRedisClusterHelper.
Event Bus
Trừu tượng hóa nhắn tin pub/sub với mẫu adapter có thể cắm thay. Hiện tại cung cấp adapter Redis Pub/Sub.
Nguồn: packages/core/src/helpers/event-bus/
Giao diện IEventBus
interface IEventBus {
publish<T>(opts: { channel: string; data: T }): Promise<void>;
subscribe<T>(opts: { channel: string; handler: (data: T) => Promise<void> }): Promise<void>;
unsubscribe(opts: { channel: string }): Promise<void>;
disconnect(): Promise<void>;
}Phong bì IEventBusMessage
Mỗi thông điệp được xuất bản được bọc trong một phong bì tiêu chuẩn:
interface IEventBusMessage<T = unknown> {
id: string; // Snowflake ID
type: string; // Tên kênh
publishedAt: string; // Dấu thời gian ISO
data: T; // Dữ liệu payload
metadata?: Record<string, unknown>;
}RedisPubSubAdapter
Adapter mặc định sử dụng hai instance RedisHelper (một publisher, một subscriber).
import { RedisPubSubAdapter } from '@nx/core';
const eventBus = new RedisPubSubAdapter({
publisher: publisherRedisHelper,
subscriber: subscriberRedisHelper,
});
// Subscribe
await eventBus.subscribe({
channel: 'payment:success',
handler: async (data) => {
console.log('Payment succeeded:', data);
},
});
// Xuất bản
await eventBus.publish({
channel: 'payment:success',
data: { orderId: '123', amount: 50000 },
});| Phương thức | Mô tả |
|---|---|
publish({ channel, data }) | Bọc dữ liệu trong IEventBusMessage và xuất bản lên Redis |
subscribe({ channel, handler }) | Đăng ký handler cho một kênh (idempotent) |
unsubscribe({ channel }) | Xóa handler và hủy đăng ký khỏi Redis |
disconnect() | Hủy đăng ký tất cả kênh và đóng kết nối Redis |
getSubscriptions() | Trả về danh sách tên kênh đã đăng ký |
getHandlerCount() | Trả về số lượng handler đã đăng ký |
isSubscribed(channel) | Kiểm tra xem một kênh có đăng ký đang hoạt động không |
WARNING
Redis Pub/Sub không hỗ trợ xác nhận hoặc thử lại thông điệp. Nếu handler ném lỗi, thông điệp sẽ bị mất. Hãy triển khai logic thử lại trong handler nếu cần, hoặc sử dụng BullMQ queue để đảm bảo gửi ít nhất một lần.
Các bước Tiếp theo
- Khám phá vòng đời và cấu hình DefaultApplication chi tiết
- Tìm hiểu về mẫu xóa mềm SoftDeletableRepository
- Xem lại Network Services cho giao tiếp liên dịch vụ
- Đọc Bootstrap Helpers cho các điểm khởi đầu ứng dụng và migration
- Đọc BaseSocketEventService cho phát sự kiện WebSocket
- Đọc RedisConnectionFactory cho quản lý kết nối Redis
- Đọc Event Bus cho nhắn tin pub/sub với Redis