User Resource - Action Pattern Integration
Dokumen ini menjelaskan bagaimana UserResource di Filament diintegrasikan dengan Action Pattern untuk menangani operasi Create, Update, dan Delete secara terpisah.
Ini adalah salah satu contoh paling penting di starter kit karena biasanya dari sinilah developer mulai memahami bagaimana saya ingin Filament dan logika bisnis saling bekerja sama.
Kenapa UserResource Dijadikan Contoh
Karena modul user hampir selalu ada di admin panel, dan modul ini cukup kompleks untuk menunjukkan pola yang saya sukai:
- create user
- update user
- delete user
- policy
- role dan permission
- notifikasi atau side effect tambahan
Kalau pola di UserResource sudah dipahami, Anda biasanya akan lebih mudah meniru pendekatan yang sama untuk ProductResource, OrderResource, dan resource lain.
Struktur Action
Semua logika bisnis untuk User disimpan dalam folder app/Actions/Users/:
CreateUserAction: menangani pembuatan user baruUpdateUserAction: menangani pembaruan data userDeleteUserAction: menangani penghapusan user
Contoh Penggunaan Action
// Pembuatan User
app(CreateUserAction::class)->handle($data);
// Pembaruan User
app(UpdateUserAction::class)->handle($user, $data);
// Penghapusan User
app(DeleteUserAction::class)->handle($user);
Kenapa Bukan Langsung di Resource
Kalau semua logic diletakkan langsung di UserResource atau halaman-halamannya, biasanya file akan cepat membesar dan sulit dipakai ulang.
Contoh masalah yang sering muncul:
- API juga butuh create user
- import command juga butuh create user
- business rule create user berubah
Kalau logic ada di action, Anda cukup ubah satu tempat.
Integrasi Filament
1. Create Page (CreateUser.php)
Kita meng-override method handleRecordCreation untuk menggunakan action class:
protected function handleRecordCreation(array $data): Model
{
return app(CreateUserAction::class)->handle($data);
}
2. Edit Page (EditUser.php)
Kita meng-override method handleRecordUpdate untuk pembaruan:
protected function handleRecordUpdate(Model $record, array $data): Model
{
return app(UpdateUserAction::class)->handle($record, $data);
}
Dan untuk tombol hapus di header:
DeleteAction::make()
->using(fn (User $record, DeleteUserAction $deleteAction) => $deleteAction->handle($record)),
3. List Page / Table (UsersTable.php)
Untuk aksi hapus di baris tabel:
DeleteAction::make()
->using(fn (User $record, DeleteUserAction $deleteAction) => $deleteAction->handle($record)),
Studi Kasus
Bayangkan aturan bisnis user Anda seperti ini:
- saat user dibuat, password harus di-hash
- role default perlu diberikan
- avatar default mungkin perlu di-set
- notifikasi welcome mungkin perlu dikirim
Kalau logic ini tersebar di:
- halaman create Filament
- API controller
- import command
maka Anda akan duplikasi kode. Dengan CreateUserAction, semua logic itu tinggal dipusatkan.
Filament cukup menjadi pemanggil:
return app(CreateUserAction::class)->handle($data);
Keuntungan Menggunakan Action Pattern
- Reusability: logika pembuatan user bisa dipanggil dari Filament, API, atau Artisan Command tanpa duplikasi kode.
- Testability: kita dapat menulis test untuk masing-masing action secara terisolasi.
- Maintainability: logika besar tidak menumpuk di Resource/Page Filament.
- Transaction Safety: action dapat dibungkus dalam
DB::transaction()jika perlu.
Catatan Penting
- Action di sini menggunakan method
handle(), bukanexecute() - Authorization sebaiknya tetap dilakukan oleh policy, FormRequest, atau layer pemanggil
- Resource bertugas mengorkestrasi, bukan menjadi pusat semua business logic
Cara Meniru Pola Ini untuk Resource Lain
Jika Anda ingin membuat ProductResource, cara berpikirnya sama:
- Buat
CreateProductAction - Buat
UpdateProductAction - Buat
DeleteProductAction - Hubungkan page Filament ke action tersebut
Dengan pola ini, semua resource di project akan terasa konsisten.