Belajar Laravel #20: Event & Listener — Melempar Pemberitahuan, Bukan Tugas

Di episode sebelumnya kita sudah nyaman menulis test. Kali ini saya mau catat konsep yang dulu terdengar “enterprise banget” dan ternyata sudah tersedia bawaan di Laravel: event dan listener. Intinya sederhana — buat kode kita tidak saling melibatkan diri.

Diagram alur event dan listener di Laravel
Alur dasar: kode melempar event, listener yang menangani. Listener bisa berjalan di antrian.

Kenapa event, bukan langsung dipanggil saja?

Pernah tidak menulis kode begini di controller? Setelah user daftar: kirim email, catat log, buat data default, kirim notifikasi WhatsApp. Empat langkah itu ditumpuk berurutan di satu method. Awalnya jalan. Dua bulan kemudian ada permintaan “tambahkan juga sinkron ke CRM” — dan controller berubah jadi tempat sampah.

Event membalik pola itu. Ketika sebuah hal penting terjadi (“user baru terdaftar”), kode cukup memberi tahu: “hey, ada UserRegistered di sini”. Tidak peduli siapa yang peduli. Listener-lah yang mendaftar diri untuk menangani event itu. Controller yang tadinya menumpuk tugas kini cuma melempar event. Ini berarti bagi saya: menambah fitur baru tidak menyentuh kode lama — prinsip yang saya dengar sebagai “open-closed principle”, tapi baru terasa manfaatnya lewat event.

Praktik dasar: event + listener

Laravel punya command artisan untuk membuat keduanya. Saya jalankan di proyek latihan:

php artisan make:event OrderPlaced
php artisan make:listener SendOrderConfirmation

Event-nya sendiri cuma berisi data yang relevan — di Laravel versi baru event bisa dibuat sebagai kelas biasa, atau pakai trait Dispatchable supaya bisa dilempar dari mana saja:

<?php

namespace App\Events;

use App\Models\Order;
use Illuminate\Foundation\Events\Dispatchable;

class OrderPlaced
{
    use Dispatchable;

    public function __construct(public Order $order) {}
}

Di controller, satu baris untuk melempar:

event(new OrderPlaced($order));
// atau: OrderPlaced::dispatch($order);

Listener-nya yang bekerja. Di Laravel 11+, pendaftaran event-listener tidak lagi wajib di EventServiceProvider — Laravel mendeteksi otomatis lewat nama kelas (listener SendOrderConfirmation otomatis mendengarkan OrderPlaced). Tapi kalau mau eksplisit, pendaftaran manual tetap didukung dan justru membantu saat membaca alur aplikasi dari satu tempat.

Supaya tidak lambat: queued listener

Ini bagian yang paling saya sukai. Kalau listener mengirim email, pengguna harus menunggu email itu terkirim sebelum melanjutkan. Padahal email bukan urusan inti — urusan intinya adalah pesanan tersimpan. Solusinya: listener dijalankan lewat queue. Cukup implement interface ShouldQueue di listener, lalu pindahkan logikanya ke method handle:

<?php

namespace App\Listeners;

use App\Events\OrderPlaced;
use Illuminate\Contracts\Queue\ShouldQueue;

class SendOrderConfirmation implements ShouldQueue
{
    public function handle(OrderPlaced $event): void
    {
        // berjalan di worker, bukan di request pengguna
        Mail::to($event->order->user)
            ->send(new OrderMail($event->order));
    }
}

Worker-nya dijalankan terpisah: php artisan queue:work. Kalau gagal, job masuk tabel failed_jobs dan bisa dicoba ulang lewat php artisan queue:retry — ingat materi episode Queue & Job.

Observer: event khusus model

Sering sekali event-nya berputar di sekitar satu model: created, updated, deleted, restored. Untuk kasus ini Laravel punya model observer — satu kelas yang menampung method per aksi model. Buat dengan php artisan make:observer OrderObserver, lalu daftarkan di AppServiceProvider:

Order::observe(OrderObserver::class);

Saya memakai observer ketika logika itu benar-benar “reaksi terhadap model”, bukan bisnis utama. Kalau logikanya inti bisnis, saya tetap pakai event eksplisit supaya namanya jelas.

Yang saya catat

Event membuat kode longgar: pemberi tahu tidak kenal penerima. Listener bisa ditambah tanpa menyentuh kode lama, dan dengan ShouldQueue pekerjaan berat keluar dari request pengguna. Harga dari kelonggaran ini adalah alur yang tidak linear — kadang saya perlu mencari “event apa yang dipicu di sini” lewat pencarian nama kelas. Untuk proyek kecil, event berlebihan memang terasa ribet; saya mulai pakai ketika ada tiga atau lebih tindakan turunan dari satu aksi.

Sumber

Tinggalkan Balasan

Alamat email Anda tidak akan dipublikasikan. Ruas yang wajib ditandai *

Situs ini menggunakan Akismet untuk mengurangi spam. Pelajari bagaimana data komentar Anda diproses