Provider System
The Provider system is the backbone of Basefloor's modular architecture, enabling seamless integration with third-party services through a unified interface.
Overview
The Provider system allows you to integrate various external services (AI, email, transcription, storage, etc.) into your Basefloor application through a standardized interface. Each provider is a self-contained module that handles the specific implementation details of a service while exposing a consistent API.
How Providers Work
Provider Loader
The provider loader (packages/api/providers/loader.js
) is responsible for:
- Dependency Checking: Verifies required npm packages are installed
- Dynamic Loading: Loads provider modules at runtime
- Error Handling: Provides helpful error messages for missing dependencies
- Package Manager Detection: Automatically detects whether you're using npm or yarn
Provider Structure
Each provider follows a consistent structure:
packages/api/providers/
├── @anthropic/
│ └── ai.js
├── @google/
│ └── transcription.js
├── @postmark/
│ └── emails.js
├── @mailgun/
│ └── emails.js
├── loader.js
└── manifest.json
Available Providers
AI Providers
Anthropic (@anthropic/ai)
- Service: Claude AI models
- Dependencies:
@anthropic-ai/sdk
- Use Cases: Text generation, chat completion, reasoning tasks
Ollama (@ollama/ai)
- Service: Local AI models
- Dependencies:
ollama
- Use Cases: Local AI inference, privacy-focused applications
Email Providers
Postmark (@postmark/emails)
- Service: Transactional email delivery
- Dependencies:
postmark
- Use Cases: User notifications, password resets, verification emails
Mailgun (@mailgun/emails)
- Service: Email delivery and marketing
- Dependencies:
mailgun.js
- Use Cases: Transactional and marketing emails, email validation
Transcription Providers
Google Cloud Speech-to-Text (@google/transcription)
- Service: Speech-to-text transcription
- Dependencies:
@google-cloud/speech
- Use Cases: Audio transcription, voice commands, accessibility features
Storage Providers
MinIO (@minio/files)
- Service: S3-compatible object storage
- Dependencies:
minio
- Use Cases: File storage, image hosting, backup solutions
DigitalOcean Spaces (@digitalocean/files)
- Service: Object storage
- Dependencies:
aws-sdk
(S3-compatible) - Use Cases: CDN, file hosting, static assets
Image Processing Providers
Sharp (@sharp/files)
- Service: High-performance image processing
- Dependencies:
sharp
- Use Cases: Image resizing, format conversion, optimization
Document Processing Providers
LibreOffice (@libreoffice/files)
- Service: Document conversion and processing
- Dependencies: System LibreOffice installation
- Use Cases: PDF generation, document conversion, office file processing
Files Service Multi-Provider Architecture
The Files service uses a unique multi-provider architecture that combines multiple providers to handle different aspects of file management:
Provider Roles
Remote Provider: Handles file storage and retrieval
- Examples:
@minio/files
,@digitalocean/files
,@aws/files
- Responsibilities: Upload, download, delete files from remote storage
- Examples:
Sharp Provider: Handles image processing
- Provider:
@sharp/files
- Responsibilities: Image resizing, format conversion, optimization
- Automatically loaded when Files service is enabled
- Provider:
LibreOffice Provider: Handles document conversion
- Provider:
@libreoffice/files
- Responsibilities: PDF generation, document format conversion
- Automatically loaded when LibreOffice is installed
- Provider:
How It Works
When the Files service is enabled, all three provider types are automatically loaded:
// The Files service internally loads multiple providers
API.Files = {
Remote: loadProvider('@minio/files'), // Storage operations
Sharp: loadProvider('@sharp/files'), // Image processing
LibreOffice: loadProvider('@libreoffice/files') // Document conversion
}
Configuration Example
// basefloor.config.js
files: {
enabled: true,
providers: {
"Remote": "@minio/files", // Required: Storage provider
"Sharp": "@sharp/files" // Optional: Image processing
// LibreOffice provider auto-loaded if available
}
},
providers: {
"@minio/files": {
endPoint: process.env.MINIO_ENDPOINT,
port: parseInt(process.env.MINIO_PORT),
useSSL: process.env.MINIO_USE_SSL === 'true',
access: process.env.MINIO_ACCESS_KEY,
secret: process.env.MINIO_SECRET_KEY,
bucket: process.env.MINIO_BUCKET
},
"@sharp/files": {
// Sharp configuration for image processing
}
}
File Processing Pipeline
Files flow through providers based on their type and requested operations:
- Upload: Remote provider stores the file
- Image Processing: Sharp provider handles resizing/conversion if needed
- Document Conversion: LibreOffice provider converts office documents to PDF/images
- Download: Remote provider retrieves the file
Dependencies
The Files service requires specific dependencies to be installed in the BasefloorAPI packages directory:
cd packages/api
npm install minio sharp --save
Note: LibreOffice must be installed separately on the system for document conversion features.
Database Providers
MongoDB (@mongodb/database)
- Service: NoSQL database
- Dependencies:
mongodb
- Use Cases: Document storage, user data, application state
Configuration
Single Provider Configuration
// basefloor.config.js
module.exports = (API) => {
return {
// Service configuration
emails: {
enabled: true,
provider: '@postmark/emails',
},
// Provider-specific settings
providers: {
'@postmark/emails': {
serverToken: process.env.POSTMARK_SERVER_TOKEN,
},
},
}
}
Multiple Provider Configuration
// basefloor.config.js
module.exports = (API) => {
return {
// Service with multiple providers
emails: {
enabled: true,
providers: {
'Transactional': '@postmark/emails',
'Marketing': '@mailgun/emails',
},
},
// Provider configurations
providers: {
'@postmark/emails': {
serverToken: process.env.POSTMARK_SERVER_TOKEN,
},
'@mailgun/emails': {
apiKey: process.env.MAILGUN_API_KEY,
domain: process.env.MAILGUN_DOMAIN,
},
},
}
}
Dependency Management
Automatic Dependency Checking
The provider system automatically checks for required dependencies and provides helpful installation instructions:
# Example error message
Missing required dependencies for @anthropic/ai:
Please run 'npm install @anthropic-ai/sdk --save' in the Basefloor directory to install the missing dependencies.
Manifest System
The manifest.json
file defines the required dependencies for each provider:
{
"@anthropic/ai": ["@anthropic-ai/sdk"],
"@google/transcription": ["@google-cloud/speech"],
"@postmark/emails": ["postmark"],
"@mailgun/emails": ["mailgun.js"],
"@minio/files": ["minio"],
"@sharp/files": ["sharp"],
"@libreoffice/files": ["libreoffice-convert"]
}
Package Manager Detection
The system automatically detects your package manager and provides appropriate installation commands:
- Yarn:
yarn add --save package-name
- npm:
npm install package-name --save
Creating Custom Providers
Provider Template
// packages/api/providers/@yourservice/yourprovider.js
module.exports = ({ providerVars, providerName }) => {
// Initialize your service with configuration
const client = new YourServiceClient({
apiKey: providerVars.apiKey,
baseURL: providerVars.baseURL,
});
return {
// Expose your service methods
async performAction(options) {
try {
const result = await client.action(options);
return result;
} catch (error) {
throw new Error(`${providerName} error: ${error.message}`);
}
},
// Add more methods as needed
async anotherAction(options) {
// Implementation
},
};
};
Adding to Manifest
Update manifest.json
to include your provider's dependencies:
{
"@yourservice/yourprovider": ["your-service-sdk", "other-dependency"]
}
Configuration
Add your provider to the service configuration:
// basefloor.config.js
module.exports = (API) => {
return {
yourservice: {
enabled: true,
provider: '@yourservice/yourprovider',
},
providers: {
'@yourservice/yourprovider': {
apiKey: process.env.YOUR_SERVICE_API_KEY,
baseURL: process.env.YOUR_SERVICE_BASE_URL,
},
},
}
}
Error Handling
Graceful Degradation
Providers are designed to fail gracefully. If a provider cannot be loaded due to missing dependencies or configuration issues, the service will:
- Log a descriptive error message
- Continue loading other providers
- Allow the application to start without the failed provider
// Example error handling in service modules
try {
API.AI = {
...API.AI,
...loadProvider(`${paths.basefloor}/providers/${ai.provider}`)({
providerVars: providers[ai.provider],
providerName: ai.provider,
})
}
} catch (err) {
console.error(`AI Service Error: ${err.message}`);
// Continue without AI service
return API;
}
Common Error Types
- Missing Dependencies: Required npm packages not installed
- Invalid Configuration: Missing or incorrect provider configuration
- Authentication Errors: Invalid API keys or credentials
- Network Issues: Unable to connect to provider services
Best Practices
Security
- Environment Variables: Always use environment variables for sensitive configuration
- Credential Rotation: Regularly rotate API keys and credentials
- Least Privilege: Use service accounts with minimal required permissions
- Secure Storage: Never commit credentials to version control
Performance
- Connection Pooling: Reuse connections where possible
- Caching: Cache provider responses when appropriate
- Rate Limiting: Respect provider rate limits
- Timeout Handling: Implement appropriate timeouts
Reliability
- Error Handling: Implement comprehensive error handling
- Retry Logic: Add retry mechanisms for transient failures
- Circuit Breakers: Implement circuit breakers for external services
- Monitoring: Monitor provider health and performance
Development
- Testing: Create tests for your custom providers
- Documentation: Document provider configuration and usage
- Versioning: Version your providers appropriately
- Backwards Compatibility: Maintain backwards compatibility when possible
Environment Variables
Common Patterns
# AI Providers
ANTHROPIC_API_KEY=your_anthropic_key
OLLAMA_BASE_URL=http://localhost:11434
# Email Providers
POSTMARK_SERVER_TOKEN=your_postmark_token
MAILGUN_API_KEY=your_mailgun_key
MAILGUN_DOMAIN=your_domain.com
# Transcription Providers
GOOGLE_CREDENTIALS_BASE64=your_base64_credentials
# Storage Providers
MINIO_ENDPOINT=your_minio_endpoint
MINIO_ACCESS_KEY=your_access_key
MINIO_SECRET_KEY=your_secret_key
# Database Providers
MONGODB_URI=mongodb://localhost:27017/yourdb
Environment File Example
# .env.example
# Copy to .env and fill in your values
# AI Services
ANTHROPIC_API_KEY=
OLLAMA_BASE_URL=http://localhost:11434
# Email Services
POSTMARK_SERVER_TOKEN=
MAILGUN_API_KEY=
MAILGUN_DOMAIN=
# Transcription Services
GOOGLE_CREDENTIALS_BASE64=
# Storage Services
MINIO_ENDPOINT=
MINIO_ACCESS_KEY=
MINIO_SECRET_KEY=
# Database Services
MONGODB_URI=mongodb://localhost:27017/basefloor
Troubleshooting
Provider Not Loading
- Check Dependencies: Ensure required packages are installed
- Verify Configuration: Check provider configuration in
basefloor.config.js
- Environment Variables: Verify environment variables are set correctly
- Network Connectivity: Test connectivity to provider services
Performance Issues
- Rate Limiting: Check if you're hitting provider rate limits
- Network Latency: Test network connectivity to provider services
- Resource Usage: Monitor CPU and memory usage
- Caching: Implement caching to reduce provider calls
Authentication Errors
- API Keys: Verify API keys are valid and not expired
- Permissions: Check service account permissions
- Quotas: Verify you haven't exceeded usage quotas
- IP Restrictions: Check for IP-based access restrictions
Provider Ecosystem
The Basefloor provider ecosystem is designed to be extensible. You can:
- Use Existing Providers: Leverage pre-built integrations
- Create Custom Providers: Build providers for your specific needs
- Contribute Providers: Share providers with the community
- Mix and Match: Use multiple providers for different use cases
This modular approach allows you to build applications that can easily adapt to changing requirements and integrate with new services as they become available.