Laravel memiliki sistem validasi yang sangat powerful.
Validasi di controller:
public function store(Request $request)
{
$validated = $request->validate([
"name" => "required|string|max:255",
"email" => "required|email|unique:users",
"age" => "nullable|integer|min:1|max:150",
"role" => "required|in:admin,editor,user",
]);
$user = User::create($validated);
return response()->json($user, 201);
}
Rule yang sering dipakai:
| Rule | Keterangan |
|---|---|
required |
Wajib diisi |
string |
Harus string |
integer |
Harus bilangan bulat |
email |
Format email valid |
max:255 |
Maksimal 255 karakter |
min:1 |
Minimal 1 |
unique:table |
Harus unik di tabel |
exists:table,column |
Harus ada di tabel |
in:a,b,c |
Harus salah satu dari daftar |
nullable |
Boleh null |
confirmed |
Harus ada field _confirmation |
Error response otomatis (422):
{
"message": "The name field is required.",
"errors": {
"name": ["The name field is required."],
"email": ["The email has already been taken."]
}
}
Form Request — Ekstrak Validasi dari Controller
Kalau rules-nya panjang atau dipakai di beberapa controller method, pindahkan ke Form Request class. Controller jadi bersih dan validasi lebih mudah di-test.
php artisan make:request StoreUserRequest
// app/Http/Requests/StoreUserRequest.php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class StoreUserRequest extends FormRequest
{
// Authorization — siapa yang boleh pakai request ini
public function authorize(): bool
{
return auth()->check() && auth()->user()->can("create-user");
}
// Aturan validasi
public function rules(): array
{
return [
"name" => ["required", "string", "max:255"],
"email" => ["required", "email", "unique:users"],
"age" => ["nullable", "integer", "min:1", "max:150"],
"role" => ["required", Rule::in(["admin", "editor", "user"])],
];
}
// (Opsional) custom error messages
public function messages(): array
{
return [
"email.unique" => "Email ini sudah terdaftar. Silakan login.",
];
}
// (Opsional) pre-process input sebelum validasi
protected function prepareForValidation(): void
{
$this->merge([
"email" => strtolower(trim($this->email ?? "")),
]);
}
}
Kemudian di controller, type-hint FormRequest-nya — Laravel otomatis memvalidasi sebelum method body dijalankan:
public function store(StoreUserRequest $request)
{
// Kalau validasi gagal, auto-return 422 — kode ini tidak tereksekusi
// Kalau authorize() return false, auto-return 403
$user = User::create($request->validated()); // hanya field yang divalidasi
return response()->json($user, 201);
}
Keuntungan Form Request vs inline $request->validate():
| Inline validate() | Form Request | |
|---|---|---|
| Controller size | Bloat cepat | Tetap ramping |
| Reusability | Copy-paste antar method | Type-hint di banyak method |
| Testability | Harus lewat HTTP test | Bisa di-unit-test langsung |
| Authorization | Di controller terpisah | Nyatu di authorize() |
| Prepare input | Manual di controller | prepareForValidation() |
Rule of thumb: kalau validasi ≤3 rules dan hanya dipakai sekali, inline OK. Begitu lebih dari itu atau dipakai di 2+ method, pindahkan ke Form Request.