Skip to main content
Version: 1.2.2

Multi-Tenancy API Reference

SymbolSignaturePurpose
NewTenantRouterNewTenantRouter(config TenantConfig, resolver func(context.Context) string, factory func(string) (*Client, error)) *TenantRouterBuilds a tenant-aware router.
TenantRouter.ResolveTenantResolveTenant(ctx) (string, error)Extracts the tenant ID from context.
TenantRouter.GetClientGetClient(ctx) (*Client, error)Returns the client for the resolved tenant.
TenantRouter.ActiveTenantsActiveTenants() []stringLists cached tenant connections.
DatabasePerTenantTenantStrategy constSeparate DB pool per tenant.
SchemaPerTenantTenantStrategy constShared pool, schema prefix per tenant.
RowLevelSecurityClientTenantStrategy constClient-side WHERE tenant_id = ? injection.
RowLevelSecurityNativeTenantStrategy constEngine-enforced policies (PostgreSQL only).

Tenant Strategies

StrategyDescriptionUse Case
DatabasePerTenantSeparate DB per tenantStrong isolation, regulatory
SchemaPerTenantSchema per tenantMedium isolation, shared pool
RowLevelSecurityClientClient-side WHERE tenant_id = ? injection on every Quark-built query (raw SQL bypasses it).Shared table, simple scaling. On PG, RowLevelSecurityNative offers engine-enforced policies as the alternative.
RowLevelSecurityNativePostgreSQL-only. Engine-enforced via set_config('app.tenant_id', ...) per implicit transaction + CREATE POLICY clauses on each tenant-scoped table. client.Raw() is also filtered server-side.PG deployments where bypass risk matters; mutually exclusive with RowLevelSecurityClient per router.
RowLevelSecurity is deprecated

RowLevelSecurity is a deprecated alias for RowLevelSecurityClient. Use RowLevelSecurityClient in new code; the alias is scheduled for removal in v2.0.

TenantRouter

NewTenantRouter(config, resolver, factory) *TenantRouter

router := quark.NewTenantRouter(
quark.TenantConfig{
Strategy: quark.SchemaPerTenant,
BaseClient: baseClient,
MaxCachedPools: 100, // For DatabasePerTenant
},
func(ctx context.Context) string {
return ctx.Value("tenant_id").(string) // Extract from context
},
func(tenantID string) (*quark.Client, error) {
// Create tenant-specific client
return quark.New("postgres", fmt.Sprintf(".../tenant_%s", tenantID))
},
)

Usage with Queries

// RowLevelSecurityClient: WHERE tenant_id = 'acme' is auto-injected
users, _ := quark.For[User](ctx, router).List()

// SchemaPerTenant: queries "acme.users"
orders, _ := quark.For[Order](ctx, router).List()

Tenant Router Methods

MethodDescription
ResolveTenant(ctx) (string, error)Extract tenant ID from context
GetClient(ctx) (*Client, error)Get tenant-specific client
ActiveTenants() []stringList cached tenant connections