Comment gérer les téléversements de fichiers Node.js avec Fastify
Amarachi Aso
8 décembre 2022
0 minutes de lectureLe téléversement de fichiers est une fonctionnalité courante dans les applications web. C’est pourquoi de nombreux frameworks web permettent aux applications côté serveur d’accepter des fichiers et de les traiter. C’est également le cas de Fastify, un framework web Node.js souvent considéré comme le successeur d’Express. Rapide et axé sur une expérience développeur optimale, il offre une architecture de plugins puissante et une surcharge minimale.
Dans ce tutoriel, vous allez utiliser le framework Fastify dans une application Node.js pour configurer le téléversement de fichiers. Vous découvrirez le fonctionnement des téléversements de fichiers sur un serveur classique et comment les gérer dans une application serveur Fastify.
Les bases du téléversement de fichiers
Pour téléverser des fichiers vers un serveur d’application, un ordinateur client doit envoyer une requête POST au serveur. Le corps de la requête contient des données généralement envoyées au moyen de formulaires HTML. Les formulaires HTML proposent trois méthodes d’encodage des données :
application/x-www-form-urlencoded(par défaut) est le type de contenu ou l’encodage utilisé par défaut pour les formulaires HTML. Toutefois, lorsque des fichiers sont envoyés avec ce formulaire, ils doivent être encodés à l’aide de la méthodemultipart/form-data.multipart/form-datasert à représenter les différentes parties ou champs d’un formulaire HTML. Ces parties sont envoyées dans le corps de la requête sous forme de paires nom/valeur. Le nom et la valeur correspondent respectivement au nom et à la valeur des champs de saisie.text/plainsert à envoyer des données sous forme de texte brut non mis en forme et ne permet pas d’envoyer des fichiers.
Lorsque des fichiers sont envoyés à un serveur d’application, celui-ci doit généralement les traiter, les enregistrer, ou les deux. Les applications serveur peuvent traiter et enregistrer les fichiers téléversés de différentes manières, notamment :
Les enregistrer dans le système de fichiers de votre serveur. Vous pouvez les placer dans un répertoire dédié sur le serveur qui héberge votre application ou sur un autre serveur réservé au stockage des fichiers.
Les stocker dans une base de données.
Les téléverser vers un service de stockage cloud comme Amazon S3 ou Cloudinary.
Ce tutoriel porte sur la première méthode de gestion des téléversements de fichiers.
Mettre en place le téléversement de fichiers avec Fastify
Avant de commencer ce tutoriel, vous aurez besoin des éléments suivants :
Node.js installé
Un éditeur de code de votre choix, comme Visual Studio Code (VS Code)
Postman : vous pouvez vous connecter et utiliser l’application web, ou l’installer sur votre ordinateur.
Dans les sections suivantes, vous allez créer un projet Fastify, configurer un plugin de téléversement de fichiers, créer une route /upload capable de gérer plusieurs fichiers et écrire un test pour cette route.
Créer un projet et configurer Fastify
Pour commencer, vous devez créer un projet et configurer Fastify. Accédez au répertoire dans lequel vous souhaitez créer ce projet, puis créez un dossier nommé fastify-file-upload. Dans votre terminal, exécutez la commande suivante :
Placez-vous dans ce dossier :
Ouvrez ensuite le dossier dans l’éditeur de code de votre choix. Si vous utilisez VS Code, vous pouvez exécuter la commande suivante :
Initialisez votre projet et créez un fichier package.json en exécutant la commande suivante :
Installez ensuite les dépendances que vous allez utiliser dans ce projet :
Créez également deux fichiers : app.js et server.js :
Le fichier app.js contiendra le code de votre application. Copiez-collez le code suivant dans ce fichier :
import Fastify from fastify
Ce code importe le framework Fastify et en crée une instance d’application. Ajoutez ensuite le code suivant dans votre fichier server.js :
Ce code sert votre application lorsqu’elle est exécutée ou renvoie une erreur si un problème survient lors de sa mise en service.
Dans ce projet, vous allez utiliser la syntaxe des modules ES6. Vos fichiers JavaScript doivent donc être chargés en tant que modules. Pour cela, ajoutez la propriété type à votre fichier package.json et définissez sa valeur sur module :
Configurer un plugin de téléversement de fichiers
Fastify-multipart permet de gérer les types de contenu multipart dans Fastify. Vous avez déjà installé le plugin avec les dépendances ; il est donc temps de le configurer. Pour cela, importez multipart depuis '@fastify/multipart', puis enregistrez-le.
Ajoutez les lignes commençant par + au contenu de votre fichier app.js :
Vous avez ici enregistré multipart dans l’application Fastify créée précédemment. Votre instance d’application peut maintenant analyser facilement les types de contenu multipart.
Téléversements de fichiers
Il existe plusieurs façons d’accéder aux fichiers d’une requête POST. Par exemple, si vous savez qu’une requête ne contient qu’un seul fichier, vous pouvez y accéder avec le code suivant :
Dans ce code, request est le paramètre de requête de la fonction de traitement de votre route de téléversement. Votre fonction de traitement ressemble à ceci :
Si vous prévoyez de recevoir plusieurs fichiers, appelez la méthode files() au lieu de file(), comme ceci :
Dans votre fichier app.js, vous devez écrire le code qui permet de gérer entièrement le téléversement de plusieurs fichiers. Mais vous devez d’abord créer un répertoire où seront stockés les fichiers téléversés par votre application. Créez ce répertoire à la racine de votre projet et nommez-le uploads :
Modifiez ensuite le fichier app.js comme suit :
Dans le code modifié, vous avez importé des fonctions des modules Node.js natifs fs, util et stream. Vous avez ensuite créé une route /upload et sa fonction de traitement.
Dans la fonction de traitement, vous avez utilisé req.files() pour accéder à tous les fichiers de la requête. Vous avez parcouru les fichiers et, pour chacun, le code await pump(part.file, fs.createWriteStream(`./uploads/${part.filename}`)) effectue le téléversement et enregistre le fichier dans le répertoire uploads créé précédemment.
Notez que les fichiers téléversés ne sont pas accumulés en mémoire avant leur enregistrement. La fonction fs.createWriteStream crée plutôt un flux de réception, vers lequel est dirigé le flux du fichier provenant de part.file. Ainsi, le contenu du fichier n’est pas d’abord mis en mémoire tampon : les blocs de données sont directement écrits dans le fichier au fur et à mesure de leur arrivée dans le flux. Cette méthode est particulièrement utile pour les fichiers volumineux. Elle ne bloque pas la boucle d’événements et permet également de gérer les fichiers de manière économe en mémoire dans votre application.
Vous pouvez maintenant lancer votre serveur et lui envoyer des fichiers avec Postman. Dans votre fichier package.json, remplacez le script de démarrage par le suivant :
Démarrez ensuite le serveur avec la commande suivante :
Dans Postman, envoyez une requête POST à http://localhost:8000/upload. Dans le corps de la requête, sélectionnez l’option form-data, puis téléversez deux fichiers de votre choix :

