Schema Reuse
Menggunakan satu schema serta schema-derived type untuk form UI dan data boundary tanpa menduplikasi aturan profile.
Tujuan belajar
- Menempatkan schema pada module domain yang dapat diimport
- Mengimpor schema-derived type ke form dan submit logic
- Membedakan reuse yang berguna dari abstraction berlebihan
- Memvalidasi data lagi pada boundary yang menerima input
Isi lesson
6 blok- 1.Satu aturan perlu satu rumah yang mudah ditemukanBelum selesaiWajib
- 2.Form dan service memakai schema profile yang samaBelum selesaiWajib
- 3.Coding practiceBelum selesaiWajib
- 4.Cek pemahamanBelum selesaiWajib
- 5.Shared schema bukan alasan menambah banyak flagBelum selesaiWajib
- 6.RingkasanBelum selesaiWajib
Satu aturan perlu satu rumah yang mudah ditemukan
WajibForm profile dapat muncul pada settings page, onboarding, atau modal kecil. Jika setiap component menulis ulang field serta aturan, perubahan seperti batas nama dari 40 ke 60 karakter mudah membuat UI berbeda. Simpan profileSchema dan ProfileFormValues di satu module validation, lalu import yang diperlukan oleh form serta submit boundary.
Reuse bukan berarti satu schema global untuk seluruh aplikasi. Profile update, password change, dan admin invite bisa memiliki aturan serta authorization berbeda. Reuse ketika domainnya sama. Type yang diturunkan membantu editor, tetapi safeParse atau parse masih diperlukan ketika boundary menerima data yang belum dapat dipercaya saat runtime.
Bagian ini memengaruhi progres lesson.
Form dan service memakai schema profile yang sama
Wajib// lib/validation/profile-schema.ts
import { z } from "zod";
export const profileSchema = z.object({
displayName: z.string().trim().min(2).max(40),
email: z.email(),
});
export type ProfileFormValues = z.infer<typeof profileSchema>;
// components/profile-form.tsx
const form = useForm<ProfileFormValues>({
resolver: zodResolver(profileSchema),
});
// lib/services/update-profile.ts
export async function updateProfile(values: ProfileFormValues) {
const parsed = profileSchema.safeParse(values);
if (!parsed.success) {
throw new Error("Data profile tidak valid.");
}
return persistProfile(parsed.data);
}Form memakai resolver untuk feedback field. Data boundary menjalankan safeParse lagi sebelum persistence. Pada feature user-owned, identity dan authorization server-side tetap diperlukan. Contoh memperlihatkan satu source of truth untuk domain profile, bukan pola untuk memaksa semua form memakai schema yang sama.
Bagian ini memengaruhi progres lesson.
Coding practice
WajibDibuka di workspace khususReuse profile schema type
Lengkapi schema profile dan type turunannya yang dipakai kembali oleh form serta update boundary tanpa menduplikasi shape data.
Tujuan awal: Fokus di tab TSX.
Practice ini dibuka di workspace khusus. Buka practice untuk memakai editor, preview, dan cek otomatis.
Tombol selesai aktif setelah semua validasi wajib lolos.
Cek pemahaman
WajibJawab duluCek pemahaman singkat
Mengapa updateProfile tetap menjalankan safeParse walaupun UI memakai zodResolver?
Progres lesson naik setelah jawaban benar.
Kesalahan umum
WajibShared schema bukan alasan menambah banyak flag
Jika dua feature mulai membutuhkan optional field atau validation rule yang bertentangan, pecah schema dengan nama yang menjelaskan tujuan. Schema yang kecil dan domain-specific lebih mudah dibaca daripada satu object besar yang mencoba menangani setiap variasi form.
Bagian ini memengaruhi progres lesson.
Ringkasan
Wajib- Schema dan z.infer type sebaiknya tinggal pada module domain yang jelas.
- Form memakai resolver, sedangkan data boundary memvalidasi input kembali sebelum operasi penting.
- Reuse mengurangi duplicated rule antara UI dan submit logic.
- Pecah schema jika domain atau aturan feature mulai berbeda.
- Berikutnya, Uji Kompetensi memeriksa seluruh flow form dari registration hingga schema reuse.
Bagian ini memengaruhi progres lesson.
Langkah berikutnya
Selesaikan bagian penting lesson ini
Lanjutkan blok wajib berikutnya: Satu aturan perlu satu rumah yang mudah ditemukan.