monita-libs v0.0.6
Monita Microservices Libraries
This directory contains shared libraries used across the Monita microservices architecture. Below is a guide on how to use each library in your services.
Auth Library (@/libs/auth
)
The auth library provides OTP (One-Time Password) functionality.
Usage
import { OtpModule, OtpService } from '@/libs/auth';
@Module({
imports: [
OtpModule
]
})
// In your service:
constructor(private readonly otpService: OtpService) {}
// Generate OTP
const result = await this.otpService.generateOtp(phone, purpose, options);
// Verify OTP
const isValid = await this.otpService.verifyOtp({
phone,
otp,
reference,
purpose
});
Cache Library (@/libs/cache
)
Redis-based caching implementation for the microservices.
Usage
import { CacheModule, CacheService } from '@/libs/cache';
@Module({
imports: [
CacheModule.register()
]
})
// In your service:
constructor(private readonly cacheService: CacheService) {}
// Basic cache operations
await this.cacheService.set('key', 'value', ttlSeconds);
const value = await this.cacheService.get('key');
await this.cacheService.del('key');
// Hash operations
await this.cacheService.hset('key', 'field', 'value');
const hashValue = await this.cacheService.hget('key', 'field');
const allValues = await this.cacheService.hgetall('key');
NATS Library (@/libs/nats
)
Message queue implementation using NATS for inter-service communication.
Environment Variables
Each service should have these NATS-related environment variables:
# Required
NATS_URL=nats://localhost:4222
NATS_SERVICE_QUEUE=service_queue # Replace 'service' with your service name (e.g., payment_queue)
# Optional with defaults
NATS_TIMEOUT=5000
NATS_RECONNECT=true
NATS_RECONNECT_TIME_WAIT=2000
NATS_MAX_RECONNECT_ATTEMPTS=10
Basic Usage
import { NatsModule, NatsService, NatsMessageDto } from '@/libs/nats';
// Register in your module (Simple)
@Module({
imports: [
NatsModule.register({
transport: Transport.NATS,
options: {
servers: ['nats://localhost:4222'],
queue: 'my_service_queue',
},
}),
],
})
// Or register with async configuration
@Module({
imports: [
NatsModule.registerAsync({
imports: [ConfigModule],
useFactory: (configService: ConfigService) => ({
transport: Transport.NATS,
options: {
servers: [configService.get('NATS_URL')],
queue: configService.get('NATS_SERVICE_QUEUE'),
},
}),
inject: [ConfigService],
}),
],
})
// In your service:
constructor(private readonly natsService: NatsService) {}
// Send a message
const message: NatsMessageDto = {
pattern: 'your.pattern',
data: { your: 'data' },
};
await this.natsService.send(message);
// Emit an event
await this.natsService.emit(message);
Using Decorators
import { NatsEventPattern } from '@/libs/nats';
@Controller()
export class YourController {
@NatsEventPattern('your.pattern')
async handleEvent(data: any) {
// Handle the event with automatic logging
}
}
Advanced Features
Automatic Logging: All NATS communications are automatically logged with timing information.
Error Handling: Built-in error handling and retries.
Timeouts: Configurable timeouts for all operations.
Connection Management: Automatic connection management with reconnection support.
Type Safety: Use
NatsMessageDto
for type-safe message handling.
// Example with type safety
interface PaymentData {
amount: number;
currency: string;
}
const message: NatsMessageDto = {
pattern: 'payment.process',
data: {
amount: 100,
currency: 'USD',
} as PaymentData,
};
const result = await this.natsService.send<PaymentResponse>(message);
BullMQ Library (@/libs/bullmq
)
Background job processing library for handling long-running tasks, retries, and scheduled jobs.
Usage
import { BullmqModule } from '@/libs/bullmq';
import { join } from 'path';
// Register in your module
@Module({
imports: [
BullmqModule.forFeature({
queueName: 'my-queue',
processorPath: join(__dirname, 'processors', 'my.processor.js'),
concurrency: 3,
defaultJobOptions: {
attempts: 3,
backoff: {
type: 'exponential',
delay: 1000,
},
},
}),
],
})
// Create a job processor (my.processor.ts)
import { Job } from 'bullmq';
export default async function myProcessor(job: Job) {
try {
console.log(`Processing job ${job.id}`);
await job.updateProgress(50);
// Your job logic here
return { processed: true };
} catch (error) {
console.error(`Error processing job ${job.id}:`, error);
throw error;
}
}
// In your service
@Injectable()
export class MyService {
constructor(
@Inject('BullQueue_my-queue')
private myQueue: Queue,
) {}
async addJob(data: any) {
// Regular job
await this.myQueue.add('job-name', data);
// Delayed job
await this.myQueue.add('delayed-job', data, {
delay: 5000, // 5 seconds
});
// Repeatable job
await this.myQueue.add('repeatable-job', data, {
repeat: {
every: 1000 * 60, // Every minute
},
});
}
}
Features
- Queue Management: Create, pause, resume, and clean queues
- Job Processing: Handle long-running tasks with progress tracking
- Automatic Retries: Configure retry attempts and backoff strategies
- Job Scheduling: Delayed and repeatable jobs
- Event Handling: Monitor job completion and failures
- Resource Cleanup: Automatic cleanup on application shutdown
Environment Variables
# BullMQ Configuration
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=your_password
Common Library (@/libs/common
)
Shared utilities, constants, interfaces, and enums used across services.
Usage
import {
NOTIFICATION_QUEUE,
generateRandomString,
formatPhoneNumber,
OtpPurpose,
SwaggerConfig,
} from '@/libs/common';
// Use constants
console.log(NOTIFICATION_QUEUE); // 'notification'
// Use utility functions
const randomStr = generateRandomString();
const formattedPhone = formatPhoneNumber('+2341234567890');
// Use enums and interfaces
const purpose: OtpPurpose = OtpPurpose.REGISTRATION;
Best Practices
- Always import from the library's main entry point (e.g.,
@/libs/auth
not@/libs/auth/src/*
) - Use TypeScript types and interfaces provided by the libraries
- Follow the async/await pattern when working with services
- Configure modules properly in your service's root module
- Handle errors appropriately as most library functions are promise-based
Configuration
Most libraries require configuration through environment variables. Ensure these are set in your service's .env
file:
# Cache Configuration
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=your_password
# NATS Configuration
NATS_URL=nats://localhost:4222
NATS_SERVICE_QUEUE=service_queue # Replace 'service' with your service name (e.g., payment_queue)
# Other configurations...