Passer au contenu

Validation

Il est de bonne pratique de valider la justesse des données envoyées à une application web. Pour valider automatiquement les requêtes entrantes, Nest fournit plusieurs pipes disponibles par défaut :

  • ValidationPipe
  • ParseIntPipe
  • ParseBoolPipe
  • ParseArrayPipe
  • ParseUUIDPipe

Le ValidationPipe utilise le puissant class-validator et ses décorateurs de validation déclaratifs. Le ValidationPipe offre une approche pratique pour faire respecter les règles de validation pour toutes les charges utiles client entrantes, où les règles spécifiques sont déclarées avec des annotations simples dans les déclarations locales de classe/DTO dans chaque module.

Vue d’ensemble

Dans le chapitre Pipes, nous avons passé en revue le processus de création de pipes simples et de leur liaison aux contrôleurs, méthodes ou à l’application globale pour démontrer comment fonctionne le processus. Assurez-vous de revoir ce chapitre pour bien comprendre les sujets de ce chapitre. Ici, nous nous concentrerons sur divers cas d’utilisation réels du ValidationPipe, et montrerons comment utiliser certaines de ses fonctionnalités de personnalisation avancées.

Utilisation du ValidationPipe intégré

Pour commencer à l’utiliser, nous installons d’abord la dépendance requise.

Fenêtre de terminal
$ npm i --save class-validator class-transformer

Parce que ce pipe utilise les bibliothèques class-validator et class-transformer, il y a de nombreuses options disponibles. Vous configurez ces paramètres via un objet de configuration passé au pipe. Voici les options intégrées :

export interface ValidationPipeOptions extends ValidatorOptions {
transform?: boolean;
disableErrorMessages?: boolean;
exceptionFactory?: (errors: ValidationError[]) => any;
}

En plus de celles-ci, toutes les options class-validator (héritées de l’interface ValidatorOptions) sont disponibles :

OptionTypeDescription
enableDebugMessagesbooleanS’il est défini sur true, le validateur imprimera des messages d’avertissement supplémentaires dans la console lorsque quelque chose ne va pas.
skipUndefinedPropertiesbooleanS’il est défini sur true, le validateur ignorera la validation de toutes les propriétés qui sont indéfinies dans l’objet de validation.
skipNullPropertiesbooleanS’il est défini sur true, le validateur ignorera la validation de toutes les propriétés qui sont nulles dans l’objet de validation.
skipMissingPropertiesbooleanS’il est défini sur true, le validateur ignorera la validation de toutes les propriétés qui sont nulles ou indéfinies dans l’objet de validation.
whitelistbooleanS’il est défini sur true, le validateur retirera l’objet validé (retourné) de toute propriété qui n’utilise pas de décorateurs de validation.
forbidNonWhitelistedbooleanS’il est défini sur true, au lieu de retirer les propriétés non figurant sur la liste blanche, le validateur lancera une exception.
forbidUnknownValuesbooleanS’il est défini sur true, les tentatives de validation d’objets inconnus échoueront immédiatement.
disableErrorMessagesbooleanS’il est défini sur true, les erreurs de validation ne seront pas retournées au client.
errorHttpStatusCodenumberCe paramètre vous permet de spécifier quel type d’exception sera utilisé en cas d’erreur. Par défaut, il lance BadRequestException.
exceptionFactoryFunctionPrend un tableau des erreurs de validation et retourne un objet d’exception à lancer.
groupsstring[]Groupes à utiliser lors de la validation de l’objet.
alwaysbooleanDéfinit le défaut pour l’option always des décorateurs. Le défaut peut être remplacé dans les options de décorateur.
strictGroupsbooleanSi groups n’est pas donné ou est vide, ignore les décorateurs avec au moins un groupe.
dismissDefaultMessagesbooleanS’il est défini sur true, la validation n’utilisera pas de messages par défaut. Le message d’erreur sera toujours undefined s’il n’est pas explicitement défini.
validationError.targetbooleanIndique si la cible doit être exposée dans ValidationError.
validationError.valuebooleanIndique si la valeur validée doit être exposée dans ValidationError.
stopAtFirstErrorbooleanLorsqu’il est défini sur true, la validation de la propriété donnée s’arrêtera après la première erreur. Par défaut, c’est false.

