ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Basic CRUD with express + mongodb
    Share/Nodejs 2020. 11. 18. 23:49

    니꼬쌤의 wetube를 바탕으로 작성하였습니다

     

     

     

     

    기존에는 

    Router 

    Controller

    app.js

    init.js 

    (routes) //url 

     

    로 구조를 생성했다고 본다면, 

     

    이제는 " 실제 데이터 " 를 가지고 적용 할 수 있도록 

    mongodb 를 적용하여 Creat Read Update Delete 를 수행 해보자 + Search 까지 

     

     

     

    1. mongodb 설치 및 mongoose 설치 

    (mongodb 는 os 맞게 알아서 설치...^^)

     

    npm i mongoose

     

     

    /db.js 파일 생성 

    import mongoose from "mongoose";
    import dotenv from "dotenv";
    dotenv.config();
    
    
    mongoose.connect(
      process.env.MONGO_URL,
      {
        useNewUrlParser: true,
        useFindAndModify: false
      }
    );
    
    const db = mongoose.connection;
    
    const handleOpen = () => console.log("✅  Connected to DB");
    const handleError = error => console.log(`❌ Error on DB Connection:${error}`);
    
    db.once("open", handleOpen);
    db.on("error", handleError);
    
    • mongoose를 이용하여 간단하게 mongodb 와 연동 할 수 있다. 
    • process.env.MONGO_URL 을 이용하여 보완강화 --> .env에 따로 경로 저장 

    /init.js 에서 db 파일 import 

    import "./db"
    import app from "./app";
    import dotenv from "dotenv";
    dotenv.config();
    import "./models/Video";
    
    
    const PORT = process.env.PORT;
    
    
    const handleListening = () =>
      console.log(`✅ Listening on: http://localhost:${PORT}`);
    
    app.listen(PORT, handleListening);

     

    Terminal 1개 열어서 

    mongod  명령어 실행 하여 db 켜줌 

     

    Terminal 1개 추가로 열어서 

    npm start 했을시에 구동 성공 확인 

     

    2. 모델 생성 

    models/Comment.js

    import mongoose from "mongoose";
    
    const CommentSchema = new mongoose.Schema({
      text: {
        type: String,
        required: "Text is required"
      },
      createdAt: {
        type: Date,
        default: Date.now
      }
    });
    
    const model = mongoose.model("Comment", CommentSchema);
    export default model;

     

    전형적인 schema 


    models/Video.js

    import mongoose from "mongoose";
    
    const VideoSchema = new mongoose.Schema({
      fileUrl: {
        type: String,
        required: "File URL is required"
      },
      title: {
        type: String,
        required: "Tilte is required"
      },
      description: String,
      views: {
        type: Number,
        default: 0
      },
      createdAt: {
        type: Date,
        default: Date.now
      },
      comments: [
        {
          type: mongoose.Schema.Types.ObjectId,
          ref: "Comment"
        }
      ]
    });
    
    const model = mongoose.model("Video", VideoSchema);
    export default model;

     

    3. 실제 data 를 Router 및 Controller에 대체/적용  하자. 

     

    controllers/videoController.js 

    // import { videos } from "../db";
    import routes from "../routes";
    
    import Video from "../models/Video";
    
    export const home = async (req, res) => {
      try {
        // const videos = await Video.find({});
        const videos = await Video.find({}).sort({ _id: -1 });
        res.render("home", {pageTitle: "Home", videos})
      } catch (error) {
        console.log(error);
        res.render("home", { pageTitle: "Home", videos: [] });
      }
    };
    
    
    export const search = async(req, res) => {
        const {
          query: { term: searchingBy }
        } = req;
        
        console.log(req.query.term);
        
        // res.render("search", { pageTitle: "Search", searchingBy, videos });
    
      let videos = [];
      try {
        videos = await Video.find({
          title: { $regex: searchingBy, $options: "i" }
        });
      } catch (error) {
        console.log(error);
      }
      res.render("search", { pageTitle: "Search", searchingBy, videos });
    
    
        res.render("search", { pageTitle: "Search", searchingBy });
      };
    
      
    
      
    
      export const getUpload = (req, res) =>
      res.render("upload", { pageTitle: "Upload" });
    
      export const postUpload = async(req, res) => {
        const {
          body: { title, description },
          file: {path}
        } = req;
        // To Do: Upload and save video
        const newVideo = await Video.create({
          fileUrl: path,
          title,
          description
        })
        res.redirect(routes.videoDetail(newVideo.id))
      };
      
      export const videoDetail = async (req, res) => {
        const {
          params: { id }
        } = req;
        try {
          const video = await Video.findById(id);
          res.render("videoDetail", { pageTitle: video.title, video });
        } catch (error) {
          res.redirect(routes.home);
        }
      };
    
    export const getEditVideo = async (req, res) => {
      const {
        params: { id }
      } = req;
      try {
        const video = await Video.findById(id);
        res.render("editVideo", { pageTitle: `Edit ${video.title}`, video });
      } catch (error) {
        res.redirect(routes.home);
      }
    };
    
    export const postEditVideo = async (req, res) => {
      const {
        params: { id },
        body: { title, description }
      } = req;
      try {
        // await Video.findOneAndUpdate({ id }, { title, description }); //wowowowowow
        await Video.findOneAndUpdate({ _id: id }, { title, description });
        
        res.redirect(routes.videoDetail(id));
      } catch (error) {
        res.redirect(routes.home);
      }
    };
    
    export const deleteVideo = async (req, res) => {
      const {
        params: { id }
      } = req;
      try {
        await Video.findOneAndRemove({ _id: id });    // THIS PART 
      } catch (error) {}
      res.redirect(routes.home);
    };
    • 당연히 가장 먼저 ! 기본적으로 ! model 을 import해주고 ~ 
    • 현재 videos라는 비디오 데이터는 async - await 으로 db와의 연동을 함 
    • mongodb 함수 ( find , Create, Delete 등을 사용하여 db 값을 컨트롤 함 ) 
    • 주의 할 점은 
       
       데이터 관련 객체를 생성할때, 변수 들이다 .
      ex > 아래와 같이, post 요청시 데이터를 전달할때 body, file 등 헷갈리지 않아야함. 
    export const postUpload = async(req, res) => {
        const {
          body: { title, description },
          file: {path}
        } = req;
        // To Do: Upload and save video
        const newVideo = await Video.create({
          fileUrl: path,
          title,
          description
        })
        res.redirect(routes.videoDetail(newVideo.id))
      };
    export const getEditVideo = async (req, res) => {
      const {
        params: { id }
      } = req;
      try {
        const video = await Video.findById(id);
        res.render("editVideo", { pageTitle: `Edit ${video.title}`, video });
      } catch (error) {
        res.redirect(routes.home);
      }
    };
    • 또 주의사항은 , id 컨트롤을 조심해야됨 
    • 다음과 같이 선언 해야됨

    export const postEditVideo = async (req, res) => {
      const {
        params: { id },
        body: { title, description }
      } = req;
      try {
        // await Video.findOneAndUpdate({ id }, { title, description }); //wowowowowow
        await Video.findOneAndUpdate({ _id: id }, { title, description });
        
        res.redirect(routes.videoDetail(id));
      } catch (error) {
        res.redirect(routes.home);
      }
    };

     


    routers/videoRouter.js

    import express from "express";
    import routes from "../routes";
    
    import {
        getUpload,
        postUpload,
        videoDetail,
        deleteVideo,
        getEditVideo,
        postEditVideo
      } from "../controllers/videoController";
      import { uploadVideo } from "../middlewares";
    
    
    
    const videoRouter = express.Router();
    
    
    videoRouter.get(routes.upload, getUpload);
    videoRouter.post(routes.upload,uploadVideo, postUpload);
    videoRouter.get(routes.videoDetail(), videoDetail);
    
    videoRouter.get(routes.videoDetail, videoDetail);
    // Edit Video
    videoRouter.get(routes.editVideo(), getEditVideo);
    videoRouter.post(routes.editVideo(), postEditVideo);
    
    // Delete Video
    videoRouter.get(routes.deleteVideo(), deleteVideo);
    
    export default videoRouter;
    • router에는 딱히 바꿀께 없다 
    • 단, 경로 설정 중에 id 가 적용 되는 부분은 routes 파일에 가서 함수형식으로 바꿔줘야 에러가 나지않는다 
      (ex. deleteVideo() 의 경우 routes 에서 id 를 매개변수로 받는 함수여야 함 ) 

     

     

    *추가 사항 

    • multer를 사용하여 이미지 데이터 저장 및 경로 간편화 
    import multer from "multer";
    import routes from "./routes";
    
    const multerVideo = multer({ dest: "uploads/videos/" });
    
    export const localsMiddleware = (req, res, next) => {
      res.locals.siteName = "SuperBaik ";
      res.locals.routes = routes;
      res.locals.user = {
        isAuthenticated: true,
        id: 1
      };
    
    
      next();
      
    };
    
    export const uploadVideo = multerVideo.single("videoFile");
    
    
    

     

     

     

     

    시간이 없어서 일단 정리 끝냄. 

    'Share > Nodejs' 카테고리의 다른 글

    [Error] npm 글로벌 설치 관련 에러  (0) 2020.11.25
    webpack , scss, config파일 설정  (0) 2020.11.22
    Nodejs MVC patter Setting  (0) 2020.11.16
    git 사용 요약  (0) 2020.11.16
    Nodejs Mysql 연동  (0) 2020.11.12

    댓글

실험중인 삶, Life is not a race