LILINE’S LAB

Projet : Simple Blog From Scratch Part5

par | Mar 13, 2024 | Développement, Express, NodeJS, Projets, Simple Blog From Scratch

La semaine dernière nous avons vu comment ajouter une image dans une dossier du serveur web et créer une url vers cette image en base de données.

Controller

Le controller post va contenir les fonctions relatives aux traitements des futurs posts du blog.

JavaScript
const db = require("../models"); 
const { Op } = require("sequelize"); 
const auth = require("../middleware/auth")
const cxss = require("c-xss");
const messages = require('../messages');

// CREER UN POST
exports.createPost = async (req, res, next) => {
    try {
    // on vérifie l'identité de l'utilisateur connecté  
        const userId = auth.getUserID(req);
        const user = await db.User.findOne({ where: { id: userId } });
        // si le post ne comporte pas de titre ou de contenu on affiche un message d'erreur
        if(!req.body.title || !req.body.content){
            res.status(403).json({ message: messages.POST_ADDMISSINGTITLEORCONTENT });
        // sinon on créé le post en BDD
        } else {
            const myPost = await db.Post.create({
                // on utilise cxss pour éviter les attaques xss
                title: cxss(req.body.title),
                content: cxss(req.body.content),
                createdBy: user.username,
                UserId: userId,
            }); 
            // une fois le post enregistré en base on renvoi la réponse 
            res.status(200).json({ post: myPost, message: messages.POST_ADDOK });
        }
    } catch (error) {
        return res.status(500).json({ error: messages.SERVEUR_ERROR });
    }
};

// MODIFIER UN POST
exports.modifyPost = async (req, res, next) => {
    try {
        // on cherche le post à modifier grâce à son ID afin de pouvoir le modifier
        const thisPost = await db.Post.findOne({ where: { id: req.params.id } });
            if (req.body.title) {
                thisPost.title = cxss(req.body.title);
            }
            if (req.body.content) {
                thisPost.content = cxss(req.body.content);
            }
            // puis l'on renvoie en base 
            const newPost = await thisPost.save({
                fields: ["title", "content"],
            });
            res.status(200).json({ newPost: newPost, message: messages.POST_MODIFIED });
    } catch (error) {
        return res.status(500).json({ error: messages.SERVEUR_ERROR });
    }
};

// ARCHIVER UN POST -> Permet d'archiver un post en BDD afin de ne plus l'afficher sur le Front
exports.archivePost = async (req, res, next) => {
    try {
        // on recherche le post à archiver 
        const thisPost = await db.Post.findOne({ where: { id: req.params.id } });
            // et l'on passe l'archivage de false à true
            if(thisPost.isArchived === false) {
                thisPost.isArchived = true;
                const newPost = await thisPost.save({ 
                    fields: ["isArchived"],
                });
                res.status(200).json({ newPost: newPost, message: messages.POST_ARCHIVED });
            }
    } catch (error) {
        return res.status(500).json({ error: messages.SERVEUR_ERROR });
    }
};

// AFFICHER UN POST
exports.getOnePost = async (req, res, next) => {
    try {
        // on récupère le post afin d'afficher son titre et son contenu ainsi que son auteur et l'on vérifie aussi qu'il n'est pas archivé
        const post = await db.Post.findOne({ 
            attributes: ["id", "title", "content"], 
            where: { [Op.and]: [{id: req.params.id}, { is_archived: 0 }] },
            include: [
                {model: db.User, attributes: ["username"]},
            ],
        }); 
        if (post){
            res.status(200).json(post);
        } else {
            res.status(200).json({ message: messages.POST_NOPOST });
        }
    } catch (error) {
        return res.status(500).json({ error: messages.SERVEUR_ERROR });
    }
};

// AFFICHER TOUS LES POSTS
exports.getAllPosts = async (req, res, next) => {
    try {
        // on affiche uniquement les posts non archivés
        const allPosts = await db.Post.findAll({
            limit: 50, order: [["id", "DESC"]], 
            where: { is_archived: 0 },
            include: [
                {model: db.User, attributes: ["username"]},
            ],
        })
        res.status(200).json({ allPosts });
    } catch {
        return res.status(500).json({ error: messages.SERVEUR_ERROR });
    }
};

Routes

Cinq routes sont utilisées pour gérer les posts dans le futur blog.
Comme pour la gestion des images le middlware auth sera également utilisé ici.

JavaScript
const express = require('express');
const router = express.Router();
const postCtrl = require("../controllers/post");
const auth = require('../middleware/auth');

// créer un post
router.post("/create", auth.signin, postCtrl.createPost);
// modifier un post
router.put("/modify/:id", auth.signin, postCtrl.modifyPost);
// archiver un post
router.put("/archive/:id", auth.signin, postCtrl.archivePost);
// afficher tous les posts
router.get("/all", postCtrl.getAllPosts);
// afficher un seul post
router.get("/:id", postCtrl.getOnePost);


module.exports = router;

Le BackEnd du blog simple est maintenant terminé.
Il nous restera encore à tester les routes avant d’attaquer le FrontEnd !

Retrouvez les premiers articles du projet ici ⬇️

Simple Blog From Scratch Part1
Simple Blog From Scratch Part2
Simple Blog From Scratch Part3
Simple Blog From Scratch Part4


logo du site

   


Consultante spécialisée dans les technologies Microsoft, je justifie de plus de 14 ans d’expérience dans le secteur IT.
Mon parcours professionnel, riche et varié, m’a permis de développer de solides compétences, tant techniques qu’humaines. Je suis reconnue pour ma capacité à analyser rapidement les enjeux techniques et à concevoir des solutions pertinentes, y compris sur des problématiques complexes.
Mon approche proactive, alliée à mes compétences en développement, me permet de proposer des évolutions efficaces, toujours en cohérence avec les objectifs métiers.
En parallèle de mon activité professionnelle, je prends plaisir à approfondir mes compétences techniques en réalisant des projets personnels. Je développe notamment des jeux web basés sur React et PHP, ainsi que des applications orientées métier avec SPFx.