Auto-validation

Nous commencerons par lier le ValidationPipe au niveau de l’application, assurant ainsi que tous les points de terminaison sont protégés contre la réception de données incorrectes.

async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalPipes(new ValidationPipe());
await app.listen(3000);
}
bootstrap();

Pour tester notre pipe, créons un point de terminaison de base.

@Post()
create(@Body() createUserDto: CreateUserDto) {
return 'Cette action ajoute un nouvel utilisateur';
}

Nous pouvons maintenant ajouter quelques règles de validation dans notre CreateUserDto. Nous faisons cela en utilisant des décorateurs fournis par le package class-validator, décrits en détail ici. De cette façon, toute route utilisant le CreateUserDto appliquera automatiquement ces règles de validation.

import { IsEmail, IsNotEmpty } from 'class-validator';
export class CreateUserDto {
@IsEmail()
email: string;
@IsNotEmpty()
password: string;
}

Avec ces règles en place, si une requête atteint notre point de terminaison avec une propriété email non valide dans le corps de la requête, l’application répondra automatiquement avec un code 400 Bad Request, ainsi que le corps de réponse suivant :

{
"statusCode": 400,
"error": "Bad Request",
"message": ["email must be an email"]
}

En plus de valider les corps de requête, le ValidationPipe peut être utilisé avec d’autres propriétés d’objet de requête aussi. Imaginez que nous aimerions accepter :id dans le chemin du point de terminaison. Pour s’assurer que seuls les nombres sont acceptés pour ce paramètre de requête, nous pouvons utiliser le code suivant :

@Get(':id')
findOne(@Param() params: FindOneParams) {
return 'Cette action retourne un utilisateur';
}

Le FindOneParams, tout comme un DTO, est simplement une classe qui définit des règles de validation à l’aide de class-validator. Cela ressemblerait à ceci :

import { IsNumberString } from 'class-validator';
export class FindOneParams {
@IsNumberString()
id: number;
}

Désactiver les erreurs détaillées

Les messages d’erreur peuvent être utiles pour expliquer ce qui était incorrect dans une requête. Cependant, certains environnements de production préfèrent désactiver les erreurs détaillées. Faites-le en passant un objet d’options au ValidationPipe :

app.useGlobalPipes(
new ValidationPipe({
disableErrorMessages: true,
}),
);

En conséquence, les messages d’erreur détaillés ne seront pas affichés dans le corps de réponse.

Filtrage des propriétés

Notre ValidationPipe peut également filtrer les propriétés qui ne doivent pas être reçues par le gestionnaire de méthode. Dans ce cas, nous pouvons whitelister les propriétés acceptables, et toute propriété non incluse dans la liste blanche est automatiquement supprimée de l’objet résultant. Par exemple, si notre gestionnaire attend des propriétés email et password, mais qu’une requête inclut également une propriété age, cette propriété peut être automatiquement supprimée du DTO résultant. Pour activer un tel comportement, définissez whitelist sur true.

app.useGlobalPipes(
new ValidationPipe({
whitelist: true,
}),
);

Lorsqu’il est défini sur true, cela supprimera automatiquement les propriétés non figurant sur la liste blanche (celles sans décorateur dans la classe de validation).

Alternativement, vous pouvez empêcher la requête de se traiter lorsque des propriétés non figurant sur la liste blanche sont présentes et retourner une réponse d’erreur à l’utilisateur. Pour activer cela, définissez la propriété d’option forbidNonWhitelisted sur true, en combinaison avec la définition de whitelist sur true.