Multi-tenant mimari, tek bir uygulama instance'ının birden fazla müşteriyi (tenant) izole olarak servis etmesidir. SaaS uygulamalarının temel mimari yaklaşımı olan multi-tenancy, ölçeklenebilirlik ve maliyet verimliliği sağlar.
Tenancy Modelleri
1. Shared Database, Shared Schema
tenants: id, name, subdomain users: id, tenant_id, email products: id, tenant_id, name -- Query SELECT * FROM products WHERE tenant_id = 123
- ✅ En düşük maliyet
- ✅ Kolay yönetim
- ❌ İzolasyon riski
- ❌ Noisy neighbor
2. Shared Database, Separate Schema
tenant_123.users tenant_123.products tenant_456.users tenant_456.products
- ✅ Orta düzey izolasyon
- ✅ Per-tenant backup
- ❌ Schema migration karmaşıklığı
3. Separate Database
db_tenant_123: users, products db_tenant_456: users, products
- ✅ Tam izolasyon
- ✅ Per-tenant scaling
- ❌ En yüksek maliyet
- ❌ Yönetim karmaşıklığı
Tenant İdentifikasyonu
Subdomain
tenant1.app.com
tenant2.app.com
// Laravel middleware
$tenant = Tenant::where("subdomain", $request->getHost())->first();
URL Path
app.com/tenant1/dashboard app.com/tenant2/dashboard
Request Header
X-Tenant-ID: 123
Veri İzolasyonu
Global Scope (Laravel)
class TenantScope implements Scope
{
public function apply(Builder $builder, Model $model)
{
$builder->where("tenant_id", auth()->user()->tenant_id);
}
}
// Model
protected static function booted()
{
static::addGlobalScope(new TenantScope);
}
Row-Level Security (PostgreSQL)
CREATE POLICY tenant_isolation ON products
USING (tenant_id = current_setting("app.current_tenant")::int);
Configuration
- Tenant-specific settings
- Feature flags per tenant
- Custom branding (logo, colors)
- Domain/subdomain mapping
Performans
Caching
// Redis key prefix
cache()->tags(["tenant:{$tenantId}"])->put($key, $value);
Job Queue
// Tenant context korunmalı
dispatch(new ProcessOrder($order)->onQueue("tenant-{$tenantId}"));
Güvenlik
- Tenant context her request'te doğrula
- Cross-tenant data access önleme
- API rate limiting per tenant
- Audit logging
Scaling
- Shard by tenant_id
- Separate infrastructure for large tenants
- Read replicas per region
- Caching layer (Redis Cluster)
Laravel Paketleri
- spatie/laravel-multitenancy
- stancl/tenancy
Testing
// Her test tenant context'inde çalışmalı
public function test_user_can_only_see_own_tenant_products()
{
$tenant1 = Tenant::factory()->create();
$tenant2 = Tenant::factory()->create();
$product1 = Product::factory()->for($tenant1)->create();
$product2 = Product::factory()->for($tenant2)->create();
$this->actingAs($tenant1->users->first())
->get("/products")
->assertSee($product1->name)
->assertDontSee($product2->name);
}
Multi-tenant mimari, SaaS'ın temel yapı taşıdır. Doğru model seçimi ve implementasyonla ölçeklenebilir, güvenli sistemler inşa edin.