Synchronisation de Contrat Interface
Automatise la cohérence des types entre ton Backend Headless et ton Frontend Next.js, finis les désalignements silencieux.
2.1Le problème des deux ateliers
Dans un RPG multijoueur, quand le dev backend change une API (renomme un champ user_name en username), le frontend plante silencieusement. Pas d'erreur de compilation. Juste un undefined discret qui casse l'UI en production.
Ce scénario arrive tout le temps en architecture headless. La solution : un contrat partagé qui force les deux côtés à rester alignés.
2.2Stratégie 1 : Zod comme source de vérité unique
Zod te permet de définir un schéma une seule fois et d'en dériver automatiquement le type TypeScript. Tu utilises ce même schéma pour valider les données à l'entrée et pour typer ton composant.
import { z } from 'zod';
// 1. Définir le schéma une seule fois
export const WpPostSchema = z.object({
id: z.number(),
slug: z.string(),
status: z.enum(['publish', 'draft', 'pending', 'private']),
title: z.object({ rendered: z.string() }),
content: z.object({ rendered: z.string(), protected: z.boolean() }),
excerpt: z.object({ rendered: z.string(), protected: z.boolean() }),
date: z.string().datetime(),
author: z.number(),
categories: z.array(z.number()),
featured_media: z.number(),
});
// 2. Dériver les types automatiquement depuis le schéma
export type WpPost = z.infer<typeof WpPostSchema>;
export type WpPostStatus = WpPost['status']; // 'publish' | 'draft' | ...
// 3. Dériver un type "partial" pour les formulaires d'édition
export const WpPostDraftSchema = WpPostSchema.partial();
export type WpPostDraft = z.infer<typeof WpPostDraftSchema>;import { WpPostSchema } from '@/lib/types/schemas/post.schema';
export async function fetchPost(slug: string) {
const res = await fetch(`/wp-json/wp/v2/posts?slug=${slug}&_embed`);
const data = await res.json();
// Validation à la frontière : si l'API change, l'erreur est immédiate
const parsed = WpPostSchema.safeParse(data[0]);
if (!parsed.success) {
console.error('API contract mismatch:', parsed.error.format());
throw new Error('Les données reçues ne respectent pas le contrat.');
}
return parsed.data; // Typé WpPost, garanti valide
}2.3Stratégie 2 : Générer depuis la spec OpenAPI
Si ton backend expose une spec OpenAPI (c'est le cas de WP REST API avec le plugin Swagger), tu peux générer automatiquement tous tes types frontend depuis cette spec.
# Installer openapi-typescript
npm install -D openapi-typescript
# Générer depuis la spec de ton WordPress
npx openapi-typescript https://monwp.com/wp-json/ -o lib/types/wp-api.d.ts
# Ou depuis un fichier local
npx openapi-typescript openapi.json -o lib/types/wp-api.d.ts// Les types sont générés, tu ne touches plus rien à la main
import type { paths, components } from '@/lib/types/wp-api.d.ts';
// Extraire le type d'une réponse d'endpoint
type PostListResponse = paths['/wp/v2/posts']['get']['responses']['200']['content']['application/json'];
// Extraire un composant de schéma
type WpPost = components['schemas']['post'];2.4Stratégie 3 : Le prompt de synchronisation manuelle
Quand ton API change, utilise ce prompt pour mettre à jour tes types d'un coup :
Mes types TypeScript actuels :
[COLLE TES INTERFACES ACTUELLES]
La nouvelle réponse de l'API (après la mise à jour) :
[COLLE LE NOUVEAU JSON]
Fais-moi :
1. La liste précise des différences (champs ajoutés, supprimés, renommés, retypés)
2. Les interfaces TypeScript mises à jour
3. Les endroits où mes composants existants devront être mis à jour (si tu les connais)
Sois exhaustif et signale chaque changement de breaking change.La règle d'or du contrat
Un seul endroit pour la définition des types. Que tu utilises Zod, OpenAPI ou GraphQL codegen, tes types ne doivent jamais être dupliqués. Une modification → une seule source à toucher → tout le reste suit.