TechTopia Casing SSD NVMe NGFF USB 3.1 Type-C Enclosure Eksternal M.2 SATA & NVMe High Speed

Laravel Validation: Cara Membuat Validasi Form yang Aman dan Rapi

Validasi form adalah bagian penting dalam hampir setiap aplikasi web.

Ketika pengguna mengirim data, aplikasi tidak boleh langsung menganggap semua input tersebut benar. Data dapat kosong, memiliki format yang salah, terlalu panjang, menggunakan nilai yang tidak diperbolehkan, atau bahkan sengaja dimanipulasi.

Laravel menyediakan sistem validation yang cukup lengkap sehingga developer dapat menentukan aturan input dengan cara yang konsisten dan mudah dibaca.

Contohnya:

$request->validate([
    'name' => ['required', 'string', 'max:100'],
    'email' => ['required', 'email'],
    'password' => ['required', 'min:8'],
]);

Dengan beberapa baris tersebut, Laravel dapat memeriksa data sebelum diproses lebih lanjut.

Namun, validasi bukan hanya tentang membuat form menolak input yang salah. Validasi yang baik juga harus mempertimbangkan keamanan, pengalaman pengguna, maintainability, dan aturan bisnis aplikasi.

Apa Itu Validation di Laravel?

Validation adalah proses memeriksa apakah data yang diterima aplikasi memenuhi aturan tertentu.

Misalnya form registrasi membutuhkan:

Nama
Email
Password

Aturannya mungkin:

Nama
→ wajib diisi

Email
→ wajib diisi
→ harus memiliki format email
→ belum boleh digunakan

Password
→ wajib diisi
→ minimal 8 karakter

Laravel memungkinkan aturan tersebut ditulis langsung dalam kode.

Mengapa Validasi Penting?

Tanpa validasi, aplikasi dapat menerima data seperti:

Nama: kosong
Email: bukan alamat email
Umur: abc
Harga: -999999
File: executable berbahaya

Data seperti ini dapat menyebabkan:

  • error aplikasi,
  • data database tidak konsisten,
  • pengalaman pengguna buruk,
  • masalah keamanan,
  • kegagalan proses bisnis.

Karena itu, validasi sebaiknya dilakukan sebelum data diproses atau disimpan.

Validasi Sederhana dengan $request->validate()

Cara paling sederhana adalah menggunakan method:

$request->validate();

Contoh:

public function store(Request $request)
{
    $validated = $request->validate([
        'name' => ['required', 'string', 'max:100'],
        'email' => ['required', 'email'],
    ]);

    // proses data
}

Jika validasi berhasil, $validated berisi data yang lolos validasi.

Jika gagal, Laravel menangani kegagalan validation dan mengembalikan response yang sesuai dengan jenis request.

Mengapa Sebaiknya Menggunakan Data Hasil Validasi?

Daripada menggunakan:

$name = $request->name;
$email = $request->email;

setelah validation, lebih baik menggunakan data yang sudah divalidasi:

$validated = $request->validate([
    'name' => ['required', 'string'],
    'email' => ['required', 'email'],
]);

$name = $validated['name'];
$email = $validated['email'];

Pendekatan ini membuat batas antara input mentah dan input yang sudah tervalidasi menjadi lebih jelas.

Untuk aplikasi yang kompleks, kebiasaan ini juga membantu mencegah field yang tidak diperlukan ikut diproses.

Rule required

Rule paling dasar adalah:

'required'

Contoh:

$request->validate([
    'name' => ['required'],
]);

Artinya field name harus memiliki nilai yang dianggap tersedia.

Jika pengguna tidak mengirimkan field tersebut, validation gagal.

Rule string

Untuk memastikan nilai berupa string:

'name' => ['required', 'string'],

Biasanya rule ini digunakan bersama batas panjang:

'name' => ['required', 'string', 'max:100'],

Rule max dan min

Untuk string:

'title' => ['required', 'string', 'min:5', 'max:150'],

Artinya title minimal lima karakter dan maksimal 150 karakter.

