PHP Validation Form Requests Redirects Error Bags
Definisi
Di Laravel, form backend biasanya mengikuti alur yang cukup konsisten: request masuk, data divalidasi, lalu aplikasi mengembalikan response. Kalau validasi gagal, response paling sering berupa redirect kembali ke form dengan error message dan input lama. Kalau validasi lolos, request lanjut ke proses simpan atau update data.
Empat konsep yang paling sering dipakai di sini adalah:
- validation: memeriksa apakah input memenuhi aturan
- FormRequest: kelas khusus untuk memindahkan rules, messages, dan authorization dari controller
- redirect: response yang mengirim browser ke halaman lain, sering kali kembali ke form
- error bag: wadah untuk memisahkan kumpulan error validasi, terutama saat ada lebih dari satu form dalam satu halaman
Kalau dibaca dari sisi produksi, topik ini bukan cuma soal syntax. Yang penting adalah memahami kapan controller masih cukup, kapan validasi harus dipindah, dan bagaimana error bisa kembali ke view tanpa bikin alur form berantakan.
Alur submit → validate → redirect/error bag
Diagram ini menunjukkan pola yang paling umum di form web Laravel. Validation gagal bukan berarti aplikasi berhenti tanpa arah; biasanya request dialihkan kembali sambil membawa error dan input lama lewat session.
Validation di controller: kapan cukup
Untuk form yang kecil dan aturan validasinya masih sederhana, validation di controller sering sudah cukup. Contohnya ketika:
- field yang divalidasi sedikit
- rules tidak dipakai ulang di banyak tempat
- tidak ada authorization khusus pada request itu
- controller masih mudah dibaca walau ada
validate()di dalamnya
Contoh:
public function store(Request $request)
{
$validated = $request->validate([
'title' => ['required', 'string', 'max:255'],
'body' => ['required', 'string'],
]);
Post::create($validated);
return redirect()->route('posts.index');
}Cara ini cocok untuk endpoint sederhana karena cepat, eksplisit, dan tidak menambah file baru tanpa alasan.
Controller validation masih sehat kalau
- form hanya dipakai di satu tempat
- rules singkat dan mudah dibaca sekilas
- pesan error tidak perlu custom yang rumit
- otorisasi tidak perlu dipisahkan
Tanda mulai tidak cukup
Kalau controller mulai penuh dengan rules, conditional validation, atau pengecekan authorization yang makin spesifik, biasanya validasi sebaiknya dipindah.
Kapan pindah ke FormRequest
FormRequest lebih cocok kalau validasi mulai menjadi bagian yang serius dari alur aplikasi, bukan sekadar check kecil di controller.
Pindahkan ke FormRequest kalau:
- rules cukup panjang atau kompleks
- rules dipakai ulang di beberapa action
- perlu authorization per request
- perlu custom message atau attribute name yang lebih rapi
- controller mulai terlalu tebal
- logika validasi butuh method tambahan seperti
prepareForValidation()atauwithValidator()
Contoh:
use Illuminate\Foundation\Http\FormRequest;
class StorePostRequest extends FormRequest
{
public function authorize(): bool
{
return true;
}
public function rules(): array
{
return [
'title' => ['required', 'string', 'max:255'],
'body' => ['required', 'string'],
];
}
}Controller-nya jadi lebih ringan:
public function store(StorePostRequest $request)
{
$validated = $request->validated();
Post::create($validated);
return redirect()->route('posts.index');
}Kenapa FormRequest lebih enak di project yang tumbuh
- validasi terkonsentrasi di satu tempat
- controller fokus pada orchestration
- rules lebih mudah dites
- authorization bisa dipisah dari proses simpan
- reuse lebih jelas untuk create/update flow yang mirip
Batas sehat FormRequest
FormRequest bagus, tapi jangan dipakai hanya karena ingin “rapi”. Untuk form yang benar-benar kecil, validation di controller tetap valid. Yang penting adalah keterbacaan dan biaya perawatan, bukan jumlah file.
Bagaimana redirect bekerja setelah validation gagal
Di form web Laravel, validation failure biasanya tidak mengembalikan JSON. Yang terjadi adalah browser diarahkan kembali ke halaman sebelumnya atau halaman form, lalu session membawa error dan old input.
Pola umumnya seperti ini:
- user submit form
- Laravel validasi data
- kalau gagal, Laravel membuat redirect response
- error disimpan sementara di session
- input lama juga disimpan sementara di session
- view form membaca error dan old input saat render ulang
Itu sebabnya nilai field sering tetap terisi setelah gagal submit.
Contoh redirect manual
return redirect()
->back()
->withErrors(['title' => 'Judul wajib diisi'])
->withInput();Contoh redirect sukses
return redirect()
->route('posts.index')
->with('status', 'Post berhasil disimpan');Inti yang perlu diingat
redirect()->back()mengirim user kembali ke halaman sebelumnyawithErrors()menaruh error ke session untuk dibaca viewwithInput()menaruh input lama ke session- view harus menampilkan kembali old input secara aman
Error bags
Error bag adalah cara Laravel memisahkan kumpulan error validasi. Secara default, Laravel memakai error bag bernama default. Itu cukup untuk satu form sederhana dalam satu halaman.
Masalah muncul ketika satu halaman punya beberapa form. Misalnya:
- form profil
- form password
- form alamat
Kalau semua error dilempar ke bag yang sama, view bisa bingung menampilkan pesan yang mana untuk form yang mana.
Kapan error bag penting
- ada beberapa form dalam satu halaman
- form berbeda punya field dengan nama yang mirip
- redirect balik ke halaman yang sama tetapi error harus tampil di blok yang berbeda
Contoh memakai named error bag
return redirect()
->back()
->withErrors($validator, 'profileUpdate')
->withInput();Di view, error-nya dibaca dari bag yang sama:
@error('name', 'profileUpdate')
<div>{{ $message }}</div>
@enderrorAtau:
@if ($errors->profileUpdate->has('name'))
<div>{{ $errors->profileUpdate->first('name') }}</div>
@endifKapan cukup pakai default bag
Kalau halaman hanya punya satu form utama, default bag biasanya paling sederhana. Named bag baru terasa manfaatnya saat halaman mulai padat.
Cara kerja FormRequest saat validasi gagal
FormRequest sebenarnya memudahkan redirect/error bag juga. Saat validation gagal, Laravel akan otomatis mengembalikan response yang sesuai untuk konteks request.
Untuk form web biasa:
- request gagal validasi
- Laravel redirect kembali
- error masuk ke session
- old input ikut disimpan
Untuk request API:
- request gagal validasi
- Laravel mengembalikan response error, biasanya JSON dengan status 422
Artinya, perilaku validasi tidak sama di semua konteks. Web form cenderung redirect, sedangkan API cenderung response JSON.
Jebakan umum pada form backend
1. Hanya validasi di frontend
Frontend validation membantu UX, tetapi bukan batas keamanan. Server tetap harus memvalidasi ulang.
2. Controller terlalu gemuk
Kalau controller penuh dengan rules, message, dan kondisi bercabang, sulit dibaca dan sulit dites. Itu tanda FormRequest mulai lebih cocok.
3. Lupa mengembalikan old input
Kalau redirect gagal tidak menyertakan input lama, user harus mengetik ulang semuanya. Di form yang panjang, ini bikin pengalaman buruk.
4. Salah menampilkan error bag
Kalau ada beberapa form di satu halaman, error bisa muncul di blok yang salah kalau tidak dipisahkan dengan named bag.
5. Menyimpan data sebelum validasi selesai
Jangan pernah simpan ke database dulu lalu validasi belakangan. Urutan yang benar adalah validasi dulu, baru proses bisnis.
6. Authorization dicampur dengan validation secara sembarangan
Validasi menjawab “datanya valid atau tidak”. Authorization menjawab “user ini boleh melakukan aksi ini atau tidak”. Dua hal ini beda.
7. Rule update dan create disamakan mentah-mentah
Saat update, beberapa field mungkin boleh kosong atau tidak boleh sama dengan record saat ini. FormRequest terpisah sering lebih bersih daripada satu ruleset yang dipaksa menampung semua skenario.
8. Pesan error terlalu generik
Pesan seperti “Terjadi kesalahan” memang aman, tapi sering terlalu kabur untuk debugging. Sebaliknya, pesan juga jangan terlalu bocor ke detail internal.
Contoh alur yang sehat
public function store(StorePostRequest $request)
{
$validated = $request->validated();
Post::create([
'title' => $validated['title'],
'body' => $validated['body'],
'user_id' => $request->user()->id,
]);
return redirect()
->route('posts.index')
->with('status', 'Post berhasil dibuat');
}Kalau validasi gagal, Laravel akan otomatis kembali ke form dan menaruh error ke session. Kalau berhasil, aplikasi lanjut ke proses simpan lalu redirect sukses.
Catatan implementasi
- Pakai validation di controller kalau form masih kecil dan tidak dipakai ulang.
- Pindah ke FormRequest kalau rules mulai banyak, perlu authorization, atau ingin controller tetap tipis.
- Redirect gagal hampir selalu harus membawa error dan old input.
- Gunakan named error bag saat satu halaman memuat beberapa form.
- Bedakan validation, authorization, dan business logic.
- Untuk debugging, cek tiga hal dulu: rules, bag yang dipakai, dan apakah
withInput()ikut dikirim.
Referensi terkait
- Laravel Validation
- Laravel Form Requests
- Laravel Redirects
- Laravel Error Bags
- Session flash data untuk error dan old input