Validation des données avec Zod (Next.js / TypeScript)

Validez les données API avec Zod pour éviter les erreurs runtime et sécuriser vos flux front/back.

4 min read

Accéder gratuitement à cette formation

Renseigne ton email pour débloquer immédiatement cette formation gratuite.

Mise à jour SEO (Mars 2026)

Dans cette leçon, vous mettez en place Zod pour filtrer et typer les réponses API afin de fiabiliser vos fonctionnalités avant affichage.

Dans cette leçon, tu vas apprendre à protéger tes données provenant de l’API The Movie Database en utilisant Zod. Plutôt que de travailler avec du any, Zod te permet de :

  • Décrire un schéma pour les réponses de l’API
  • Valider automatiquement les propriétés reçues
  • Inférer des types TypeScript à partir du schéma

ℹ️ On se concentre ici sur la validation côté serveur dans app/server/movies.ts.


Installer Zod

Démarre par ajouter Zod à ton projet :

Terminal
1
npm install zod

Définir le schéma pour une liste de films

Ouvre app/server/movies.ts et ajoute un schéma qui reflète la structure renvoyée par l’API :

app/server/movies.ts
1
import { z } from 'zod'
2
3
const GetMoviesSchema = z.object({ // ^? z.object: crée un schema objet
4
page: z.number(), // ^? z.number: nombre de page
5
results: z.array(
6
z.object({
7
id: z.number(), // ^? z.number: identifiant du film
8
title: z.string(), // ^? z.string: titre du film
9
poster_path: z.string(), // ^? z.string: chemin de l'affiche
10
release_date: z.string(), // ^? z.string: date de sortie
11
})
12
),
13
})

Parser les données et renvoyer des résultats typés

Ensuite, utilise parse() pour valider la réponse brute et extraire results :

app/server/movies.ts
1
export async function getMovies() {
2
const data = await fetchMovieDb({ url: '/movie/popular' })
3
// @callout: parse l'objet `data` selon le schéma et lève si invalidé
4
const { results } = GetMoviesSchema.parse(data)
5
return results
6
}

Une fois validées, les données sont considérées « sûres ». Tu peux boucler dessus sans crainte.


Inférer le type Movie

Pour bénéficier de la complétion TypeScript, crée un type à partir du schéma :

app/server/movies.ts
1
export type Movie = z.infer<
2
typeof GetMoviesSchema
3
>['results'][number] // ^? infère le type d'un élément du tableau results

Désormais, getMovies() renvoie un Movie[] et chaque movie est typé précisément.


Étendre la validation aux séries

L’API propose également /tv/popular. Tu peux définir un schéma similaire :

app/server/movies.ts
1
const GetSeriesSchema = z.object({
2
page: z.number(),
3
results: z.array(
4
z.object({
5
id: z.number(),
6
name: z.string(),
7
poster_path: z.string(),
8
first_air_date: z.string(),
9
})
10
),
11
})
12
13
export async function getSeries() {
14
const data = await fetchMovieDb({ url: '/tv/popular' })
15
const { results } = GetSeriesSchema.parse(data)
16
return results
17
}
18
19
export type Series = z.infer<
20
typeof GetSeriesSchema
21
>['results'][number]

Validation d’un film ou d’une série détaillée

Pour l’appel /movie/{id} ou /tv/{id}, tu peux valider un objet unique :

app/server/movies.ts
1
// film détaillé
2
const GetMovieDetailSchema = z.object({
3
id: z.number(),
4
title: z.string(),
5
poster_path: z.string(),
6
release_date: z.string(),
7
})
8
9
export async function getMovie({ movieId }: { movieId: number }) {
10
'use cache'
11
const data = await fetchMovieDb({ url: `/movie/${movieId}` })
12
const result = GetMovieDetailSchema.parse(data) // lève si champs manquant
13
return result
14
}

Tu peux faire de même pour getSerie().


Bonnes pratiques

  • Toujours valider avant de manipuler les données.
  • Utilise safeParse() pour récupérer un objet success/error si tu veux gérer les erreurs sans exception.
  • Factorise tes schémas si plusieurs appels partagent des champs communs.

Exercices rapides

  1. Créer un schéma de détail de série
    Réalise un GetSerieDetailSchema dans app/server/movies.ts et valide la réponse de /tv/{serieId}.

  2. Tester la validation côté serveur
    Modifie getMovies() pour utiliser safeParse(). En cas d’erreur, logue le détail avant de rethrow.

  3. Étendre le type Movie
    Ajoute la propriété overview: z.string() dans GetMoviesSchema et vérifie que l’IDE remonte bien le type dans MovieCard.


Tu as maintenant toutes les clés pour sécuriser tes données externes et tirer pleinement parti de TypeScript !

Aller plus loin avec Algomax