Untuk angka, min dan max dapat digunakan sesuai konteks tipe data.

Validasi Email

Gunakan:

'email' => ['required', 'email'],

Jika email harus unik di tabel users, gunakan rule unique.

use Illuminate\Validation\Rule;

'email' => [
    'required',
    'email',
    Rule::unique('users', 'email'),
],

Dengan demikian validation dapat memastikan format email benar sekaligus memeriksa apakah email sudah digunakan.

Validasi Email Saat Update Data

Ini adalah kasus yang sering membuat developer keliru.

Misalnya user dengan ID 10 sedang mengubah profile:

$email = '[email protected]';

Email tersebut memang sudah ada di database, tetapi milik user yang sedang melakukan update.

Jika hanya menggunakan:

'email' => ['required', 'email', 'unique:users,email'],

validation akan menganggap email tersebut sudah digunakan.

Gunakan Rule::unique() dan abaikan record yang sedang diedit:

use Illuminate\Validation\Rule;

'email' => [
    'required',
    'email',
    Rule::unique('users', 'email')->ignore($user->id),
],

Ini adalah pola penting untuk form update.

Validasi Password

Untuk password, jangan hanya mengandalkan:

'password' => ['required', 'min:8'],

Jika aplikasi membutuhkan kebijakan password yang lebih kuat, Laravel menyediakan rule password yang dapat dikonfigurasi.

Contohnya:

use Illuminate\Validation\Rules\Password;

'password' => [
    'required',
    'confirmed',
    Password::min(8)
        ->mixedCase()
        ->numbers()
        ->symbols(),
],

Rule tersebut dapat memastikan password memenuhi persyaratan tertentu.

Rule confirmed

Jika form memiliki:

password
password_confirmation

gunakan:

'password' => [
    'required',
    'confirmed',
],

Laravel akan memeriksa kesesuaian antara kedua field tersebut.

Contoh request:

password = rahasia123
password_confirmation = rahasia123

akan lolos jika aturan lainnya juga terpenuhi.

Validasi Angka

Misalnya form meminta jumlah stok:

'stock' => ['required', 'integer', 'min:0'],

Dengan begitu input seperti:

stock = abc

dapat ditolak.

Untuk harga:

'price' => ['required', 'numeric', 'min:0'],

Pemilihan integernumeric, atau rule lain harus disesuaikan dengan tipe data dan kebutuhan aplikasi.

Validasi Boolean

Untuk checkbox atau flag:

'is_active' => ['required', 'boolean'],

Jika field boleh tidak dikirim:

'is_active' => ['sometimes', 'boolean'],

Perhatikan perbedaan antara:

required

dan:

sometimes

required berarti field harus ada dan memenuhi aturan.

sometimes berarti aturan diterapkan jika field tersebut ada dalam input.

nullable

Gunakan nullable jika field boleh memiliki nilai null.

Contoh:

'phone' => [
    'nullable',
    'string',
    'max:30',
],

Artinya phone boleh kosong sebagai null, tetapi jika memiliki nilai maka harus berupa string dengan panjang maksimal 30 karakter.

sometimes vs nullable

Keduanya sering tertukar.

Contoh:

'phone' => ['sometimes', 'string', 'max:30'],

Artinya validation rule tersebut diterapkan jika phone dikirim.

Sedangkan:

'phone' => ['nullable', 'string', 'max:30'],

berarti field diharapkan ada dalam data yang divalidasi, tetapi nilainya boleh null.

Perbedaan ini menjadi penting terutama pada API dan partial update.

Validasi Array

Misalnya form mengirim:

tags = [1, 2, 3]

Validation:

'tags' => ['required', 'array'],

Jika setiap ID harus berupa integer:

'tags' => ['required', 'array'],
'tags.*' => ['integer'],

Atau jika setiap tag harus benar-benar ada:

'tags' => ['required', 'array'],
'tags.*' => ['integer', 'exists:tags,id'],

Tanda * digunakan untuk memvalidasi setiap item di dalam array.

Validasi Array dengan distinct

