Form tanpa validasi adalah pintu terbuka bagi data sampah. Bayangkan form pendaftaran yang bisa diisi dengan email asal-asalan, kata sandi satu karakter, atau kolom nama yang dikosongkan. Data seperti itu akan merusak database dan pengalaman pengguna. Kabar baiknya, form validasi Laravel 12 membuat urusan ini sangat mudah: hanya dengan beberapa baris kode, setiap input dari pengguna bisa diperiksa otomatis sebelum disimpan.
Artikel ini membahas tuntas cara membuat form validasi di Laravel 12, mulai dari metode $request->validate() yang paling cepat, daftar aturan validasi yang paling sering dipakai, cara membuat pesan error kustom dalam Bahasa Indonesia, sampai merapikan kode memakai Form Request class. Di akhir ada contoh menampilkan error di Blade dan tips memakai validasi untuk REST API.

Kenapa Validasi Form Itu Wajib
Validasi adalah proses memastikan data yang dikirim pengguna memenuhi syarat sebelum diproses lebih lanjut. Tanpa validasi, aplikasi rentan terhadap tiga masalah besar. Pertama, data tidak konsisten, misalnya kolom email berisi teks biasa atau tanggal lahir berisi angka acak. Kedua, celah keamanan, karena input berbahaya bisa lolos ke database. Ketiga, pengalaman pengguna yang buruk, karena kesalahan baru ketahuan belakangan tanpa penjelasan yang jelas.
Laravel menyelesaikan ketiga masalah ini dengan sistem validasi yang ekspresif. Kamu cukup mendeklarasikan aturan dalam bentuk array, dan Laravel otomatis memeriksa input, mengembalikan pengguna ke form sebelumnya bila ada yang salah, lengkap dengan pesan error dan input lama yang sudah terisi. Semua ini terjadi tanpa kamu menulis logika pengecekan manual yang panjang.
Cara Kerja $request->validate() untuk Form Validasi Laravel 12
Cara tercepat memvalidasi form adalah memanggil metode validate() pada objek $request di dalam controller. Perhatikan contoh berikut untuk form pembuatan artikel.
<?php
namespace App\Http\Controllers;
use App\Models\Post;
use Illuminate\Http\Request;
class PostController extends Controller
{
public function create()
{
return view('posts.create');
}
public function store(Request $request)
{
$validated = $request->validate([
'title' => 'required|string|min:5|max:100',
'slug' => 'required|string|unique:posts,slug',
'body' => 'required|string|min:20',
'category_id' => 'required|exists:categories,id',
'published_at'=> 'nullable|date',
]);
Post::create($validated);
return redirect('/posts')->with('success', 'Artikel berhasil disimpan.');
}
}
Ada tiga hal penting dari kode di atas. Pertama, aturan ditulis sebagai string yang dipisahkan karakter pipe (|), misalnya required|string|min:5. Kedua, metode validate() mengembalikan array $validated yang hanya berisi field yang lolos aturan, sehingga aman langsung dipakai untuk Post::create(). Ketiga, jika validasi gagal, Laravel otomatis mengembalikan (redirect back) pengguna ke halaman form sebelumnya sambil membawa pesan error dan input lama, jadi kamu tidak perlu menulis logika itu sendiri.
Kalau kamu mengikuti seri Laravel di blog ini dari tutorial CRUD Laravel 12, pola di atas akan terasa familiar karena melengkapi proses store dan update yang sudah dibahas di sana.
Aturan Form Validasi Laravel 12 yang Paling Sering Dipakai
Laravel menyediakan puluhan aturan validasi siap pakai. Berikut tabel aturan yang paling sering dipakai dalam form validasi Laravel 12 beserta artinya.
| Aturan | Arti |
|---|---|
required |
Field wajib diisi, tidak boleh kosong |
string |
Nilai harus berupa string |
numeric |
Nilai harus berupa angka |
email |
Nilai harus berformat email yang valid |
min:5 |
Panjang minimal 5 karakter (atau nilai minimal 5 untuk angka) |
max:100 |
Panjang maksimal 100 karakter |
unique:posts,slug |
Nilai harus unik di kolom slug tabel posts |
exists:categories,id |
Nilai harus ada di kolom id tabel categories |
confirmed |
Harus ada field {nama}_confirmation yang nilainya sama (untuk kata sandi) |
date |
Nilai harus berupa tanggal yang valid |
nullable |
Field boleh kosong (null) |
image |
File harus berupa gambar (jpeg, png, bmp, gif, svg, webp) |
mimes:pdf,docx |
File harus berekstensi sesuai daftar |
in:admin,user |
Nilai harus salah satu dari daftar yang disebut |
Aturan unique dan exists sangat berguna karena langsung memeriksa ke database tanpa query manual. Contoh unique:users,email memastikan tidak ada dua pengguna dengan email yang sama, sedangkan exists:categories,id memastikan kategori yang dipilih benar-benar ada.
Untuk form edit data, aturan unique perlu pengecualian agar data milik sendiri tidak dianggap duplikat. Caranya dengan menambahkan ID yang dikecualikan, contoh: unique:posts,slug,10 (mengabaikan baris ber-ID 10) atau memakai sintaks lengkap Rule::unique('posts')->ignore($post->id).
Membuat Pesan Error Kustom Bahasa Indonesia
Secara bawaan, pesan error validasi Laravel berbahasa Inggris, misalnya “The title field is required.” Untuk aplikasi berbahasa Indonesia, kamu bisa menggantinya dengan pesan kustom lewat parameter kedua metode validate().
$validated = $request->validate(
[
'title' => 'required|string|min:5|max:100',
'email' => 'required|email|unique:users,email',
'password' => 'required|string|min:8|confirmed',
],
[
'title.required' => 'Judul wajib diisi.',
'title.min' => 'Judul minimal :min karakter.',
'title.max' => 'Judul maksimal :max karakter.',
'email.required' => 'Alamat email wajib diisi.',
'email.email' => 'Format email tidak valid.',
'email.unique' => 'Email ini sudah terdaftar, silakan pakai email lain.',
'password.required' => 'Kata sandi wajib diisi.',
'password.min' => 'Kata sandi minimal :min karakter.',
'password.confirmed' => 'Konfirmasi kata sandi tidak sama.',
]
);
Kunci array pesan memakai format {nama_field}.{nama_aturan}, sehingga kamu bisa mengatur pesan berbeda untuk tiap kombinasi field dan aturan. Placeholder seperti :min dan :max otomatis diganti Laravel dengan angka dari aturan yang dipakai, jadi pesan tetap dinamis.
Jika pesan kustom dipakai di banyak form, pendekatan yang lebih rapi adalah menerjemahkan seluruh file bahasa validasi. Salin file lang/en/validation.php menjadi lang/id/validation.php, ubah isinya ke Bahasa Indonesia, lalu set 'locale' => 'id' di config/app.php. Dengan begitu seluruh aplikasi memakai pesan Bahasa Indonesia tanpa mengulang array pesan di setiap controller.
Merapikan Kode dengan Form Request Class
Ketika aturan validasi mulai banyak, menaruhnya di controller membuat metode store() terlihat penuh. Solusi resminya adalah Form Request: class khusus yang menampung aturan validasi, pesan kustom, dan logika otorisasi. Buat dengan Artisan:
php artisan make:request StorePostRequest
Perintah itu menghasilkan file app/Http/Requests/StorePostRequest.php. Isi dengan aturan dan pesanmu:
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class StorePostRequest extends FormRequest
{
public function authorize(): bool
{
return true;
}
public function rules(): array
{
return [
'title' => 'required|string|min:5|max:100',
'slug' => 'required|string|unique:posts,slug',
'body' => 'required|string|min:20',
'category_id' => 'required|exists:categories,id',
];
}
public function messages(): array
{
return [
'title.required' => 'Judul wajib diisi.',
'title.min' => 'Judul minimal :min karakter.',
'slug.unique' => 'Slug ini sudah dipakai artikel lain.',
'body.required' => 'Isi artikel wajib diisi.',
'category_id.exists' => 'Kategori yang dipilih tidak valid.',
];
}
}
Metode authorize() menentukan apakah pengguna boleh melakukan request ini; kembalikan true untuk mengizinkan semua, atau tulis logika izin di sana. Lalu pakai class ini sebagai type-hint di controller:
use App\Http\Requests\StorePostRequest;
public function store(StorePostRequest $request)
{
$validated = $request->validated();
Post::create($validated);
return redirect('/posts')->with('success', 'Artikel berhasil disimpan.');
}
Validasi berjalan otomatis sebelum kode di dalam metode dieksekusi. Controller menjadi bersih dan hanya fokus pada logika bisnis. Pola Form Request ini juga dipakai di form autentikasi seperti pada tutorial login dan register dengan Breeze, sehingga layak kamu kuasai sejak awal.
Membuat Aturan Validasi Sendiri
Kadang aturan bawaan tidak cukup, misalnya kamu ingin menolak judul yang mengandung kata terlarang tertentu. Laravel 12 menyediakan perintah Artisan untuk membuat rule kustom.
php artisan make:rule NoSpamWord
Perintah itu membuat class app/Rules/NoSpamWord.php. Implementasikan logika di metode validate():
<?php
namespace App\Rules;
use Closure;
use Illuminate\Contracts\Validation\ValidationRule;
class NoSpamWord implements ValidationRule
{
public function validate(string $attribute, mixed $value, Closure $fail): void
{
$kataTerlarang = ['gratis', 'promo', 'diskon'];
foreach ($kataTerlarang as $kata) {
if (str_contains(strtolower($value), $kata)) {
$fail('Kolom :attribute mengandung kata yang tidak diizinkan.');
return;
}
}
}
}
Pakai rule kustom ini seperti aturan biasa dengan membuat instance-nya di array aturan:
use App\Rules\NoSpamWord;
$request->validate([
'title' => ['required', 'string', 'min:5', new NoSpamWord],
]);
Perhatikan bahwa aturannya ditulis sebagai array (bukan string pipe) ketika dicampur dengan objek rule. Placeholder :attribute otomatis diganti dengan nama field. Rule kustom cocok untuk logika bisnis yang spesifik dan dipakai di banyak form.
Menampilkan Error di Blade
Pesan error yang dihasilkan validasi tersedia di view lewat variabel $errors. Pola yang umum dipakai adalah menampilkan ringkasan di atas form dan pesan per field di bawah inputnya.
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<form method="POST" action="/posts">
@csrf
<label for="title">Judul</label>
<input type="text" name="title" id="title" value="{{ old('title') }}">
@error('title')
<small class="text-danger">{{ $message }}</small>
@enderror
<label for="body">Isi Artikel</label>
<textarea name="body" id="body">{{ old('body') }}</textarea>
@error('body')
<small class="text-danger">{{ $message }}</small>
@enderror
<button type="submit">Simpan</button>
</form>
Directive @error('title') hanya merender isinya jika field title memiliki pesan error, dan variabel $message berisi teks error tersebut. Fungsi old('title') mengisi kembali input dengan nilai yang dikirim pengguna sebelumnya, sehingga mereka tidak perlu mengetik ulang seluruh form hanya karena satu field salah. Kombinasi ketiganya menghasilkan form yang ramah pengguna dengan sedikit kode.
Tips Validasi untuk REST API
Untuk endpoint API, perilaku bawaan validate() yang me-redirect kurang cocok karena klien API mengharapkan respons JSON. Laravel menanganinya otomatis: jika request memiliki header Accept: application/json, kegagalan validasi mengembalikan respons JSON berisi pesan error dengan status 422, tanpa redirect. Jadi aturan yang sama bisa dipakai ulang untuk API.
Untuk struktur API yang lebih terkontrol, validasi juga bisa dilakukan manual dengan Validator::make() agar kamu mengatur sendiri format responsnya. Pembahasan lengkap pola ini ada di artikel cara membuat REST API dengan Laravel yang sudah terbit di blog ini.
Kesimpulan
Form validasi Laravel 12 memberimu tiga lapis kemudahan: $request->validate() untuk kebutuhan cepat, pesan error kustom Bahasa Indonesia agar pengguna paham kesalahannya, dan Form Request class untuk kode yang rapi dan bisa dipakai ulang. Aturan seperti required, unique, exists, dan confirmed mencakup sebagian besar kebutuhan form sehari-hari tanpa query manual.
Mulailah dengan menerapkan validasi pada satu form yang sudah kamu buat, misalnya form tambah artikel dari seri CRUD, lalu pindahkan aturannya ke Form Request saat form mulai kompleks. Kalau kamu ingin mendalami alur autentikasi yang juga mengandalkan validasi berat, baca juga tutorial Laravel 12 membuat fitur login dan register dengan Breeze sebagai latihan berikutnya.