Schémas Zod
Validez et documentez vos inputs avec Zod.
Qu'est-ce que Zod ?
Zod est une libraire TypeScript pour la validation de schémas runtime. Elle permet de :
- Valider les données à l'exécution
- Documenter vos APIs via
.describe() - Générer des schémas OpenAPI automatiquement
- Garantir la type-sécurité avec TypeScript
Schéma simple
import { z } from "zod";
const GreetingSchema = z.object({
name: z.string().describe("Le nom de la personne"),
age: z.number().int().positive().describe("L'âge en années"),
});
// Inférer le type TypeScript
type Greeting = z.infer<typeof GreetingSchema>;
// = { name: string; age: number }
// Valider
const result = GreetingSchema.parse({
name: "Alice",
age: 30,
});
Types courants
Strings
z.string() // Any string
.email() // Valid email
.url() // Valid URL
.min(3) // Min length
.max(50) // Max length
.regex(/^[a-z]+$/) // Regex pattern
.describe("Description") // Documentation
Numbers
z.number()
.int() // Integer only
.positive() // > 0
.negative() // < 0
.gte(0) // >= 0
.lte(100) // <= 100
.describe("A number")
Arrays
z.array(z.string()) // Array of strings
.min(1) // At least 1 item
.max(10) // Max 10 items
.describe("List of names")
Enums
z.enum(["red", "green", "blue"])
.describe("A color")
// Or with TypeScript enum
enum Color {
Red = "red",
Green = "green",
Blue = "blue",
}
z.nativeEnum(Color).describe("A color")
Objects
z.object({
name: z.string(),
email: z.string().email(),
age: z.number().optional(), // Optional field
tags: z.array(z.string()),
}).describe("User object")
Validation optionnelle
// Optional field (undefined allowed)
z.object({
nickname: z.string().optional(),
})
// Default value
z.object({
language: z.enum(["fr", "en"]).default("fr"),
})
// Nullable
z.object({
middleName: z.string().nullable(),
})
Gestion des erreurs
const schema = z.object({
email: z.string().email("Email invalide"),
age: z.number().positive("L'âge doit être positif"),
});
// Utiliser .parse() (lance une erreur)
try {
const result = schema.parse({
email: "invalid",
age: -5,
});
} catch (error) {
console.error(error.issues); // Liste des erreurs
}
// Ou utiliser .safeParse() (retourne un Result)
const result = schema.safeParse({
email: "invalid",
age: -5,
});
if (!result.success) {
console.error(result.error.issues);
} else {
console.log(result.data);
}
Bonnes pratiques
✅ DO
- Utilisez
.describe()pour chaque champ important - Validez au point d'entrée (au début du handler)
- Utilisez
.safeParse()pour les APIs externes - Créez des schémas réutilisables
- Inférez les types avec
z.infer<>
❌ DON'T
- Ne truquer pas la validation (ne pas faire
.parse()aveuglément) - Ne pas créer des schémas trop complexes dans le handler
- Ne pas oublier
.describe()(c'est pour la documentation OpenAPI) - Ne pas dupliquer les schémas
Schéma réutilisable
// schemas/common.ts
export const EmailSchema = z.string().email().describe("Adresse email valide");
export const PhoneSchema = z.string().regex(/^\+?[0-9-]{10,}/).describe("Numéro de téléphone");
// schemas/user.ts
export const UserInputSchema = z.object({
email: EmailSchema,
phone: PhoneSchema.optional(),
name: z.string().min(2).describe("Nom complet"),
});