Validasi & Form Request
Memvalidasi input dengan aturan Laravel, pesan kustom, dan memindahkan validasi ke class Form Request.
Jangan percaya input
Setiap data dari pengguna harus divalidasi sebelum disimpan. Validasi Laravel deklaratif: kamu menyebutkan aturan, Laravel memeriksa dan — bila gagal — otomatis mengembalikan pengguna ke form dengan pesan error (untuk web) atau JSON status 422 (untuk API).
Validasi langsung di controller
public function store(Request $request): RedirectResponse
{
$data = $request->validate([
'nama' => 'required|string|min:3|max:100',
'email' => 'required|email|unique:users,email',
'harga' => 'required|integer|min:0',
]);
Produk::create($data); // $data hanya berisi field yang lolos validasi
return redirect()->route('produk.index');
}
Aturan boleh ditulis sebagai string dipisah | atau sebagai array (lebih rapi, wajib bila memakai objek Rule): ['required', 'string', 'max:100'].
Aturan yang paling sering dipakai
| Aturan | Arti |
|---|---|
required, nullable, sometimes | Wajib / boleh kosong / hanya divalidasi bila ada |
string, integer, numeric, boolean, array, date | Tipe data |
min:3, max:100, between:1,10, size:8 | Panjang string / nilai angka / jumlah item |
email, url, regex:/.../, alpha_dash | Format |
unique:tabel,kolom | Belum dipakai di tabel |
exists:tabel,kolom | Harus ada di tabel (mis. foreign key) |
in:aktif,draft | Salah satu nilai |
confirmed | Cocok dengan field *_confirmation (konfirmasi password) |
image, mimes:jpg,png, max:2048 | Berkas gambar; maks. 2048 KB |
after:today, before:tanggal | Tanggal |
Rule object & password
use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\Password;
'email' => ['required', 'email', Rule::unique('users')->ignore($user->id)], // abaikan baris sendiri saat update
'status' => ['required', Rule::in(['draft', 'terbit'])],
'password' => ['required', 'confirmed', Password::min(8)->letters()->numbers()],
Pesan kustom
$request->validate($rules, [
'nama.required' => 'Nama produk wajib diisi.',
'harga.min' => 'Harga tidak boleh negatif.',
]);
Form Request: validasi di class sendiri
Saat aturan makin panjang, pindahkan ke Form Request agar controller tetap tipis:
php artisan make:request StoreProdukRequest
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class StoreProdukRequest extends FormRequest
{
public function authorize(): bool
{
return true; // atau: return $this->user()?->can('create', Produk::class) ?? false;
}
public function rules(): array
{
return [
'nama' => ['required', 'string', 'min:3', 'max:100'],
'harga' => ['required', 'integer', 'min:0'],
'kategori_id' => ['required', 'exists:kategoris,id'],
];
}
public function messages(): array
{
return [
'nama.required' => 'Nama produk wajib diisi.',
'harga.min' => 'Harga tidak boleh negatif.',
];
}
}
public function store(StoreProdukRequest $request): RedirectResponse // validasi otomatis sebelum method jalan
{
Produk::create($request->validated());
return redirect()->route('produk.index');
}
authorize() menentukan apakah pengguna berhak mengirim request ini (jika false → 403). Hook lain: prepareForValidation() (merapikan input sebelum divalidasi, mis. membuat slug) dan attributes() (nama field yang ramah).
Menampilkan error di Blade
<input name="nama" value="{{ old('nama') }}">
@error('nama')
<small class="error">{{ $message }}</small>
@enderror
@if ($errors->any()) ... @endif
old('nama') mengembalikan isi sebelumnya sehingga pengguna tak perlu mengetik ulang.
Untuk API
Bila klien meminta JSON (Accept: application/json), kegagalan validasi menghasilkan respons 422: { "message": "...", "errors": { "nama": ["..."] } } — tanpa kode tambahan.