• 10 hours
  • Medium

Free online content available in this course.

course.header.alt.is_video

course.header.alt.is_certifying

Got it!

Last updated on 3/13/20

Modifiez les routes pour prendre en compte les fichiers

Log in or subscribe for free to enjoy all this course has to offer!

Pour que notre middleware de téléchargement de fichiers fonctionne sur nos routes, nous devrons les modifier, car le format d'une requête contenant un fichier du front-end est différent.

Modifiez la route POST

Tout d'abord, ajoutons notre middleware multer à notre route POST dans notre routeur stuff :

const express = require('express');
const router = express.Router();
const auth = require('../middleware/auth');
const multer = require('../middleware/multer-config');
const stuffCtrl = require('../controllers/stuff');
router.get('/', auth, stuffCtrl.getAllStuff);
router.post('/', auth, multer, stuffCtrl.createThing);
router.get('/:id', auth, stuffCtrl.getOneThing);
router.put('/:id', auth, stuffCtrl.modifyThing);
router.delete('/:id', auth, stuffCtrl.deleteThing);
module.exports = router;

Pour gérer correctement la nouvelle requête entrante, nous devons mettre à jour notre contrôleur :

exports.createThing = (req, res, next) => {
const thingObject = JSON.parse(req.body.thing);
delete thingObject._id;
const thing = new Thing({
...thingObject,
imageUrl: `${req.protocol}://${req.get('host')}/images/${req.file.filename}`
});
thing.save()
.then(() => res.status(201).json({ message: 'Objet enregistré !'}))
.catch(error => res.status(400).json({ error }));
};

Que fait le code ci-dessus ?

  • Pour ajouter un fichier à la requête, le front-end doit envoyer les données de la requête sous la forme form-data, et non sous forme de JSON. Le corps de la requête contient une chaîne thing , qui est simplement un objet Thing converti en chaîne. Nous devons donc l'analyser à l'aide de JSON.parse() pour obtenir un objet utilisable.

  • Nous devons également résoudre l'URL complète de notre image, car req.file.filename ne contient que le segment filename . Nous utilisons req.protocol pour obtenir le premier segment (dans notre cas 'http' ). Nous ajoutons '://' , puis utilisons req.get('host') pour résoudre l'hôte du serveur (ici, 'localhost:3000' ). Nous ajoutons finalement '/images/' et le nom de fichier pour compléter notre URL.

En fait, nous effectuons une demande GET vers http://localhost:3000/images/<image-name>.jpg. Cela semble simple, mais n'oubliez pas que notre application s'exécute sur localhost:3000 et nous ne lui avons pas indiqué comment répondre aux requêtes transmises à cette route : elle renvoie donc une erreur 404. Pour remédier à cela, nous devons indiquer à notre app.js comment traiter les requêtes vers la route /image , en rendant notre dossier images statique.

Il nous faudra une nouvelle importation dans app.js pour accéder au path de notre serveur :

const path = require('path');

De plus, nous ajoutons le gestionnaire de routage suivant juste au-dessus de nos routes actuelles :

app.use('/images', express.static(path.join(__dirname, 'images')));

Cela indique à Express qu'il faut gérer la ressource images de manière statique (un sous-répertoire de notre répertoire de base, __dirname ) à chaque fois qu'elle reçoit une requête vers la route /images . Enregistrez et actualisez l'application dans le navigateur ; désormais, tout devrait fonctionner correctement. Et maintenant, occupons-nous de la route PUT !

Modifiez la route PUT

La modification de notre route PUT est sensiblement plus compliquée, car nous devons prendre en compte deux possibilités : l'utilisateur a mis à jour l'image, ou pas. Dans le premier cas, nous recevrons l'élément form-data et le fichier. Dans le second cas, nous recevrons uniquement les données JSON.

Tout d'abord, ajoutons multer comme middleware à notre route PUT :

const express = require('express');
const router = express.Router();
const auth = require('../middleware/auth');
const multer = require('../middleware/multer-config');
const stuffCtrl = require('../controllers/stuff');
router.get('/', auth, stuffCtrl.getAllStuff);
router.post('/', auth, multer, stuffCtrl.createThing);
router.get('/:id', auth, stuffCtrl.getOneThing);
router.put('/:id', auth, multer, stuffCtrl.modifyThing);
router.delete('/:id', auth, stuffCtrl.deleteThing);
module.exports = router;

À présent, nous devons modifier notre fonction modifyThing() pour voir si nous avons reçu ou non un nouveau fichier, et répondre en conséquence :

exports.modifyThing = (req, res, next) => {
const thingObject = req.file ?
{
...JSON.parse(req.body.thing),
imageUrl: `${req.protocol}://${req.get('host')}/images/${req.file.filename}`
} : { ...req.body };
Thing.updateOne({ _id: req.params.id }, { ...thingObject, _id: req.params.id })
.then(() => res.status(200).json({ message: 'Objet modifié !'}))
.catch(error => res.status(400).json({ error }));
};

Dans cette version modifiée de la fonction, on crée un objet thingObject qui regarde si req.file existe ou non. S'il existe, on traite la nouvelle image ; s'il n'existe pas, on traite simplement l'objet entrant. On crée ensuite une instance Thing à partir de thingObject , puis on effectue la modification.

Félicitations ! Notre application gère correctement les téléchargements de fichiers lorsque nous mettons de nouveaux articles en vente et lorsque nous modifions les articles existants.

Example of certificate of achievement
Example of certificate of achievement