Jika sebuah ID tidak boleh muncul dua kali:

'tags' => ['required', 'array'],
'tags.*' => [
    'integer',
    'exists:tags,id',
    'distinct',
],

Input:

[1, 2, 3]

valid.

Sedangkan:

[1, 2, 2]

akan gagal pada rule distinct.

Validasi exists

Untuk memastikan nilai tersedia di database:

'user_id' => [
    'required',
    'integer',
    'exists:users,id',
],

Artinya user_id harus merujuk pada record yang benar-benar ada di tabel users.

Ini sangat penting untuk input seperti:

category_id
user_id
product_id
tag_id

Jangan hanya mengandalkan bahwa ID yang dikirim client pasti valid.

Validasi in

Jika sebuah field hanya boleh memiliki nilai tertentu:

'status' => [
    'required',
    'in:draft,published,archived',
],

Input selain tiga nilai tersebut akan ditolak.

Untuk aturan yang lebih kompleks, gunakan Rule::in():

use Illuminate\Validation\Rule;

'status' => [
    'required',
    Rule::in([
        'draft',
        'published',
        'archived',
    ]),
],

Validasi date

Untuk tanggal:

'published_at' => [
    'required',
    'date',
],

Jika membutuhkan format tertentu, gunakan rule tanggal yang sesuai dengan kebutuhan aplikasi.

Misalnya:

'published_at' => [
    'required',
    'date_format:Y-m-d H:i:s',
],

Dengan begitu format input dapat dikontrol lebih ketat.

Validasi File Upload

Upload file membutuhkan perhatian khusus.

Misalnya form memungkinkan user mengunggah avatar:

'avatar' => [
    'required',
    'image',
    'max:2048',
],

max:2048 pada konteks file biasanya berarti batas ukuran dalam kilobyte.

Untuk membatasi jenis file:

'document' => [
    'required',
    'file',
    'mimes:pdf,doc,docx',
    'max:5120',
],

Jangan hanya memeriksa ekstensi file dari nama file yang diberikan pengguna.

Validasi file sebaiknya dilakukan berdasarkan mekanisme file validation Laravel dan kebutuhan keamanan aplikasi.

Validasi Gambar

Untuk gambar:

'image' => [
    'required',
    'image',
    'max:2048',
],

Jika ingin membatasi dimensi:

'image' => [
    'required',
    'image',
    'dimensions:min_width=300,min_height=300',
],

Ini berguna untuk memastikan gambar memenuhi kebutuhan UI aplikasi.

Validasi Conditional

Tidak semua field harus selalu divalidasi dengan aturan yang sama.

Misalnya company_name wajib diisi hanya jika tipe account adalah business.

Rule seperti required_if dapat digunakan:

'company_name' => [
    'required_if:account_type,business',
    'string',
    'max:150',
],

Dengan conditional validation, aturan dapat mengikuti kondisi data lainnya.

required_if

Contoh:

'address' => [
    'required_if:delivery_type,courier',
],

Jika:

delivery_type = courier

maka address wajib tersedia.

required_unless

Contoh:

'company_name' => [
    'required_unless:account_type,personal',
],

Artinya field wajib diisi kecuali kondisi tertentu terpenuhi.

required_with

Misalnya:

'phone' => [
    'required_with:country_code',
],

Jika country_code tersedia, phone juga wajib tersedia.

Conditional validation menjadi sangat berguna pada form yang memiliki banyak pilihan dan alur berbeda.

Membuat Form Request

Ketika validation semakin panjang, menulis semuanya di controller dapat membuat controller sulit dibaca.

Laravel menyediakan Form Request untuk memisahkan validation dari controller.

Buat Form Request:

php artisan make:request StorePostRequest

Laravel akan membuat class request di:

app/Http/Requests/

Contoh Form Request

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',
                'max:150',
            ],
            'content' => [
                'required',
                'string',
            ],
        ];
    }
}

Controller kemudian menjadi lebih bersih:

public function store(StorePostRequest $request)
{
    $validated = $request->validated();

    Post::create($validated);
}