Ici, vous téléversez un fichier nommé article.txt et un autre nommé cover.jpg (leurs clés seront respectivement « article » et « coverImage »). Une fois les fichiers téléversés, vous devriez obtenir le code d’état 200 et l’objet de réponse {message : 'files uploaded' } :

Vous devriez également voir les fichiers ajoutés au répertoire « upload » créé précédemment pour les téléversements.
Vous avez maintenant géré avec succès le téléversement de plusieurs fichiers à l’aide du plugin fastify/multipart. La plupart des formulaires nécessitent l’envoi non seulement de fichiers, mais aussi de fichiers et d’autres champs textuels. Pour gérer ce type de formulaire, vous devez modifier le code existant afin de traiter à la fois les flux de fichiers et les autres champs.
Pour ce faire, modifiez votre fichier app.js comme suit :
Remarquez que cette fois, vous utilisez req.parts() pour accéder à la fois aux flux de fichiers et aux champs, plutôt que req.files(). Dans le corps de la boucle, une instruction if permet de déterminer quelle partie correspond à un fichier et de la traiter différemment des champs.
Vous pouvez maintenant envoyer une autre requête. Enregistrez votre fichier, puis arrêtez et redémarrez votre serveur avec npm start. Retournez dans Postman, supprimez les paires clé/valeur de la requête précédente et créez-en de nouvelles. Dans le premier champ, indiquez votre nom complet, puis ajoutez deux fichiers (comme précédemment).
Remarque : si vous comptez réutiliser les mêmes fichiers, pensez à supprimer ceux qui ont été téléversés précédemment dans votre répertoire uploads.
Votre requête devrait ressembler à ceci :

Si c’est le cas, votre application peut maintenant gérer plusieurs flux de fichiers et champs.
Écrire des tests
Pour protéger votre implémentation du téléversement de fichiers, vous devez la tester. Mais comment écrire des tests pour le téléversement de fichiers dans Fastify ? Vous allez utiliser le framework de test tap, le package form-auto-content et la méthode .inject de Fastify pour écrire vos tests.
Créez le fichier app.test.js à la racine de votre projet. Copiez-collez ensuite le code suivant dans ce fichier :
Remplacez les chemins ./sample_files/file.txt et ./sample_files/cover.jpg par les chemins vers deux fichiers de votre système de fichiers. Vous pouvez aussi en télécharger une copie ici.
La méthode .inject de Fastify permet d’injecter de fausses requêtes HTTP dans votre application sans exécuter votre code sur un véritable serveur. Dans le code précédent, vous avez utilisé formAutoContent pour créer un formulaire nommé myForm, puis l’avez utilisé comme corps de la requête POST simulée dans votre test. Vous n’avez qu’un seul test, qui vérifie que lorsque le formulaire envoyé contient plusieurs fichiers, l’application renvoie un statusCode de 200.
Exécutez ce test et vérifiez qu’il réussit. Dans votre fichier package.json, remplacez le script de test par celui-ci :
Exécutez ensuite la commande suivante :
Votre test devrait réussir et afficher un résultat semblable à celui-ci :

Tout le code de ce tutoriel est disponible dans ce dépôt GitHub.
Conclusion
Dans cet article, vous avez découvert les bases du téléversement de fichiers et pourquoi les formulaires contenant des fichiers sont encodés uniquement avec le multipart/form-data content-type. Vous avez également découvert deux façons pour les applications serveur de traiter et d’enregistrer les fichiers : dans un répertoire dédié sur le même serveur ou dans un service de stockage cloud comme Amazon S3. Enfin, vous avez appris à gérer les téléversements dans Fastify, un framework web rapide et léger pour Node.js.
Pour en savoir plus, consultez la documentation du plugin Fastify-multipart ainsi que le guide de Fastify sur les tests.



