Validation dan Form Request - Perwira Learning Center

Latar Belakang

Sebagai lanjutan dari pembahasan mengenai Policy dan Gate di Laravel, tahap berikutnya adalah mempelajari validasi data menggunakan Validation dan Form Request. Dalam pengembangan aplikasi web, data yang dikirimkan oleh pengguna melalui form harus diperiksa terlebih dahulu sebelum diproses oleh sistem. Hal ini penting untuk memastikan bahwa data yang diterima sesuai dengan aturan yang telah ditentukan serta untuk mencegah terjadinya kesalahan atau data yang tidak valid.
Artikel ini dibuat dengan tujuan untuk mendokumentasikan hasil pembelajaran saya mengenai penerapan validasi data di Laravel menggunakan Validation dan Form Request. Dengan memahami konsep ini, saya dapat memastikan bahwa data yang masuk ke dalam sistem telah melalui proses pemeriksaan sehingga aplikasi dapat berjalan dengan lebih stabil dan terkontrol.

Alat dan Bahan

Alat dan Bahan yang digunakan yaitu sebagai berikut:

A. Perangkat Lunak

  • Web browser (Google Chrome) 
  • Code editor (Visual Studio Code)
  • Terminal
  • Web server    
  • Composer 
  • PHP
  • Laravel

B. Perangkat Keras

  • Laptop

Pendahuluan

Dalam pengembangan aplikasi web, validasi input adalah salah satu aspek paling krusial yang tidak boleh diabaikan. Validasi adalah proses pemeriksaan data yang dikirimkan oleh pengguna (melalui form) untuk memastikan bahwa data tersebut memenuhi standar dan aturan yang telah ditentukan sebelum diproses lebih lanjut, seperti disimpan ke dalam database.

Bayangkan sebuah skenario sederhana ketika pengguna mengisi form registrasi:

  • Pengguna mengisi email dengan format yang salah, misalnya budi@com (tanpa domain yang valid).

  • Pengguna membuat password yang terlalu pendek, hanya 3 karakter.

  • Pengguna membiarkan field nama tetap kosong.

Tanpa adanya sistem validasi, data yang masuk ke database bisa menjadi tidak konsisten (contoh: email dengan format salah) dan berpotensi menyebabkan error pada aplikasi di kemudian hari. Selain itu, hal ini juga membuka celah keamanan yang dapat dieksploitasi oleh pihak tidak bertanggung jawab.

Untungnya, Laravel menyediakan sistem validasi yang sangat mudah digunakan, ekspresif, dan fleksibel. Laravel memungkinkan kita untuk mendefinisikan aturan validasi secara sederhana, sehingga kita dapat fokus pada logika utama aplikasi tanpa pusing memikirkan boilerplate code untuk validasi.

Konsep Dasar Validasi di Laravel

Pada dasarnya, validasi di Laravel dilakukan ketika aplikasi menerima request dari form. Laravel memiliki berbagai macam validation rules (aturan validasi) siap pakai, seperti:

  • required: Field tidak boleh kosong.

  • string: Field harus bertipe string.

  • email: Field harus berformat email yang valid.

  • min:n: Field minimal harus berisi n karakter (untuk string) atau bernilai minimal n (untuk angka).

  • max:n: Field maksimal harus berisi n karakter atau bernilai maksimal n.

  • unique:table,column: Field harus bernilai unik pada kolom tertentu di database.

  • dan masih banyak lagi.

Salah satu keunggulan Laravel adalah penanganan error yang otomatis. Ketika validasi gagal, Laravel akan:

  1. Mengembalikan pengguna ke halaman sebelumnya (biasanya halaman form).

  2. Menyimpan input yang telah diisi ke dalam session (flash data) agar bisa ditampilkan kembali menggunakan fungsi old().

  3. Mengirimkan pesan error ke view melalui variable $errors.

Membuat Form Input Menggunakan Laravel Blade

Sebelum masuk ke validasi, mari kita buat dulu sebuah form registrasi sederhana menggunakan Blade, template engine milik Laravel.

Simpan kode berikut dalam file resources/views/register.blade.php.

