Aller au contenu principal

My Class Validator

Pourquoi choisir entre la Performance (JSON Schema) et la Lisibilité (Decorators) ? my-class-validator réunit le meilleur des deux mondes.

🚀 Le concept

Contrairement à class-validator qui utilise la réflexion (reflection) à chaque requête (lent), cette librairie transforme vos classes TypeScript en JSON Schema standard au démarrage de l'application.

Ce schéma est ensuite compilé par AJV (Fastify) pour une validation ultra-rapide (JIT).

📦 Installation

Vous avez besoin du package et de reflect-metadata.

npm install my-class-validator reflect-metadata

⚡️ Utilisation Recommandée

La bonne pratique consiste à définir la classe et à exporter son schéma dans le même fichier.

1. Définir et Exporter le DTO (create-user.dto.ts)

Vous définissez vos décorateurs, puis vous appelez generateSchema à la fin du fichier.

import { IsString, IsInt, IsRequired, generateSchema } from 'my-class-validator';

export class CreateUserDto {
@IsString({ message: "Le nom doit être une chaîne de caractères" })
@IsRequired()
username: string;

@IsInt()
@IsRequired()
age: number;
}

// ✅ On exporte le Schéma directement ici
export const CreateUserSchema = generateSchema(CreateUserDto);

2. Utiliser avec my-fastify-decorators

Si vous utilisez my-fastify-decorators, l'intégration se fait via le décorateur @BodySchema. Il suffit d'importer le schéma généré précédemment.

import { Controller, Post, Body, BodySchema } from 'my-fastify-decorators';
// On importe la Classe (pour le typage) ET le Schéma (pour la validation)
import { CreateUserDto, CreateUserSchema } from './dto/create-user.dto';

@Controller('/users')
export class UserController {

@Post()
@BodySchema(CreateUserSchema) // <--- On passe le schéma pré-généré
create(@Body() body: CreateUserDto) {
// Ici, body est typé ET validé
return { status: 'ok', user: body.username };
}
}

3. Résultat généré

Voici ce que CreateUserSchema contient réellement (et ce que Fastify reçoit) :

{
type: 'object',
required: ['username', 'age'],
properties: {
username: {
type: 'string',
errorMessage: { type: 'Le nom doit être une chaîne de caractères' }
},
age: { type: 'integer' }
}
}