Event, Listener & Mail
Memisahkan reaksi dari aksi dengan event dan listener, serta mengirim email dengan Mailable.
Event: "sesuatu telah terjadi"
Saat pesanan dibuat, kamu mungkin ingin: mengirim email, mengurangi stok, memberi notifikasi admin, mencatat analitik. Menaruh semuanya di controller membuatnya gemuk dan sulit diubah. Pola event–listener memisahkan: controller cukup memancarkan event PesananDibuat; sejumlah listener terpisah bereaksi.
php artisan make:event PesananDibuat
php artisan make:listener KirimEmailKonfirmasi --event=PesananDibuat
Event
<?php
namespace App\Events;
use App\Models\Pesanan;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
class PesananDibuat
{
use Dispatchable, SerializesModels;
public function __construct(public Pesanan $pesanan)
{
}
}
Event hanyalah pembawa data (data class). Memancarkannya: PesananDibuat::dispatch($pesanan);
Listener
<?php
namespace App\Listeners;
use App\Events\PesananDibuat;
use App\Mail\KonfirmasiPesanan;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Support\Facades\Mail;
class KirimEmailKonfirmasi implements ShouldQueue // ShouldQueue: dikerjakan di antrian
{
public function handle(PesananDibuat $event): void
{
Mail::to($event->pesanan->user)->send(new KonfirmasiPesanan($event->pesanan));
}
}
Laravel menemukan listener otomatis: ia membaca type-hint pada method handle(PesananDibuat $event) sehingga tidak perlu mendaftarkannya manual. Listener yang implements ShouldQueue otomatis diantrikan.
Mail: Mailable
php artisan make:mail KonfirmasiPesanan --markdown=emails.konfirmasi
<?php
namespace App\Mail;
use App\Models\Pesanan;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
class KonfirmasiPesanan extends Mailable
{
public function __construct(public Pesanan $pesanan)
{
}
public function envelope(): Envelope
{
return new Envelope(subject: 'Konfirmasi Pesanan #' . $this->pesanan->id);
}
public function content(): Content
{
return new Content(markdown: 'emails.konfirmasi');
}
}
Data publik pada Mailable otomatis tersedia di view email ($pesanan). Pengiriman: Mail::to($user)->send(new KonfirmasiPesanan($pesanan)); atau ->queue(...) agar via antrian.
Konfigurasi email
Atur di .env (MAIL_MAILER, MAIL_HOST, MAIL_PORT, MAIL_USERNAME, MAIL_PASSWORD, MAIL_FROM_ADDRESS). Saat pengembangan pakai MAIL_MAILER=log (email ditulis ke log) atau Mailpit/Mailtrap agar tidak mengirim email sungguhan. Produksi: Postmark, Resend, Amazon SES, Mailgun, dll.
Notifikasi: satu pesan, banyak saluran
Untuk pemberitahuan ke pengguna lewat berbagai saluran (email, database, SMS, Slack) gunakan Notification:
php artisan make:notification PesananDikirim
$user->notify(new PesananDikirim($pesanan)); // method via() menentukan saluran: ['mail', 'database']
Event model & observer
Eloquent juga memancarkan event otomatis (created, updated, deleted, ...). Kumpulkan reaksinya di Observer dan pasang dengan atribut #[ObservedBy([PesananObserver::class])] pada model.
Praktik baik
- Listener kecil, satu tugas; pekerjaan lambat →
ShouldQueue. - Event diberi nama bentuk lampau (
PesananDibuat), menyatakan fakta yang sudah terjadi. - Jangan membuat listener yang saling memicu event berantai tanpa kendali.