Mengapa Form Request Lebih Rapi?

Bandingkan controller yang penuh dengan validation:

public function store(Request $request)
{
    $validated = $request->validate([
        'title' => ['required', 'string', 'max:150'],
        'content' => ['required', 'string'],
        'category_id' => ['required', 'exists:categories,id'],
        'status' => ['required', 'in:draft,published'],
    ]);

    // ...
}

Dengan:

public function store(StorePostRequest $request)
{
    $validated = $request->validated();

    // ...
}

Rule validation sekarang memiliki tempat tersendiri.

Ini sangat berguna ketika aplikasi memiliki banyak endpoint dan form.

Method authorize()

Form Request memiliki method:

public function authorize(): bool
{
    return true;
}

Method ini menentukan apakah request tersebut diizinkan.

Untuk authorization sederhana:

public function authorize(): bool
{
    return auth()->check();
}

Untuk aturan yang lebih spesifik, authorization dapat menggunakan user dan resource terkait.

Dengan demikian Form Request dapat menangani dua hal:

Authorization
+
Validation

Custom Validation Message

Pesan default Laravel biasanya sudah cukup baik, tetapi aplikasi dapat memiliki kebutuhan bahasa atau wording tertentu.

Gunakan method:

public function messages(): array
{
    return [
        'title.required' => 'Judul wajib diisi.',
        'title.max' => 'Judul maksimal :max karakter.',
        'email.unique' => 'Email tersebut sudah digunakan.',
    ];
}

Dengan demikian pesan validation dapat disesuaikan dengan kebutuhan aplikasi.

Custom Attribute Name

Anda juga dapat membuat nama field lebih ramah pengguna:

public function attributes(): array
{
    return [
        'email' => 'alamat email',
        'title' => 'judul artikel',
    ];
}

Pesan validation kemudian dapat menggunakan nama tersebut.

Ini berguna untuk aplikasi berbahasa Indonesia agar pesan error lebih natural.

Menampilkan Error di Blade

Laravel menyediakan error bag yang dapat digunakan pada Blade.

Contoh:

<input
    type="text"
    name="email"
    value="{{ old('email') }}"
>

@error('email')
    <div class="text-red-500">
        {{ $message }}
    </div>
@enderror

Jika field email gagal validation, pesan error akan ditampilkan.

Mempertahankan Input dengan old()

Ketika validation gagal, pengguna tidak seharusnya mengisi ulang seluruh form dari awal.

Gunakan:

value="{{ old('name') }}"

Untuk textarea:

<textarea name="content">{{ old('content') }}</textarea>

Dengan old(), Laravel dapat membantu mengembalikan input sebelumnya ke form.

Jangan Mengembalikan Password dengan old()

Untuk alasan keamanan dan pengalaman pengguna, jangan melakukan:

value="{{ old('password') }}"

Password sebaiknya tidak dipertahankan atau ditampilkan kembali setelah validation gagal.

Menampilkan Semua Error

Jika ingin menampilkan seluruh error:

@if ($errors->any())
    <div>
        <ul>
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
@endif

Ini berguna untuk menampilkan summary error di bagian atas form.

Validation pada API

Untuk API, validation juga sangat penting.

Contoh:

public function store(StorePostRequest $request)
{
    $post = Post::create($request->validated());

    return response()->json([
        'data' => $post,
    ], 201);
}

Ketika validation gagal, Laravel dapat menghasilkan response error yang sesuai untuk request API.

Client kemudian dapat menggunakan informasi tersebut untuk menampilkan pesan kepada pengguna.

Validation Bukan Pengganti Authorization

Ini adalah konsep yang sangat penting.

Validation menjawab:

Apakah data yang dikirim memiliki format dan nilai yang valid?

Authorization menjawab:

Apakah user ini berhak melakukan tindakan tersebut?

Misalnya:

'post_id' => ['required', 'exists:posts,id'],

hanya memastikan post tersebut ada.

Itu tidak berarti user boleh mengubah post tersebut.

Authorization tetap harus diperiksa.

