28-7 Ajout de l'action create au contrôleur de projets
Nous sommes en mesure de récupérer tous les projets ainsi qu'un seul. Il serait bien maintenant de pouvoir en ajouter de nouveaux.
Pour cela, toujours selon la convention Nest, il est suggéré d'utiliser une fonction create() répondant e à la méthode HTTP POST.
| Verbe | Chemin | Action du contrôleur |
|---|---|---|
| GET | /projets | findAll() |
| POST | /projets | create() |
| GET | /projets/:id | findOne() |
| PUT/PATCH | /projets/:id | update() |
| DELETE | /projets/:id | remove() |
En entrée, il nous faudra un Projet, mais nous avons un dilemme: pas tous les attributs sont nécessaires afin de créer un nouveau projet. En fait, certains attributs n'auraient pas de sens à recevoir en entrée: id, date_creation et date_modification, par exemple. En effet, on ne crée pas un projet en connaissant à l'avance son id, c'est une valeur retournée par le serveur.
Il nous faut une façon de représenter l'objet tel qu'il sera reçu et attendu pour sa création. Cela permettra aussi de personnaliser les validations.
Cette représentation s'appelle un DTO (Data Transfer Object). Il s'agit d'une classe qui représente un objet dans un état de transfert de données (pour la création ou la modification, par exemple). C'est un objet utilisé seulement pour représenter l'état des données au moment du transfert entre le client et le serveur.
C'est similaire aux objets de requêtes créés dans Angular.
Créer un DTO CreateProjetDto
Les DTO, tout comme les modèles ou les entités, sont des classes simples que l'on place dans le dossier du module concerné.
-
Créez le dossier
dtosousprojets:src/projets/dto -
Sous ce nouveau dossier, ajoutez un fichier
TypeScriptcreate-projet.dto.ts -
À l'intérieur de ce nouveau fichier, créez la classe
CreateProjetDtoavec les attributs pour la créationsrc/projets/dto/create-projet.dto.tsexport class CreateProjetDto {
nom: string;
description: string;
image_url?: string;
}infoIl est tout de même possible de spécifier des attributs optionnels, comme
image_urldans notre cas.
Ajouter la fonction creer() au service ProjetsService
Le service est ultimement responsable de gérer la coordination d'ajout de projet. Pour ce faire, on créera une fonction creer acceptant en paramètre un DTO CreateProjetDto.
Comme nous n'avons pas de base de données encore, on créera le tout de façon manuelle en ajoutant le projet au tableau.
-
Ajoutez une fonction
creerau serviceProjetsServicesrc/projets/projets.service.ts//...
creer(createProjetDto: CreateProjetDto) {
}
//... -
Trouvons l'id le plus élevé dans la liste à l'aide de la fonction
reduceafin de créer automatiquement un nouvelidpour le nouveau projet.src/projets/projets.service.tscreer(createProjetDto: CreateProjetDto) {
const maxId = this.projets.reduce((max, projet) => {
return Math.max(max, projet.id);
}, 0);
}infoLa fonction reduce exécute la fonction passée en paramètre pour chaque item de la liste
projetet met le retour dans une variable (maxici) réutilisée à chaque itération.Pour chaque projet existant dans la liste, on vérifie si son identifiant est plus élevé que celui déjà contenu dans la variable
maxet si oui, on retourne l'id. Il sera ainsi associé à la variablemaxet passé à la prochaine itération. -
Créer le projet reçu en lui assignant un
idet une date decreation/modification.src/projets/projets.service.tscreer(createProjetDto: CreateProjetDto) {
const maxId = this.projets.reduce((max, projet) => {
return Math.max(max, projet.id);
}, 0);
const projet: Projet = {
id: maxId + 1,
nom: createProjetDto.nom,
description: createProjetDto.description,
date_creation: new Date().toJSON(),
date_modification: new Date().toJSON(),
};
//highlight-next
} -
Ajouter le nouveau projet à la liste en mémoire et le retourner
src/projets/projets.service.tscreer(createProjetDto: CreateProjetDto) {
const maxId = this.projets.reduce((max, projet) => {
return Math.max(max, projet.id);
}, 0);
const projet: Projet = {
id: maxId + 1,
nom: createProjetDto.nom,
description: createProjetDto.description,
date_creation: new Date().toJSON(),
date_modification: new Date().toJSON(),
};
this.projets.push(projet);
return projet;
}
Ajouter l'action create au contrôleur ProjetsController
Il est maintenant temps d'ajouter la fonction create() au contrôleur répondant à la méthode HTTP POST.
-
Ajouter la fonction
createavec le décorateur@Postsrc/projets/projets.controller.ts@Post()
create() {
} -
Récupérer le
bodyde la requête via le décorateur de paramètre@Body()src/projets/projets.controller.ts@Post()
create(@Body() createProjetDto: CreateProjetDto) {
}infoLe décorateur
Bodypermet de récupérer le body de la requête et de l'assigner à un paramètre de la fonction. Il est possible de préciser à quel type d'objet devrait correspondre la requête, soitCreateProjetDtodans notre cas. -
Appeler le service via sa fonction
creerpour créer le projet et le retournersrc/projets/projets.controller.ts@Post()
create(@Body() createProjetDto: CreateProjetDto) {
return this.projetsService.creer(createProjetDto);
}
En résumé:
- Le contrôleur utilise le décorateur
@Post()pour préciser que la fonctioncreatesera responsable des méthodes HTTP POST. - Dans la signature de la fonction, on récupère le
bodyde la requête, qui est au fond le JSON reçu et on l'assigne à la variable createProjetDto de type CreateProjetDto. - Le projet est retourné
Test Postman
Testez via Postman à l'aide d'une requête:
- Type:
POST - URL:
http://localhost:3000/projets - Body:
raw/JSONcontenant{
"nom": "Un nouveau projet",
"description": "Comme si je n'en n'avais pas déjà assez."
}
Vous devriez recevoir comme un résultat semblable à ceci:
{
"id": 3,
"nom": "Un nouveau projet",
"description": "Comme si je n'en n'avais pas déjà assez.",
"date_creation": "2024-10-11T14:09:54.368Z",
"date_modification": "2024-10-11T14:09:54.368Z"
}