Büyük Kontrolcü Antipaterni
Bir B2B SaaS platformunu geliştirmeye başladığınızda, uygulama mantığınız genellikle basittir. Bir müşteri bir hesap kaydeder ve kimlik bilgilerini kaydedersiniz. Ancak kurumsal özellikler ölçeklendikçe, temel kod bloklarınız kırılgan hale gelir. Aniden, kullanıcı kayıt kontrolcüsü birden fazla şeyi birden yapar hale gelir.
Kayıt mantığınız hızla bir mimari karmaşaya dönüşebilir: kiracı kullanıcısını kaydetmek, Stripe üzerinden kurumsal bir aboneliği başlatmak, bir Slack izleme güncellemesi göndermek, varsayılan çalışma alanı panolarını oluşturmak ve bir doğrulama e-postası sıraya almak. Eğer Slack API’sinde bir kesinti olursa veya çalışma alanı kurulumu küçük bir hata verirse, tüm kullanıcı kaydı süreci çökebilir. Tek bir aşağı akış hatası, temel özelliği kapatacak şekilde sıkı bir şekilde bağlı bir monolit oluşturmuşsunuzdur. Dayanıklı bir SaaS altyapısı inşa etmek için Olay Tabanlı Mimari uygulamanız gerekir.
Çözüm: Olaylar ve Asenkron Dinleyiciler
Olay tabanlı mimari, temel uygulama mantığını “Bir olay gerçekleşti” şeklinde ifade etmeye ve hemen kullanıcıya bir HTTP yanıtı döndürmeye olanak tanır. Özel arka plan dinleyicileri bu olayı alır ve bağımsız iş akışlarını arka planda eş zamanlı olarak yürütür. Eğer bir kritik olmayan dinleyici başarısız olursa, temel sistem tamamen etkilenmez.
Adım 1: Temel Olay Sınıfını Tanımlama
Laravel’de, yalnızca gerekli verileri (payload veri modeli) taşımakla görevli açık bir olay sınıfı oluştururuz.
namespace App\Events;
use App\Models\User;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
class TenantRegistered
{
use Dispatchable, SerializesModels;
// Arka plan dinleyicilerin kontekst verilerini incelemesine olanak tanır
public User $user;
public function __construct(User $user)
{
$this->user = $user;
}
}
Adım 2: Asenkron Dinleyicileri Ekleme
Bağımsız, asenkron dinleyiciler oluştururuz ve ShouldQueue arayüzünü uygularız. Bu, Laravel’e olayı otomatik olarak seri hale getirmesini ve yürütmeyi tamamen Redis arka plan işçilerine devretmesini söyler.
namespace App\Listeners;
use App\Events\TenantRegistered;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Services\StripeBillingService;
// ShouldQueue'yi uygulamak, blokaj yapmayan yürütmeyi garanti eder
class ProvisionBillingAccount implements ShouldQueue
{
protected StripeBillingService $billing;
public function __construct(StripeBillingService $billing)
{
$this->billing = $billing;
}
public function handle(TenantRegistered $event): void
{
// Stripe API'si ile asenkron olarak iletişim kurma
$this->billing->createCustomerAccount($event->user);
}
}
Adım 3: Olayı Kaydetme ve Yayınlama
Olaylarımızı ve dinleyicilerimizi EventServiceProvider içinde eşleriz (ya da Laravel’in bunları otomatik olarak keşfetmesine izin veririz), böylece kontrolcü kodumuz tamamen sade ve belirleyici hale gelir.
// Kullanıcı Kayıt Kontrolcünüzün içinde
public function register(Request $request)
{
$user = User::create($request->validated());
// 1. Olayı yayınla ve hemen işlemi sürdür
TenantRegistered::dispatch($user);
// 2. 15 ms'den daha kısa sürede 201 Başarı kodunu döndür!
return response()->json(['status' => 'success'], 201);
}
Mühendislik ROI’si
Olay tabanlı bir mimariye geçerek, iş alanlarınızı birbirinden ayırırsınız. Temel istek kontrolcüleriniz anında çalışır çünkü artık üçüncü parti ağ API’lerinin veya ağır derleme görevlerinin tamamlanmasını beklemezler. Sisteminiz derinlemesine modüler hale gelir: yeni bir özellik (örneğin, analiz kaydı) eklemek, yeni bir arka plan dinleyici sınıfı oluşturmanızı gerektirir, böylece test edilmiş, kritik kayıt kontrolcü kodunuzla oynamadan veya riske atmadan işlerinizi sürdürebilirsiniz.
Kaynak: Orijinal Makale


