SNS서비스 Project 4 (최종)

게시글(이미지), 팔로우 기능

Posted by ETHAN KIM on November 10, 2021 · 9 mins read
Node.js

1. 게시글, 이미지업로드 라우터

multer 패키지를 통해 각 파일 및 게시글 데이터를 받는다.

  1. 이미지파일 업로드 시 서버에 파일 저장 후 주소 즉시반환하여 이미지 출력
  2. 게시글 업로드 시 이미지 주소와 함께 DB저장
routes/post.js
const express = require('express');
const multer = require('multer');
const path = require('path');
const fs = require('fs');

const { Post ,Hashtag } = require('../models');
const { isLoggedIn } = require('./middlewares');

const router = express.Router();

try { 
    fs.readdirSync('uploads');
}catch (error){
    console.error('uploads 폴더가 없어 uploads 폴더를 생성합니다.');
    fs.mkdirSync('uploads');
}

const upload = multer({
    storage: multer.diskStorage({
        destination(req,file,cb) {
            cb(null, 'uploads/');
        },
        filename(req,file,cb) {
            const ext = path.extname(file.originalname);
            cb(null, path.basename(file.originalname, ext) + Date.now() + ext);
        },
    }),
    limits : { fileSize:5 * 1024 * 1024 },
});

router.post('/img', isLoggedIn, upload.single('img'), (req,res) => {
    console.log(req.file);
    res.json({ url: `/img/${req.file.filename}`});
});

const upload2 = multer();
router.post('/', isLoggedIn, upload2.none(), async (req,res, next) => {
    try{
        const post = await Post.create({
            content: req.body.content,
            img: req.body.url,
            UserId: req.user.id,
        });
        const hashtags = req.body.content.match(/#[^\s#]+/g);
        if(hashtags){
            const result = await Promise.all(
                hashtags.map(tag => {
                    return Hashtag.findOrCreate({
                        where: { title: tag.slice(1).toLowerCase() },
                    });
                }),
            );
            await post.addHashtags(result.map(r => r[0]));
        }
        res.redirect('/');
    }catch(error){
        console.error(error);
        next(error);
    }
});

module.exports = router;


2. 팔로우 기능

팔로우 요청 라우터를 통해 관계 테이블인 Follow 테이블에 데이터 추가

routes/middlewares.js
const express = require('express');

const  { isLoggedIn } = require('./middlewares');
const User = require('../models/user');

const router = express.Router();

router.post('/:id/follow', isLoggedIn, async (req,res,next) => {
    try {
        const user = await User.findOne({ where: { id: req.user.id } });
        if(user){
            await user.addFollowing(parseInt(req.params.id, 10));
            res.send('success');
        }else {
            res.status(404).send('no user');
        }
    } catch (error) {
        console.error(error);
        next(error);
    }
});

module.exports = router;


3. 해시태그 검색라우터

해시태그로 조회 시 user 정보와 함께 posts in hashtag 조회

routes.page.js
const express = require('express');
const { isLoggedIn, isNotLoggedIn } = require('./middlewares');
const { Post , User , Hashtag } = require('../models');
const { hash } = require('bcrypt');

const router = express.Router();

router.use((req, res, next)=>{
    res.locals.user = req.user;
    res.locals.followerCount = req.user ? req.user.Followers.length : 0;
    res.locals.followingCount = req.user ? req.user.Followings.length : 0;
    res.locals.followerIdList = req.user ? req.user.Followings.map(f => f.id) : [];
    next();
});

...

router.get('/hashtag', async(req,res,next) => {
    const query = req.query.hashtag;
    if(!query) {
        return res.redirect('/');
    }
    try{
        const hashtag = await Hashtag.findOne({ where: { title: query }});
        let posts = [];
        if(hashtag){
            posts = await hashtag.getPosts({ include: [{ model: User }] });
        }

        return res.render('main', {
            title: `${query} | NodeBird`,
            twits: posts,
        });
    }catch(erorr){
        console.error(error);
        return next(error);
    }
});

module.exports = router;


4. 프로젝트 마무리

팔로우, 업로드, 검색기능 테스트