html
<!DOCTYPE html>
<html>
<head>
    <title>Form Registrasi</title>
    <!-- Sertakan Bootstrap CSS untuk tampilan yang lebih rapi (opsional) -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
    <div class="container mt-5">
        <div class="row justify-content-center">
            <div class="col-md-6">
                <div class="card">
                    <div class="card-header">Form Registrasi</div>
                    <div class="card-body">
                        {{-- Form mengirim data ke route 'register.store' dengan method POST --}}
                        <form method="POST" action="{{ route('register.store') }}">
                            
                            {{-- Directif @csrf untuk melindungi dari serangan CSRF --}}
                            @csrf

                            {{-- Field Nama --}}
                            <div class="mb-3">
                                <label for="name" class="form-label">Nama</label>
                                <input type="text" class="form-control" id="name" name="name" value="{{ old('name') }}">
                                {{-- Tempat pesan error untuk 'name' akan ditampilkan di sini nanti --}}
                            </div>

                            {{-- Field Email --}}
                            <div class="mb-3">
                                <label for="email" class="form-label">Alamat Email</label>
                                <input type="email" class="form-control" id="email" name="email" value="{{ old('email') }}">
                                {{-- Tempat pesan error untuk 'email' akan ditampilkan di sini nanti --}}
                            </div>

                            {{-- Field Password --}}
                            <div class="mb-3">
                                <label for="password" class="form-label">Password</label>
                                <input type="password" class="form-control" id="password" name="password">
                                {{-- Tempat pesan error untuk 'password' akan ditampilkan di sini nanti --}}
                            </div>

                            <button type="submit" class="btn btn-primary">Daftar</button>
                        </form>
                    </div>
                </div>
            </div>
        </div>
    </div>
</body>
</html>

Penjelasan Kode:

  • @csrf: Ini adalah directive Blade yang menghasilkan token CSRF. Token ini akan diverifikasi oleh Laravel untuk memastikan bahwa request yang masuk benar-benar berasal dari aplikasi kita, bukan dari situs jahat.

Validasi Langsung di Controller

Cara pertama dan tercepat untuk melakukan validasi adalah dengan menulisnya langsung di method controller menggunakan method validate() pada request.

Pertama, pastikan Anda memiliki route untuk menampilkan form dan memproses data. Di file routes/web.php:

php
Route::get('/register', function () {
    return view('register');
})->name('register');

Route::post('/register', [RegisterController::class, 'store'])->name('register.store');

Sekarang, buat controller RegisterController (atau gunakan controller yang sudah ada). Di dalam method store, kita tambahkan validasi.

php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\User; // Asumsikan kita punya model User
use Illuminate\Support\Facades\Hash;

class RegisterController extends Controller
{
    public function store(Request $request)
    {
        // --- VALIDASI LANGSUNG DI CONTROLLER ---
        $validatedData = $request->validate([
            'name'     => 'required|string|max:255', // Harus diisi, string, maksimal 255 karakter
            'email'    => 'required|email|unique:users,email', // Harus diisi, format email, unik di tabel users kolom email
            'password' => 'required|min:6', // Harus diisi, minimal 6 karakter
        ]);

        // Jika validasi BERHASIL, kode di bawah sini akan dieksekusi.
        // Data yang sudah divalidasi tersedia dalam variabel $validatedData.

        // Enkripsi password sebelum disimpan
        $validatedData['password'] = Hash::make($validatedData['password']);

        // Simpan data ke database
        User::create($validatedData);

        // Redirect ke halaman sukses atau halaman lain
        return redirect('/')->with('success', 'Registrasi berhasil!');
    }
}

Bagaimana jika validasi gagal?
Jika aturan validasi tidak terpenuhi (misalnya, email sudah terdaftar atau password kurang dari 6 karakter), Laravel akan secara otomatis melemparkan ValidationException. Pengguna akan langsung di-redirect kembali ke halaman form sebelumnya (/register), lengkap dengan input yang telah diisi (melalui fungsi old()) dan daftar pesan error.

Menampilkan Pesan Error di Blade

Setelah validasi gagal dan pengguna diarahkan kembali ke form, kita perlu menampilkan pesan errornya. Laravel menyediakan directive @error dan variable $errors untuk keperluan ini.

Perbarui file register.blade.php Anda dengan menambahkan kode untuk menampilkan error.

html
{{-- Di dalam form, tepat di bawah setiap field input --}}

