@ 6thbridge/ 使用文档
一个用于Node.js应用程序的综合性TypeScript通用库,为包括数据库操作,缓存,消息,日志等共同开发任务提供可再使用的组件.
目录
安装
# Using npm
npm install @6thbridge/utils
# Using yarn
yarn add @6thbridge/utils
依赖关系
此套件包括以下关键依赖性:
- 数据库数字 :
mongoose, , , , ,ioredismongoose-paginate-v2 - 通讯数字 :
amqplib, , , , ,kafkajsamqp-connection-manager - 公用事业数字 :
lodash, (中文(简体) ),dayjs, (中文(简体) ),joi, (中文(简体) ),axios - 监测:,,
rollbar@opentelemetry/auto-instrumentations-node
快速启动
import {
HelperUtil,
ReferenceUtil,
RedisClient,
RabbitMQClient,
MongoDBRepository,
logger
} from '@6thbridge/utils';
// Generate a reference
const reference = ReferenceUtil.generateReference('production');
// Use Redis
const redis = RedisClient.getInstance();
await redis.connect({ url: 'redis://localhost:6379' });
// Clean data
const cleanData = HelperUtil.removeFieldsWithEmptyValue(data);
// Log information
logger.info('Application started', { reference });
伙伴 API 密钥和路径
见 伙伴 API 密钥和路径 页:1
can(['partner'], []),用户服务关键验证合同, PartnerContextEntity, (中文(简体) ),
和快递线路注册实例.
核心单元
🔧 公用事业
用于数据操作、参考生成和共同操作的基本功能.
- 辅助工具: 数据清理、活动记录、同步设施
- 参考UTI: 参考和UUID生成
- 电话号码格式化: 国际电话号码格式化
🗄️ 数据库
数据库抽象层和寄存器模式.
- MongoDB 仓库: 蒙戈DB与Mongoose的业务
- Redis 整合: 缓存和会话管理
📨 经纪人
事件驱动架构的信息代理执行 .
- 兔子的密度: AMQP 与兔子MQ的通讯
- KafkaJS 一体化: Apache Kafka 消息流
💾 缓存
改进业绩的缓存解决方案.
- 冗余客户: 基于 Redis 的缓存, 有集群支持
- 节点缓存: 用于轻量级应用的内装箱
📝 锁定器
综合采伐制度分多层和集成.
- 结构化日志: JSON 格式日志
- 多重运输: 控制台、文件和外部服务记录
- 跟踪错误:与监测服务相结合
🛡️ 中间软件
Express.js 用于通用功能的中间软件.
- 认证: JWT 和 API 密钥验证
- 验证: 请求/答复确认
- 处理错误: 集中错误处理
- 限制费率: 以服务为主的 ioredis 连接重置请求限制
共享费率限制符
import Redis from 'ioredis';
import { Ratelimiter } from '@6thbridge/utils';
const redisClient = new Redis(process.env.REDIS_URL);
Ratelimiter.configure({
redisClient,
serviceName: 'my-service',
});
const loginLimiter = Ratelimiter.limit({
keyPrefix: 'login',
numberOfTries: 5,
skipSuccessfulRequests: true,
});
// Use loginLimiter as Express middleware on your login route.
默认的限制是30分钟窗口内每个IP五次尝试. 越狱了
返回 HTTP 429 与 errorCode: 'RateLimitExceeded'设置 skipSuccessfulRequests
从计数中排除成功的响应; 它默认为 false。 。 。 .
打电话 Ratelimiter.configure({ redisClient, serviceName }) 启动前
创建限制器。 它接受一个现有的标准 ioredis Redis 连接;
呼叫服务拥有连接设置和关闭。 通话 limit 在此之前
配置会丢出一个错误。 个人 limit 电话不再带客户.
serviceName 是可选的,默认为 process.env.APP_NAME这样
Ratelimiter.configure({ redisClient }) 足够当 APP_NAME 已经设定.
明确 serviceName 以优先为准。 配置抛出( N)
提供服务名称.
每个 Redis 键开头 rl:<serviceName>:设置特定路径 keyPrefix
在服务中隔离计数器;其默认值为 rate-limit-key。例如,
上方的登录限制 rl:my-service:login:<normalized-ip>服务
不同名称可以安全共享 Redis. 现有限制保留配置
它们被创造,如果 configure 又被调用.
可选同步 keyGenerator(req, res) 替换默认密钥,
包括 keyPrefix,同时保留服务前缀。 没有它
限制用途 res.locals.ip,则
cf-connecting-ip, (中文(简体) ), x-forwarded-for,则 ip 页眉,或 req.ip按照顺序,
并规范IPv6地址。 配置可信任的代理来提供这些值 .
该类也作为 middlewares.Ratelimiter 从包根.
📊 监测
应用监测和可观察性工具.
- 打开几何: 分布式跟踪
- Rollbar 整合: 错误监测和提醒
API 参考
辅助工具
class HelperUtil {
// Async utility
static async sleep(durationInMs: number = 1000): Promise<void>
// Data cleaning
static removeFieldsWithEmptyValue(value: any): any
// Activity logging
static async saveActivityLog(activityLog: SaveActivityLogDTO, options?: any): Promise<void>
}
参考UTI
class ReferenceUtil {
// Generate environment-specific reference
static generateReference(env: string): string
// Generate reference with custom prefix
static generateReferenceWithPrefix(env: string, prefix: string): string
// Generate UUID
static generateUUID(options?: any): string
}
冗余客户
class RedisClient {
// Singleton pattern
static getInstance(): RedisClient
static resetInstance(): void
// Connection management
connect(config?: RedisConnect): Commander
// Redis operations
static getRedis(): Commander
}
兔子的密度
class RabbitMQClient {
// Singleton pattern
static getInstance(): RabbitMQClient
static resetInstance(): void
// Connection and messaging
connect(config: RabbitMQConnectConfig): AmqpConnectionManager
static async sendToQueue(queueName: string, payload: any, options?: PublishOptions): Promise<any>
static async publishToExchange(exchangeName: string, routeKey: string, payload: any, options?: PublishOptions): Promise<any>
// Message consumption
static listen(queueName: string, options: any, callback: Function): Promise<void>
}
MongoDB 仓库
class MongoDBRepository {
constructor(Model: TypedModel<any>)
// CRUD operations
create(payload: Record<string, any>, options?: CreateOptions): Promise<any>
findById(id: string, projection?: ProjectionType<any>, options?: QueryOptions): Promise<any>
findOne(condition: Record<string, any>, sort?: Record<string, number>, options?: FindOptions): Promise<any>
find(condition: Record<string, any>, sort?: Record<string, any>, options?: FindOptions): Promise<any>
// Advanced operations
paginate(condition: Record<string, any>, sort?: Record<string, any>, options?: FindOptions): Promise<PaginateResult<any>>
updateOne(query: Record<string, any>, update: Record<string, any>, options?: MongooseOptions): Promise<any>
bulkWrite(bulkWritePayload: any): Promise<any>
}
实例
基本用途实例
数据清理
import { HelperUtil } from '@6thbridge/utils';
const dirtyData = {
name: 'John Doe',
email: '',
phone: null,
address: undefined,
age: 30
};
const cleanData = HelperUtil.removeFieldsWithEmptyValue(dirtyData);
// Result: { name: 'John Doe', age: 30 }
参考生成
import { ReferenceUtil } from '@6thbridge/utils';
// Production reference
const prodRef = ReferenceUtil.generateReference('production');
// Example: L20240101120000ABCDE
// Development reference with prefix
const devRef = ReferenceUtil.generateReferenceWithPrefix('development', 'ORDER');
// Example: DORDER20240101120000ABCDE
重做操作
import { RedisClient } from '@6thbridge/utils';
async function cacheExample() {
const redis = RedisClient.getInstance();
redis.connect({
url: 'redis://localhost:6379',
keepAlive: true
});
// Cache operations
await RedisClient.getRedis().set('user:123', JSON.stringify({ name: 'John' }));
const user = await RedisClient.getRedis().get('user:123');
}
信件队列
import { RabbitMQClient } from '@6thbridge/utils';
async function messagingExample() {
const broker = RabbitMQClient.getInstance();
broker.connect({
url: 'amqp://localhost:5672',
queues: [
{ queueName: 'user.created' }
],
exchanges: [],
exchangeBindings: []
});
// Send message
await RabbitMQClient.sendToQueue('user.created', {
userId: '123',
event: 'USER_CREATED',
timestamp: new Date()
});
// Listen for messages
RabbitMQClient.listen('user.created', {}, (message, options) => {
console.log('Received:', JSON.parse(message));
options.ack();
});
}
电话号码格式化
import { formatPhoneNumber, formatPhoneNumberArray } from '@6thbridge/utils';
// Single phone number
let phoneNumber = '08012345678';
phoneNumber = formatPhoneNumber(phoneNumber, 'NG');
console.log(phoneNumber); // 2348012345678
// Multiple phone numbers
let phoneNumbers = ['08012345678', '08012345679'];
phoneNumbers = formatPhoneNumberArray(phoneNumbers, 'NG');
console.log(phoneNumbers); // ['2348012345678', '2348012345679']
日志
import { logger } from '@6thbridge/utils';
// Different log levels
logger.error('Database connection failed', { error: 'Connection refused' });
logger.warn('High memory usage detected', { usage: '85%' });
logger.info('User logged in', { userId: '123' });
logger.debug('Processing request', { requestId: 'req-456' });
// Exception logging
try {
// risky operation
} catch (error) {
logger.exception(error, { context: 'user-registration' });
}
环境变量
库支持各种环境变量配置 :
# Redis Configuration
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
REDIS_PASSWORD=your_password
REDIS_URL=redis://localhost:6379
REDIS_CLUSTER_URL=redis://node1:6379,redis://node2:6379
# RabbitMQ Configuration
RABBITMQ_URL=amqp://localhost:5672
RABBITMQ_CLUSTER_URL=amqp://node1:5672,amqp://node2:5672
# Application Configuration
APP_NAME=your-app-name
TZ=Africa/Lagos
LOG_OUT=1
# Service URLs
USER_SERVICE_URL=http://user-service:3000
测试
该图书馆包括使用Jest的综合测试套房:
# Run all tests
yarn test
# Run tests in watch mode
yarn test --watch
# Run tests with coverage
yarn test --coverage
# Run specific test file
yarn test reference.util.test.ts
写入测试
import { ReferenceUtil } from '@6thbridge/utils';
describe('ReferenceUtil', () => {
it('should generate production reference', () => {
const ref = ReferenceUtil.generateReference('production');
expect(ref).toMatch(/^L\d{14}[A-Z]{5}$/);
});
});
类型脚本支持
此库用 TypeScript 写成, 并提供完整类型定义 :
import {
RedisConnect,
RabbitMQConnectConfig,
SaveActivityLogDTO,
MongooseOptions
} from '@6thbridge/utils';
// Type-safe configuration
const redisConfig: RedisConnect = {
url: 'redis://localhost:6379',
keepAlive: true,
heartbeat: 30
};
业绩考量
- 连接集合: Redis 和 RabbitMQ 客户端使用连接集合
- 单子图案: 数据库和缓存客户端遵循单通模式
- 懒惰装入: 仅在需要时才建立连接
- 内存管理: 适当清理和关闭连接
处理错误
库执行全面的错误处理 :
try {
await RedisClient.getRedis().set('key', 'value');
} catch (error) {
logger.exception(error, { operation: 'redis-set' });
}
捐款
- 叉子存储器
- 创建您的特性分支( E)
git checkout -b feature/amazing-feature(中文(简体) ) - 提交更改( E)
git commit -m 'Add amazing feature'(中文(简体) ) - 推向分行(
git push origin feature/amazing-feature(中文(简体) ) - 打开拉请求
开发设置
# Clone repository
git clone https://github.com/DexlerNG/bridge-utils-package.git
# Install dependencies
yarn install
# Run tests
yarn test
# Build library
yarn build
许可证
这个项目根据ICC许可证颁发许可证.
贡献者
支助
欲获取支持和提问,请在 GitHub 存储器上打开一个问题 . 说明:此图书馆被积极维护和用于生产环境. 请检查date=中的日期值 (帮助) 发布部分。 。 。 .
出版
将请求拉入 main 将软件包发布到 npm 和 GitHub 软件包中,除非牵引请求有 skip-publish 标签。 合并前跳出版本 。 添加 publish-test-version 到此寄存器库的牵引请求, 将测试版本发布到 GitHub 包 .
仓库行动需要保密:
NPM_TOKEN: npm 授权发布符@6thbridge/utils。 。 。 .GH_PACKAGES_TOKEN: GitHub 个人访问信使(经典)write:packages权限6thbridge软件包命名空间。 该寄存器目前属于DexlerNG自动GITHUB_TOKEN无法向该单独的命名空间发布 .
要安装 GitHub 软件包副本, 认证为 npm.pkg.github.com 并配置 @6thbridge:registry=https://npm.pkg.github.com 在您的 npm 配置中。 寻常 npm install @6thbridge/utils 命令使用 npm.
日志分批
继续打电话 logger.info(), (中文(简体) ), logger.error()等 (中文(简体) ). 日志共享数组并冲出
在100条信息或1秒后. configureLogBatching({ batchSize: 100, flushIntervalMs: 1000 }) 更改这些默认值。 每个冲出一个纯数组
给现有的RabitMQ实例,或 POST /v1/logs 当不存在时.
运输选择发生在冲刷时。 向运输故障报告
stderr; 没有背景重试机制 .
打电话 registerLoggingShutdown() 一次登记SIGTERM/SIGINT冲洗,或
await flushLogs() 明确在关闭运输工具或离开之前。 登记
只冲出库缓冲;它不关闭提供者或退出进程.
未注册关闭时没有自动信号收听器.
在释放更新的日志之前, 在公用事业服务中部署阵列支持 .
向公用事业部门发送10,000个测试日志:
UTILITY_SERVICE_URL=https://your-utility-service yarn test:logger
脚本使用两个日志例并分批分出100个. 它不会开始一个 服务器或验证收件; 检查收到的日志的效用服务.