sequelize association, s3 multer

김가영·2020년 11월 15일
0

Node.js

목록 보기
19/34

https://velog.io/@cadenzah/sequelize-document-4#nm-%EA%B4%80%EA%B3%84


프로젝트 계층 분리

Router - controller - model - service

  1. model : 모델의 스키마 정의 및 데이터 access
  2. service : 데이터 로직을 핸들링 및 가공, 비즈니스 로직 작성
  3. router : 특정 엔드포인트에 대한 클라이언트 요청에 에플리케이션이 응답하는 방법을 결정
  4. controller : 요청을 받고 service계층에서 받은 데이터를 응답

controller

  • controller/userController.js
module.exports = {
	signup : async (req, res) => {}
}

함수의 형태로 export 해주고,

  • router/index.js
const userController = require('../../controller/userController');
router.post('/signup', userController.signup);

로 이용한다.

Sequelize association

association

  • belongsTo를 사용하는 model에 외래키가 생성
  • belongsTo(--tableName--, options);

    options

    onDelete : 'cascade'  / onModify : 'cascade'

    참조된 relation에서 매칭된 속성의 수정이나 삭제가 외래키에 반영됨

1 : 1 → hasOne, belongsTo

1 : N → hasMany, belongsTo

  • 외래키 이름을 지정해주지 않으면 기본적으로 hasMany를 사용하는 테이블 이름 + Id
db.User = require('./user')(sequelize, Sequelize);
db.Post = require('./post')(sequelize, Sequelize);

db.User.hasMany(db.Post, {onDelete : 'cascade'});
db.Post.belongsTo(db.User);

M : N → belongsToMany

as : model 이름을 바꿔준다.
through : 어떤 테이블을 매개하여 연결할 지.

  • models/like.js
const {User, Post} = require('./index');

module.exports = (sequelize, DataTypes) => {
    return sequelize.define('Like', {
        UserId : {
            type : DataTypes.INTEGER,
            reference : {
                model : User,
                key : 'id',
            }
        },
        PostId : {
            type : DataTypes.INTEGER,
            reference : {
                model : Post,
                key : 'id',
            }
        }
    }, {
        freezeTableName : true,
        timestamps : true,
    })
}
  • models/index
db.User.belongsToMany(db.Post, {through : 'Like', as: 'Liked'});
db.Post.belongsToMany(db.User, {through : 'Like', as: 'Liker'});

외래키 설정해주는 방법

/* 1 : 1 Question : Answer */
db.Question.hasOne(db.Answer, { foreignKey: 'question_id'});
db.Answer.belongsTo(db.Question, { foreignKey: 'question_id'});

각각에 모두 적어줘야됨

JOIN

const posts = await Post.findAll({ include : [{
                model : User,
                attributes : ['email', 'userName']
            }]});

S3 + multer

npm install multer

이미지 하나

const multer = require('multer');
const upload = multer({
    dest : 'upload/'
})
router.post('/single', upload.single('image'), async (req, res) => {
//   const image = req.file.location;
try{
    console.log(req.file);
    console.log(req.body);
    res.send({
      file: req.file,
      body: req.body
    });

} catch (err) {
    console.error(err)
}
});

이미지 여러개

router.post('/array', upload.array('images', 3), async (req, res) => {
//   const imageUrls = req.files.map(file => file.location);
  console.log(req.files);
  console.log(req.body);
  res.send({
    file: req.files,
    body: req.body
  });
});

s3와 연결하기

npm install multer-s3 aws-sdk

  • modules/multer
const multer = require('multer');
const multerS3 = require('multer-s3');
const aws = require('aws-sdk');
aws.config.loadFromPath(__dirname + '/../config/s3.json');

const s3 = new aws.S3();
const upload = multer({
    storage: multerS3({
        s3,
        bucket: '--name--',
        acl: 'public-read',
        key: function(req, file, cb){
            cb(null, 'images/origin/' + Date.now() + '.' + file.originalname.split('.').pop()); // 이름 설정
        }
    })
});
module.exports = upload;
  • config/s3.json
{
    "accessKeyId": "--",
    "secretAccessKey": "--",
    "region": "ap-northeast-2"
}
  • routes/multer/index.js
const express = require('express');
const router = express.Router();
const upload = require('../../modules/multer');

router.post('/single', upload.single('image'), async (req, res) => {
    try{
        const image = req.file.location;
    console.log(req.file);
    console.log(req.body);
    res.send({
      file: req.file,
      body: req.body,
      imageUrl : image,
    });

} catch (err) {
    console.error(err)
}
});

router.post('/array', upload.array('images', 3), async (req, res) => {
  const imageUrls = req.files.map(file => file.location);
  console.log(req.files);
  console.log(req.body);
  res.send({
    file: req.files,
    body: req.body,
    imageUrls : imageUrls,
  });
});

module.exports = router;

주의
upload.single(imageName)의 imageName과 동일한 이름으로 클라에서 파일을 받아야 함

profile
개발블로그

0개의 댓글