{{-- Field Nama --}}
<div class="mb-3">
    <label for="name" class="form-label">Nama</label>
    <input type="text" class="form-control @error('name') is-invalid @enderror" id="name" name="name" value="{{ old('name') }}">
    {{-- Menampilkan pesan error untuk field 'name' --}}
    @error('name')
        <div class="invalid-feedback">{{ $message }}</div>
    @enderror
</div>

{{-- Field Email --}}
<div class="mb-3">
    <label for="email" class="form-label">Alamat Email</label>
    <input type="email" class="form-control @error('email') is-invalid @enderror" id="email" name="email" value="{{ old('email') }}">
    {{-- Menampilkan pesan error untuk field 'email' --}}
    @error('email')
        <div class="invalid-feedback">{{ $message }}</div>
    @enderror
</div>

{{-- Field Password --}}
<div class="mb-3">
    <label for="password" class="form-label">Password</label>
    <input type="password" class="form-control @error('password') is-invalid @enderror" id="password" name="password">
    {{-- Menampilkan pesan error untuk field 'password' --}}
    @error('password')
        <div class="invalid-feedback">{{ $message }}</div>
    @enderror
</div>

{{-- Atau, untuk menampilkan semua error dalam satu daftar --}}
@if ($errors->any())
    <div class="alert alert-danger">
        <ul>
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
@endif

Penjelasan Kode:

  • @error('field'): Directive ini akan mengecek apakah ada pesan error untuk field tertentu. Jika ada, kode di dalamnya akan dieksekusi dan variable $message akan berisi teks error-nya.

  • $errors->any(): Mengecek apakah ada error apapun.

  • $errors->all(): Mendapatkan semua pesan error dalam bentuk array.

Menggunakan Form Request untuk Validasi

Menulis validasi langsung di controller memang cepat, tetapi saat aplikasi Anda semakin besar dan kompleks, controller bisa menjadi sangat gemuk dan sulit dibaca. Logika validasi bercampur dengan logika penyimpanan data dan logika bisnis lainnya.

Solusinya adalah dengan memisahkan logika validasi ke dalam kelas khusus yang disebut Form Request.

Langkah 1: Membuat Form Request
Jalankan perintah Artisan berikut di terminal:

bash
php artisan make:request StoreUserRequest

Perintah ini akan membuat file baru di app/Http/Requests/StoreUserRequest.php.

Langkah 2: Memahami Struktur File Form Request
Buka file tersebut, Anda akan melihat dua method utama:

  • authorize(): Method ini digunakan untuk menentukan apakah pengguna yang sedang login diizinkan untuk melakukan request ini. Biasanya kita akan mengembalikan true jika tidak ada sistem otorisasi yang rumit.

  • rules(): Method inilah yang akan kita gunakan untuk mendefinisikan aturan validasi.

Langkah 3: Menambahkan Logika Validasi ke Form Request
Modifikasi file StoreUserRequest.php seperti berikut:

php
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class StoreUserRequest extends FormRequest
{
    /**
     * Tentukan apakah pengguna diizinkan untuk melakukan request ini.
     */
    public function authorize(): bool
    {
        // Untuk sementara kita izinkan semua request.
        // Jika ada sistem login, kita bisa cek di sini, misal: return auth()->check();
        return true;
    }

    /**
     * Dapatkan aturan validasi yang berlaku untuk request.
     */
    public function rules(): array
    {
        return [
            'name'     => 'required|string|max:255',
            'email'    => 'required|email|unique:users,email',
            'password' => 'required|min:6',
        ];
    }

    /**
     * (Opsional) Kustomisasi pesan error untuk aturan tertentu.
     */
    public function messages(): array
    {
        return [
            'name.required' => 'Nama lengkap wajib diisi.',
            'email.required' => 'Alamat email tidak boleh kosong.',
            'email.email' => 'Format email tidak valid.',
            'email.unique' => 'Email ini sudah terdaftar.',
            'password.required' => 'Password wajib diisi.',
            'password.min' => 'Password minimal :min karakter.',
        ];
    }
}

Menggunakan Form Request pada Controller

Setelah Form Request siap, kita bisa menggunakannya di controller. Caranya sangat mudah, yaitu dengan mengetik-hint (type-hint) kelas Form Request tersebut pada method controller, menggantikan parameter Request biasa.

Sekarang, bersihkan controller RegisterController kita.

php
<?php

namespace App\Http\Controllers;

