This example demonstrates how to use feature flags to control routing behavior in the reverse proxy module, including tenant-specific configuration loading and feature flag overrides.
The example sets up:
- A reverse proxy with feature flag-controlled backends
- Multiple backend servers to demonstrate different routing scenarios
- Tenant-aware feature flags with configuration file loading
- Composite routes with feature flag controls
- File-based tenant configuration system
This example demonstrates how to load tenant-specific configurations from files:
tenants/beta-tenant.yaml: Configuration for beta tenant with premium featurestenants/enterprise-tenant.yaml: Configuration for enterprise tenant with analytics
- Configuration Directory: Tenant configs are stored in the
tenants/directory - File Naming: Each tenant has a separate YAML file named
{tenant-id}.yaml - Automatic Loading: The
FileBasedTenantConfigLoaderautomatically discovers and loads tenant configurations - Module Overrides: Tenant files can override any module configuration, including reverseproxy settings
- Feature Flag Integration: Tenant configs work seamlessly with feature flag evaluations
# tenants/beta-tenant.yaml
reverseproxy:
default_backend: "beta-backend"
backend_services:
beta-backend: "http://localhost:9005"
premium-api: "http://localhost:9006"
backend_configs:
default:
feature_flag_id: "beta-feature"
alternative_backend: "beta-backend"
routes:
"/api/premium": "premium-api"-
beta-feature(globally disabled, enabled for "beta-tenant"):- Controls access to the default backend
- Falls back to alternative backend when disabled
-
new-backend(globally enabled):- Controls access to the new-feature backend
- Falls back to default backend when disabled
-
composite-route(globally enabled):- Controls access to the composite route that combines multiple backends
- Falls back to default backend when disabled
-
premium-features(globally disabled, enabled for "beta-tenant"):- Controls access to premium API features
- Falls back to beta backend when disabled
-
enterprise-analytics(globally disabled, enabled for "enterprise-tenant"):- Controls access to enterprise analytics features
- Falls back to enterprise backend when disabled
-
tenant-composite-route(globally enabled):- Controls tenant-specific composite routes
- Falls back to tenant default backend when disabled
-
enterprise-dashboard(globally enabled):- Controls enterprise dashboard composite route
- Falls back to enterprise backend when disabled
- Default Backend (port 9001): Main backend service
- Alternative Backend (port 9002): Fallback when feature flags are disabled
- New Feature Backend (port 9003): New service controlled by feature flag
- API Backend (port 9004): Used in composite routes
- Beta Backend (port 9005): Special backend for beta tenant
- Premium API Backend (port 9006): Premium features for beta tenant
- Enterprise Backend (port 9007): Enterprise tenant backend
- Analytics API Backend (port 9008): Enterprise analytics backend
-
Start the application:
go run main.go
-
The application will start on port 8080 with backends on ports 9001-9008
# Normal user - should get alternative backend (feature disabled)
curl http://localhost:8080/api/beta
# Beta tenant - should get default backend (feature enabled for this tenant)
curl -H "X-Tenant-ID: beta-tenant" http://localhost:8080/api/beta# Should get new-feature backend (feature enabled)
curl http://localhost:8080/api/new# Should get composite response from multiple backends (feature enabled)
curl http://localhost:8080/api/composite# Beta tenant gets routed to their specific backend via tenant config
curl -H "X-Tenant-ID: beta-tenant" http://localhost:8080/
# Beta tenant can access premium features (enabled via tenant config)
curl -H "X-Tenant-ID: beta-tenant" http://localhost:8080/api/premium
# Beta tenant composite route with tenant-specific backends
curl -H "X-Tenant-ID: beta-tenant" http://localhost:8080/api/tenant-composite
# Enterprise tenant gets routed to enterprise backend via tenant config
curl -H "X-Tenant-ID: enterprise-tenant" http://localhost:8080/
# Enterprise tenant can access analytics (enabled via tenant config)
curl -H "X-Tenant-ID: enterprise-tenant" http://localhost:8080/api/analytics
# Enterprise tenant dashboard with multiple data sources
curl -H "X-Tenant-ID: enterprise-tenant" http://localhost:8080/api/dashboardThe feature flags are configured in code in this example, but in a real application they would typically be:
- Loaded from a configuration file
- Retrieved from a feature flag service (LaunchDarkly, Split.io, etc.)
- Stored in a database
This example demonstrates the file-based tenant configuration system:
- Tenant Discovery: The
FileBasedTenantConfigLoaderscans thetenants/directory for YAML files - Automatic Loading: Each
{tenant-id}.yamlfile is automatically loaded as tenant configuration - Module Overrides: Tenant files can override any module configuration
- Environment Variables: Tenant-specific environment variables are supported with prefixes like
beta-tenant_REVERSEPROXY_PORT - Feature Flag Integration: Tenant configurations work seamlessly with feature flag evaluations
- Global Configuration:
config.yamlprovides default settings - Tenant Configuration:
tenants/{tenant-id}.yamloverrides global settings for specific tenants - Environment Variables: Environment variables override file-based configuration
- Feature Flags: Feature flag evaluations control runtime behavior
Each backend returns JSON with information about which backend served the request, making it easy to verify feature flag behavior:
{
"backend": "alternative",
"path": "/api/beta",
"method": "GET",
"feature": "fallback"
}The feature flag system works by:
- Registering a
FeatureFlagEvaluatorservice with the application - Configuring feature flag IDs in backend and route configurations
- The reverse proxy evaluates feature flags on each request
- Routes are dynamically switched based on feature flag values
- Tenant-specific overrides are supported for multi-tenant scenarios
This allows for:
- A/B testing new backends
- Gradual rollouts of new features
- Tenant-specific feature access
- Fallback behavior when features are disabled