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"),
});

Prochaines étapes

Créer un premier plugin

Previous

← Page précédente

Next

Page suivante →