Skip to content

Providers Overview

FORGE uses a provider-based architecture to integrate with external services. Providers are pluggable implementations of common service categories such as SMS, email, storage, and payments. Each category defines a shared trait (interface) and supports multiple driver implementations that can be swapped at runtime.

Architecture

The provider system follows a trait-factory pattern:

┌─────────────────────────────────────────────────────────┐
│                    Provider System                        │
├─────────────────────────────────────────────────────────┤
│                                                          │
│   ┌─────────────┐                                        │
│   │   Trait      │  Common interface (send, store, etc.) │
│   │  (Interface) │                                        │
│   └──────┬──────┘                                        │
│          │                                                │
│    ┌─────┼──────────────┐                                │
│    │     │              │                                 │
│    ▼     ▼              ▼                                 │
│ ┌──────┐ ┌──────────┐ ┌────────┐                        │
│ │Twilio│ │ Unifonic  │ │ Vonage │  Driver implementations│
│ └──────┘ └──────────┘ └────────┘                        │
│    │          │             │                             │
│    └──────────┼─────────────┘                            │
│               ▼                                          │
│        ┌─────────────┐                                   │
│        │   Factory    │  Creates the right driver at     │
│        │              │  runtime from configuration      │
│        └─────────────┘                                   │
│                                                          │
└─────────────────────────────────────────────────────────┘

How It Works

  1. Trait -- Defines the contract that all drivers must implement (e.g., SmsProvider::send())
  2. Drivers -- Concrete implementations for specific services (e.g., Twilio, SendGrid, S3)
  3. Factory -- Reads the configuration and instantiates the correct driver at runtime

This design allows you to switch providers without changing application code. For example, migrating from Twilio to Vonage requires only a configuration change.

Provider Categories

CategoryTraitAvailable DriversDocs
SMSSmsProviderTwilio, Unifonic, VonageSMS Providers
EmailEmailProviderSMTP, SendGrid, Mailgun, Amazon SESEmail Providers
StorageStorageProviderLocal, S3Storage Providers
PaymentsPaymentProviderHyperPay, Checkout.comPayment Providers

Configuration

Providers are configured in two places:

1. forge.yaml

The providers section in forge.yaml defines which driver to use for each category:

yaml
providers:
  sms: twilio
  email: smtp
  storage: local
  payments: hyperpay

2. Settings Table

Driver-specific credentials and options are stored in the database settings table, grouped under the provider category:

┌────────────┬───────────────────┬────────────────────────────┐
│ group_name │ key               │ value                      │
├────────────┼───────────────────┼────────────────────────────┤
│ sms        │ twilio_account_sid│ ACxxxxxxxxxxxxxxxxxxxxxxxx │
│ sms        │ twilio_auth_token │ ••••••••••••••••           │
│ sms        │ twilio_from_number│ +15551234567               │
│ email      │ email_host        │ smtp.example.com           │
│ email      │ email_port        │ 587                        │
│ storage    │ s3_bucket         │ my-app-uploads             │
└────────────┴───────────────────┴────────────────────────────┘

TIP

Credentials are stored as encrypted settings using AES-256-GCM. They are never exposed in plain text through the admin UI or API.

Installing a Provider

Use the FORGE CLI to install a provider driver:

bash
# Install a specific provider driver
forge provider:add sms:twilio
forge provider:add email:sendgrid
forge provider:add storage:s3
forge provider:add payments:hyperpay

The provider:add command:

  1. Validates the provider type and driver
  2. Updates forge.yaml with the selected driver
  3. Appends the required environment variables to .env and .env.example
    • Skips variables that already exist (no duplicates on re-run)
    • Creates the files if they don't exist
    • Groups variables under a section header (e.g. # Sms Provider (twilio))
  4. Displays the required environment variables for reference

TIP

Drivers named log (e.g. sms:log, payment:log) are development-only and require no environment variables. The env file step is skipped entirely for these drivers.

Runtime Provider Creation

The factory reads the current configuration and creates the appropriate driver:

rust
// The factory creates the correct driver based on configuration
let sms = SmsFactory::create(&settings).await?;
sms.send("+1234567890", "Hello from FORGE").await?;

// Switch providers by changing the config -- no code changes needed
let email = EmailFactory::create(&settings).await?;
email.send("user@example.com", "Welcome", "Hello!").await?;

let storage = StorageFactory::create(&settings).await?;
storage.put("uploads/file.pdf", data).await?;

WARNING

Ensure all required settings for the selected driver are configured before using the provider. Missing credentials will result in a runtime error when the factory attempts to create the driver.

Creating Custom Providers

FORGE supports creating your own provider implementations. See Custom Providers for a step-by-step guide on implementing and registering a custom driver.

Released under the MIT License.