stock-bot/DI-CONTAINER-SIMPLIFICATION.md

142 lines
No EOL
4.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# DI Container Configuration Simplification
## Overview
We've simplified the dependency injection container setup across all backend services by creating a new `createServiceContainerFromConfig` function that directly accepts the AppConfig, eliminating repetitive configuration mapping code.
## Before vs After
### Before (30+ lines per service)
```typescript
// In each service's index.ts
const awilixConfig = {
redis: {
host: config.database.dragonfly.host,
port: config.database.dragonfly.port,
db: config.database.dragonfly.db,
},
mongodb: {
uri: config.database.mongodb.uri,
database: config.database.mongodb.database,
},
postgres: {
host: config.database.postgres.host,
port: config.database.postgres.port,
database: config.database.postgres.database,
user: config.database.postgres.user,
password: config.database.postgres.password,
},
questdb: {
enabled: false,
host: config.database.questdb.host,
httpPort: config.database.questdb.httpPort,
pgPort: config.database.questdb.pgPort,
influxPort: config.database.questdb.ilpPort,
database: config.database.questdb.database,
},
};
container = createServiceContainer(awilixConfig);
```
### After (2-3 lines per service)
```typescript
// In each service's index.ts
container = createServiceContainerFromConfig(config, {
enableQuestDB: false, // Service-specific options
enableMongoDB: true,
enablePostgres: true,
// ... other options
});
```
## Benefits
1. **Code Reduction**: ~30 lines reduced to 2-3 lines per service
2. **Centralized Mapping**: Configuration structure mapping is now in one place
3. **Service-Specific Control**: Each service can enable/disable specific components
4. **Type Safety**: Direct use of AppConfig ensures type safety
5. **Maintainability**: Changes to config structure only need updates in one place
## Service Configurations
### Data Ingestion Service
```typescript
container = createServiceContainerFromConfig(config, {
enableQuestDB: false, // Not needed yet
enableMongoDB: true, // Stores raw data
enablePostgres: true, // Stores metadata
enableCache: true, // For rate limiting
enableQueue: true, // Job processing
enableBrowser: true, // Web scraping
enableProxy: true, // Proxy rotation
});
```
### Data Pipeline Service
```typescript
container = createServiceContainerFromConfig(config, {
enableQuestDB: config.database.questdb?.enabled || false,
enableMongoDB: true, // Reads raw data
enablePostgres: true, // Writes processed data
enableCache: true, // Query caching
enableQueue: true, // Job processing
enableBrowser: false, // Not needed
enableProxy: false, // Not needed
});
```
### Web API Service
```typescript
container = createServiceContainerFromConfig(config, {
enableQuestDB: false, // Not needed
enableMongoDB: true, // Reads data
enablePostgres: true, // Reads data
enableCache: true, // API caching
enableQueue: false, // No job processing
enableBrowser: false, // Not needed
enableProxy: false, // Not needed
});
```
## Implementation Details
The new function in `@stock-bot/di/awilix-container.ts`:
- Accepts the standard AppConfig from `@stock-bot/config`
- Maps the nested config structure to what Awilix expects
- Provides sensible defaults for all options
- Only creates services that are enabled for the specific service
## Migration Guide
To migrate a service:
1. Change the import:
```typescript
// Before
import { createServiceContainer, ... } from '@stock-bot/di';
// After
import { createServiceContainerFromConfig, ... } from '@stock-bot/di';
```
2. Replace the config mapping:
```typescript
// Before
const awilixConfig = { /* 30+ lines of mapping */ };
container = createServiceContainer(awilixConfig);
// After
container = createServiceContainerFromConfig(config, {
// Service-specific options
});
```
3. Choose which services to enable based on your service's needs
## Result
- **3 services updated**: data-ingestion, data-pipeline, web-api
- **~90 lines of code removed** (30 lines × 3 services)
- **Cleaner, more maintainable codebase**
- **Easier to add new services** with minimal boilerplate