Contohnya:

Validation
→ post_id harus ada

Authorization
→ post tersebut harus milik user ini

Jangan menggabungkan kedua konsep tersebut menjadi satu.

Validation Bukan Pengganti Database Constraint

Validation aplikasi sangat penting, tetapi database juga harus memiliki constraint yang sesuai.

Misalnya email harus unik.

Application validation:

Rule::unique('users', 'email')

Database juga sebaiknya memiliki unique index:

$table->string('email')->unique();

Kenapa?

Karena validation aplikasi saja tidak selalu cukup untuk menghadapi kondisi concurrency.

Database constraint menjadi lapisan perlindungan tambahan.

Validasi dan Mass Assignment

Validasi tidak otomatis berarti semua field aman untuk dimasukkan ke model.

Misalnya:

$validated = $request->validated();

User::create($validated);

Pastikan model memiliki konfigurasi mass assignment yang tepat.

Contoh:

protected $fillable = [
    'name',
    'email',
    'password',
];

Jangan menganggap:

$request->validate(...)

berarti semua field yang masuk otomatis aman untuk mass assignment.

Validation dan mass assignment adalah dua mekanisme berbeda.

Jangan Menggunakan $request->all() Sembarangan

Kode seperti:

User::create($request->all());

sebaiknya dihindari.

Request dapat berisi field tambahan yang tidak Anda harapkan.

Lebih baik:

$validated = $request->validated();

User::create($validated);

Dengan begitu hanya data yang memang lolos proses validation yang digunakan.

Normalisasi Data Sebelum Validation

Dalam beberapa kasus, input perlu dinormalisasi.

Contohnya email:

 [email protected]

mungkin ingin diperlakukan sebagai:

[email protected]

Atau nomor telepon mungkin perlu dinormalisasi ke format tertentu.

Normalisasi dan validation harus dirancang dengan jelas agar hasil yang divalidasi memang sesuai dengan data yang akan disimpan.

Validation Rule untuk Data Unik dan Case Sensitivity

Perhatikan bahwa kebutuhan uniqueness tidak selalu sederhana.

Misalnya aplikasi menganggap:

[email protected]

dan:

[email protected]

sebagai akun yang sama.

Perilaku tersebut dapat bergantung pada database, collation, dan cara aplikasi menormalisasi data.

Karena itu, aturan bisnis untuk uniqueness sebaiknya konsisten antara:

Input normalization
+
Laravel validation
+
Database constraint

Validasi dengan Rule Object

Untuk aturan yang kompleks, menggunakan string panjang dapat membuat kode sulit dibaca.

Contoh:

'status' => [
    'required',
    Rule::in([
        'draft',
        'published',
        'archived',
    ]),
],

Rule object juga dapat digunakan ketika validation membutuhkan logika yang lebih spesifik.

Ini membuat rule lebih mudah dipelihara dibandingkan menaruh seluruh logika dalam controller.

Custom Validation Rule

Jika aturan bisnis tidak tersedia dalam built-in validation rule, Anda dapat membuat custom rule.

Contohnya:

php artisan make:rule ValidUsername

Kemudian rule tersebut dapat digunakan:

'username' => [
    'required',
    new ValidUsername,
],

Custom rule cocok untuk aturan seperti:

Username tidak boleh mengandung kata tertentu
Kode produk harus mengikuti format perusahaan
Nomor tertentu harus memenuhi aturan bisnis khusus

Dengan memisahkan aturan ke class sendiri, kode validation menjadi lebih mudah diuji.

Validasi Berdasarkan Role

Misalnya admin boleh mengirim field tertentu, sedangkan user biasa tidak.

Jangan hanya mengandalkan:

'salary' => ['numeric'],

Jika field tersebut seharusnya hanya tersedia bagi admin.

Aturan akses tetap perlu diperiksa melalui authorization.

Validation dapat dibuat conditional jika memang field tersebut relevan:

'salary' => [
    'sometimes',
    'numeric',
],

Tetapi keputusan apakah user boleh mengubah salary tetap merupakan tanggung jawab authorization.

