nextjsserver-actionsvalidasizodMenengah4 mnt baca

Validasi Data di Server Actions

Memvalidasi input form dengan Zod di Server Action agar data kotor tidak masuk database.

Kenapa validasi server wajib?

Validasi di browser (atribut required, JavaScript) mudah dilewati: user bisa mematikan JavaScript atau mengirim request manual. Satu-satunya validasi yang bisa dipercaya adalah di server. Server Action adalah tempat yang tepat.

Pakai Zod

Zod adalah library validasi skema yang populer. Instal dulu:

bash
npm install zod

Lalu definisikan skema dan validasi di dalam action:

tsx
// app/daftar/actions.ts
"use server";

import { z } from "zod";

const skemaDaftar = z.object({
  nama: z.string().min(3, "Nama minimal 3 karakter"),
  email: z.string().email("Email tidak valid"),
  umur: z.coerce.number().min(17, "Minimal 17 tahun"),
});

export async function daftar(formData: FormData) {
  const hasil = skemaDaftar.safeParse({
    nama: formData.get("nama"),
    email: formData.get("email"),
    umur: formData.get("umur"),
  });

  if (!hasil.success) {
    return {
      sukses: false,
      error: hasil.error.flatten().fieldErrors,
    };
  }

  // hasil.data sudah bersih dan ter-typed
  await simpanUser(hasil.data);
  return { sukses: true };
}

Menampilkan error ke user

Kembalikan error sebagai data (bukan throw), lalu tampilkan di form dengan useActionState:

tsx
"use client";

import { useActionState } from "react";
import { daftar } from "./actions";

export default function FormDaftar() {
  const [state, action] = useActionState(daftar, null);

  return (
    <form action={action}>
      <input name="nama" placeholder="Nama" />
      {state?.error?.nama && <p>{state.error.nama[0]}</p>}
      <input name="email" placeholder="Email" />
      {state?.error?.email && <p>{state.error.email[0]}</p>}
      <button type="submit">Daftar</button>
    </form>
  );
}

Kesalahan umum pemula

  • Memakai parse() bukan safeParse(). parse() melempar exception dan memicu halaman error. Untuk salah input user, safeParse() jauh lebih elegan.
  • Validasi hanya di browser. Atribut required dan JavaScript mudah dilewati. Validasi server dengan Zod adalah pertahanan sebenarnya.
  • Pesan error terlalu teknis. "String must contain at least 3 character(s)" membingungkan user awam. Tulis pesan kustom bahasa Indonesia yang jelas.

Latihan singkat

  1. Tambahkan field "umur" dengan validasi minimal 17 tahun dan pesan error bahasa Indonesia.
  2. Buat skema untuk form produk: nama (min 3 karakter), harga (angka positif), dan stok (angka bulat minimal 0).

Rangkuman

  • Validasi server dengan Zod adalah pertahanan sebenarnya; validasi browser mudah dilewati.
  • Pakai safeParse() agar salah input ditangani elegan, bukan melempar halaman error.
  • Kembalikan error sebagai data dan tampilkan dengan useActionState.
  • Tulis pesan error bahasa Indonesia yang jelas untuk user.

Catatan teknis: Pakai safeParse bukan parse. parse melempar exception yang memicu error.tsx dan menampilkan halaman error ke user, padahal ini cuma salah input. safeParse mengembalikan objek hasil yang bisa kamu tangani dengan elegan.