본문 바로가기
JS/Node.js

TIL(2023.06.27)

by 썸맨 2023. 6. 29.

★ 팀프로젝트 Development

 - 좋아요 기능을 posts 내에 넣는 것 보다 해당 게시글 id와 유저의 id를 받아서 좋아요에 넣는다면 조금 더 효율적으로 좋아요를 관리할 수 있을 거 같기에 likes 테이블을 새로 만듬(한 유저는 한 게시글에는 한 번의 좋아요만 누를 수 있고 한 번 더 누르게 된다면 좋아요가 -1되는 형식으로 구현 예정)

변경한 ERD

=> like를 추가하고 댓글도 추가한 ERD로 변경

 

☆ upload 미들웨어 추가

 - 기존에 구상했던 이미지를 직접 저장하는 방식이 아닌 multerS3와 multer 라이브러리를 이용해서 이미지만 업로드가 되도록 하는 미들웨어를 추가

const s3 = new AWS.S3({
  accessKeyId: env.S3_ACCESS_KEY,
  secretAccessKey: env.S3_ACCESS_KEY_SECRET,
  region: env.AWS_REGION,
});

const allowedExtensions = ['.png', '.jpg', '.jpeg', '.bmp', '.gif'];

const upload = multer({
  storage: multerS3({
    s3: s3,
    bucket: env.BUCKET_NAME,
    contentType: multerS3.AUTO_CONTENT_TYPE,
    key: function (req, file, callback) {
      const fileId = uuid4();
      const type = file.mimetype.split('/')[1];
      if (
        !allowedExtensions.includes(path.extname(file.originalname.toLowerCase())) ||
        !file.mimetype.startsWith('image/')
      )
        return callback('이미지 파일만 업로드가 가능합니다.');

      const fileName = `${fileId}.${type}`;
      callback(null, fileName);
    },
    acl: 'public-read-write',
  }),
  limits: { fieldSize: 1024 * 1024 },
});

const uploadMiddleware = upload.single('newFile');
module.exports = uploadMiddleware;

=> 액세스 키와 비밀키 그리고 지역이 담긴 내용을 가진 새로운 s3객체를 생성(해당 액세스 키는 AWS에서 AmazonS3FullAccess 권한을 가지고 있어야 함!), 생성된 s3객체를 이용해 버킷에 저장 / allowedEextensions를 통해 들어오는 확장자가 이미지 파일인지와 해당 파일의 mimetype이 image로 시작이 되는지를 검증함으로서 이미지 파일만 들어오도록 설정

※ uuid4()를 사용해서 동일한 이름의 이미지가 들어왔을 때에도 저장이 될수 있도록 설정(uuid로 생성된 이름에 확장자를 붙여 데이터를 저장)

 

☆ 회원가입 및 회원가입 수정에 업로드 된 파일을 저장

const filepath = req.file ? req.file.location : null;

=> 업로드 시, req.file에 해당 파일의 정보가 들어오게 되는데 파일이 있다면 filepath에 할당 후 할당 한 이 경로를 image_url 필드에 저장(꺼내올 때도 그대로 꺼내오면 됨)

 

 

☆ db.sequelize.sync()

 - db의 속성명은 카멜케이스를 사용하는 게 아닌 _를 이용해서 작성하는 편이 좋다!해서 필드명을 전체 바꾸는 것을 진행 했었는데 createdAt같은 경우 db가 생성이 될 때 자동으로 생성이 되는 필드 값이기 때문에 이 값마저 _를 이용해서 created_at으로 변경을 하고 싶었음 

 - 변경하기 위해서 기본적으로 만들어지는 createdAt을 안만들어지게 하도록 migration과 model 내에 timestamp:false를 추가 함으로 해당 테이블이 생성이 될 때 생성이 안되도록 설정! but 이것을 마이그레이션하고 실행 하면 해당 field LIst를 찾을 수 없다라는 오류가 발생!

 - 오류해결 : app.js 에 db.sequelize.sync({force:true}) (여기서 db는 model이 생성될 때 해당 모델을 사용할 수 있도록 해주는 index.js에서 exports 해주는 db)를 통해 한 번 실행해주면 해당 db의 싱크를 맞춰준다!! -> 이 후 db.sequelize.sync()로 변경 후 재 실행 한다면 오류 발생 없이 사용이 가능함

 

☆ 게시글 검색 기능

 - tilte과 content 내에 해당 키워드로 검색을 했을 때 해당이 되는 모든 게시글을 찾아서 보여주는 역할

    const { search } = req.query;

    if (!search) {
      return res.status(400).json({
        message: '검색어를 입력해주세요.',
      });
    }

    const searchPosts = await Post.findAll({
      attributes: ['post_id', 'Name', 'title', 'content'],
      where: {
        [Op.or]: [
          { title: { [Op.like]: `%${search}%` } },
          { content: { [Op.like]: `%${search}%` } },
        ],
      },
    });

=> 쿼리에 key값이 search로 입력된 value값을 가져와서 해당 값이 들어 있는 제목과 내용을 전부 가져와서 출력을 해줌으로서 구현

 

 

※ 추가적으로 여러 쿼리를 받아서 (ex) title, content, all 등등) 해당 쿼리 조건에 만족하는 조건을 검색한 결과를 반환해주는 방향으로 develop 예정