Validation untuk Update Partial Data

API sering menggunakan PATCH untuk mengubah sebagian data.

Misalnya user hanya mengirim:

{
    "name": "Budi"
}

Tidak semua field harus dianggap wajib.

Gunakan rule seperti:

'name' => ['sometimes', 'string', 'max:100'],
'email' => ['sometimes', 'email'],

Dengan demikian field hanya divalidasi jika dikirim.

Ini berbeda dengan form create yang mungkin membutuhkan:

'name' => ['required', 'string'],
'email' => ['required', 'email'],

Validasi Data Bertingkat

Laravel juga dapat memvalidasi struktur array yang lebih kompleks.

Misalnya:

{
    "items": [
        {
            "product_id": 1,
            "quantity": 2
        },
        {
            "product_id": 5,
            "quantity": 1
        }
    ]
}

Rules:

'items' => ['required', 'array', 'min:1'],
'items.*.product_id' => [
    'required',
    'integer',
    'exists:products,id',
],
'items.*.quantity' => [
    'required',
    'integer',
    'min:1',
],

Pola items.*.field sangat berguna untuk form dinamis dan API dengan nested data.

Validasi File Jangan Hanya Berdasarkan Ekstensi

Kesalahan umum adalah hanya memeriksa:

$extension = $request->file('document')->getClientOriginalExtension();

kemudian menentukan file aman berdasarkan ekstensi tersebut.

Nama file dan ekstensi yang diberikan client tidak boleh dianggap sebagai satu-satunya sumber kebenaran.

Gunakan Laravel file validation dan batasi jenis file sesuai kebutuhan aplikasi.

Selain itu, file yang diunggah sebaiknya disimpan di lokasi yang tepat dan tidak langsung dieksekusi sebagai kode.

Jangan Menyimpan File Upload Sebelum Validation Selesai

Urutan yang lebih aman:

Request
 ↓
Validation
 ↓
Process
 ↓
Store file
 ↓
Save database

Bukan:

Request
 ↓
Store file
 ↓
Validation

Jika validation gagal, aplikasi dapat meninggalkan file yang tidak diperlukan.

Validasi di Client Tidak Cukup

HTML memiliki validation seperti:

<input type="email" required>

JavaScript juga dapat melakukan validation.

Tetapi semua itu tidak boleh menggantikan server-side validation.

Client dapat dimanipulasi.

Pengguna dapat mengirim request langsung tanpa melalui form HTML.

Karena itu:

Client-side validation
→ UX

Server-side validation
→ Security + data integrity

Keduanya dapat digunakan bersama, tetapi server tetap harus melakukan validation.

Praktik Terbaik Laravel Validation

Agar validation tetap rapi, beberapa prinsip berikut sangat berguna.

Gunakan Form Request untuk Form yang Kompleks

Jika rules mulai panjang, pindahkan ke Form Request.

Gunakan $validated atau validated()

Proses data yang sudah lolos validation, bukan seluruh request.

Pisahkan Validation dan Authorization

Jangan menganggap exists berarti user memiliki hak akses terhadap record.

Gunakan Database Constraint

Untuk aturan seperti unique dan foreign key, database tetap harus memiliki constraint yang sesuai.

Buat Custom Rule untuk Logika yang Kompleks

Jangan membuat controller berisi puluhan if hanya untuk validation.

Validasi File dengan Serius

File upload memiliki risiko berbeda dari input text biasa.

Jangan Menampilkan Secret

Password, token, API key, dan data sensitif tidak boleh dikembalikan ke form menggunakan old() atau dimasukkan ke pesan error.

Alur Validation yang Ideal

Dalam aplikasi Laravel, alur yang baik dapat digambarkan seperti:

User Input
    ↓
HTTP Request
    ↓
Authorization
    ↓
Validation
    ↓
Validated Data
    ↓
Business Logic
    ↓
Database

Pada aplikasi yang lebih kompleks, service layer dapat berada setelah validation:

Request
 ↓
Form Request
 ↓