// Kita tidak lagi memanggil Request, tapi StoreUserRequest
use App\Http\Requests\StoreUserRequest;
use App\Models\User;
use Illuminate\Support\Facades\Hash;

class RegisterController extends Controller
{
    // Parameter Request diganti dengan StoreUserRequest
    public function store(StoreUserRequest $request)
    {
        // Jika kode sampai di sini, artinya validasi BERHASIL!
        // Data yang sudah tervalidasi bisa diambil dengan $request->validated()
        $validatedData = $request->validated();

        // Enkripsi password
        $validatedData['password'] = Hash::make($validatedData['password']);

        // Simpan data ke database
        User::create($validatedData);

        // Redirect ke halaman sukses
        return redirect('/')->with('success', 'Registrasi berhasil!');
    }
}

Bagaimana cara kerjanya?
Laravel secara otomatis akan menjalankan mekanisme Dependency Injection. Sebelum method store() dieksekusi, Laravel akan membuat instance dari StoreUserRequest dan menjalankan logika validasi yang ada di dalamnya. Jika validasi gagal, pengguna akan langsung di-redirect kembali ke halaman form, persis seperti metode sebelumnya. Controller tidak perlu tahu menahu tentang aturan validasinya, sehingga kodenya menjadi sangat bersih dan fokus pada tugas utamanya (menyimpan data).

Studi Kasus Sederhana

Mari kita lihat alur lengkap dari studi kasus registrasi pengguna dengan Form Request:

  1. User membuka halaman http://laravel-app.test/register dan mengisi form.

  2. User menekan tombol "Daftar", mengirimkan data POST ke route register.store.

  3. Laravel menerima request dan mengarahkannya ke method store di RegisterController, tetapi karena parameter method meminta StoreUserRequest, Laravel secara otomatis membuat objek StoreUserRequest terlebih dahulu.

  4. Form Request StoreUserRequest menjalankan validasi berdasarkan aturan di method rules().

    • Kasus 1 (Validasi Gagal): Jika ada data yang tidak sesuai aturan, Form Request akan melempar exception. User langsung di-redirect kembali ke halaman form register dengan pesan error dan input lama.

    • Kasus 2 (Validasi Berhasil): Jika semua data sesuai, maka proses dilanjutkan ke method store di controller.

  5. Controller RegisterController menerima data yang sudah tervalidasi melalui $request->validated(). Controller kemudian memproses data tersebut (misalnya mengenkripsi password) dan menyimpannya ke database menggunakan Model User.

  6. Setelah data tersimpan, controller mengembalikan response berupa redirect ke halaman utama dengan pesan sukses.

Dengan menggunakan Form Request, kita berhasil memisahkan tanggung jawab (separation of concerns):

  • Form Request bertanggung jawab atas validasi dan otorisasi.

  • Controller bertanggung jawab atas logika aplikasi (menyimpan data).

Hasil Pembelajaran

Melalui pembelajaran ini, saya memahami bahwa Laravel menyediakan fitur validasi yang dapat digunakan untuk memeriksa data yang dikirimkan oleh pengguna. Validasi dapat dilakukan secara langsung di dalam controller dengan menentukan aturan tertentu, seperti memastikan bahwa suatu field tidak boleh kosong, memiliki format tertentu, atau memiliki batasan panjang karakter.

Selain itu, saya juga mempelajari penggunaan Form Request yang memungkinkan proses validasi dipisahkan dari controller. Dengan menggunakan Form Request, aturan validasi dapat dikelola dalam kelas tersendiri sehingga kode menjadi lebih rapi dan mudah dipelihara. Pendekatan ini membantu menjaga struktur aplikasi tetap terorganisir ketika jumlah validasi semakin banyak.

Kesimpulan

Validasi dan Form Request merupakan bagian penting dalam pengembangan aplikasi menggunakan Laravel karena berfungsi untuk memastikan bahwa data yang diterima oleh sistem telah memenuhi aturan yang ditentukan. Dengan adanya proses validasi, risiko kesalahan data dapat diminimalkan dan keamanan aplikasi dapat lebih terjaga.

Pemahaman mengenai penggunaan Validation dan Form Request membantu dalam membangun aplikasi yang lebih terstruktur, stabil, dan mudah dikelola karena proses pemeriksaan data dilakukan secara sistematis sebelum data diproses lebih lanjut.