Controller
 ↓
Service
 ↓
Model / Database

Dengan pembagian tersebut, setiap lapisan memiliki tanggung jawab yang jelas.

Contoh Lengkap Form Request

Misalnya aplikasi memiliki form pembuatan artikel.

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;

class StorePostRequest extends FormRequest
{
    public function authorize(): bool
    {
        return $this->user() !== null;
    }

    public function rules(): array
    {
        return [
            'title' => [
                'required',
                'string',
                'min:5',
                'max:150',
            ],

            'content' => [
                'required',
                'string',
            ],

            'status' => [
                'required',
                Rule::in([
                    'draft',
                    'published',
                ]),
            ],

            'category_id' => [
                'required',
                'integer',
                'exists:categories,id',
            ],

            'tags' => [
                'nullable',
                'array',
            ],

            'tags.*' => [
                'integer',
                'exists:tags,id',
                'distinct',
            ],

            'thumbnail' => [
                'nullable',
                'image',
                'max:2048',
            ],
        ];
    }

    public function messages(): array
    {
        return [
            'title.required' => 'Judul artikel wajib diisi.',
            'category_id.exists' => 'Kategori yang dipilih tidak tersedia.',
            'thumbnail.image' => 'Thumbnail harus berupa gambar.',
        ];
    }
}

Controller:

public function store(StorePostRequest $request)
{
    $validated = $request->validated();

    $post = Post::create([
        'title' => $validated['title'],
        'content' => $validated['content'],
        'status' => $validated['status'],
        'category_id' => $validated['category_id'],
    ]);

    if (!empty($validated['tags'])) {
        $post->tags()->sync($validated['tags']);
    }

    return redirect()
        ->route('posts.index')
        ->with('success', 'Artikel berhasil dibuat.');
}

Struktur seperti ini jauh lebih mudah dikembangkan ketika aplikasi mulai membesar.

Checklist Sebelum Form Dianggap Siap

Sebelum sebuah form dianggap selesai, periksa:

  • Apakah field wajib sudah menggunakan required?
  • Apakah tipe data sudah divalidasi?
  • Apakah panjang string dibatasi?
  • Apakah ID terkait menggunakan exists?
  • Apakah data unik menggunakan validation dan database constraint?
  • Apakah file upload sudah divalidasi?
  • Apakah authorization sudah diperiksa?
  • Apakah hanya data tervalidasi yang diproses?
  • Apakah pesan error mudah dipahami?
  • Apakah input sebelumnya dapat dikembalikan menggunakan old()?
  • Apakah password dan secret tidak ditampilkan kembali?
  • Apakah validation untuk create dan update sudah dibedakan jika diperlukan?

Kesimpulan

Laravel Validation memberikan fondasi yang kuat untuk memastikan data yang masuk ke aplikasi memenuhi aturan yang telah ditentukan.

Beberapa konsep penting yang perlu dikuasai adalah:

  • $request->validate() untuk validation sederhana.
  • Form Request untuk validation yang lebih kompleks.
  • requiredstringintegernumericemail, dan rule dasar lainnya.
  • exists dan unique untuk validasi terhadap database.
  • nullable dan sometimes untuk menangani field opsional.
  • confirmed untuk konfirmasi password.
  • array dan wildcard * untuk data bertingkat.
  • File validation untuk upload.
  • Conditional validation untuk form dinamis.
  • whereHas dan authorization tetap berbeda dari validation.
  • $validated dan $request->validated() membantu memastikan hanya data yang telah divalidasi yang diproses.
  • Database constraint tetap penting sebagai lapisan perlindungan tambahan.

Validation yang baik bukan hanya membuat form menolak input yang salah. Validation juga membantu menjaga kualitas data, memperjelas aturan bisnis, meningkatkan keamanan, dan membuat kode Laravel lebih mudah dirawat.

Dengan memisahkan input, validation, authorization, business logic, dan database constraint, aplikasi Laravel akan memiliki fondasi yang jauh lebih kuat ketika jumlah fitur dan pengguna mulai bertambah.