Node.js, MongoDB로 웹서비스 만들기 Part 2

정창민·2022년 12월 6일
0

1. Server 세팅

const express = require('express');
const app = express();
const bodyParser= require('body-parser') 
app.use(bodyParser.urlencoded({extended: true}))

app.set('view engine', 'ejs');
app.use('/public', express.static('public'))

const MongoClient = require('mongodb').MongoClient;

let db;
MongoClient.connect('mongodb+srv://ckdals1994:ckdalsla94@cluster0.xtrzoeq.mongodb.net/?retryWrites=true&w=majority', (에러, client) => {
  if(에러) return console.log(에러)
  db = client.db('mypage');  

  app.listen(6050, () => { 
    console.log('listening on 6050');
  }); 

});

  • body-parser :
    input에 입력해서 요청해 저장된 정보를 쉽게 꺼내 보기위한 라이브러리

  • ejs :
    EJS 문법으로 데이터를 꽂아넣을 수 있음


2. 서버에서 db로 데이터 넣기 (post)

app.post('/add', (요청, 응답) => {
  console.log(요청.body)
  응답.send('전송완료')

  db.collection('schedule').insertOne({
    제목 : 요청.body.title,
    날짜 : 요청.body.date
  }, (에러, 결과) => {
    console.log('저장완료')
  })
})
  • 응답.send() 이 부분은 항상 존재해야함, 서버에서 전송이 실패나 성공에 상관없이 뭔가를 서버에서 보내줘야함 그렇지 않으면 브라우저가 멈춘다.

  • db 스케출 테이블을 찾고, data를 insert


3. db 저장된 데이터를 웹페이지로 불러들이기 (get)

app.get('/list', (요청, 응답) => {
  db.collection('schedule').find().toArray( (에러, 결과) => {
    console.log(결과)
    응답.render('list.ejs', {rows : 결과})
  })
})
  • db 스케줄 테이블을 찾아서, 저장된 모든 데이터를 Array자료형 형태로 가져옴

  • list.ejs 파일을 렌더링 함과 동시에 db 데이터들을 row에 저장해서 html로 보내줄 수 있게된다.


<ul class="list-group container">
    <% for(let i = 0; i < rows.length; i++) { %>
    <li class="list-group-item">
      <h5>제목 : <%= rows[i].제목 %></h5>
      <p>날짜 : <%= rows[i].날짜 %></p>
      <button type="button" class="btn btn-danger delete" data-id="<%= rows[i]._id %>">Delete</button>
    </li>
    <% } %>
  </ul>
  • ejs 문법으로 가져온 데이터 rows를 for문으로 활용

4. 게시물 마다 번호 달기

  • 새로운 (counter)테이블을 하나 생성한다.

  • total : 0 과 name : '게시물갯수' 로 저장하였음

  • total : 0 에 카운팅을 하여 게시물에 번호를 붙여줄 계획


app.post('/add', (요청, 응답) => {
  console.log(요청.body)
  응답.send('전송완료')

  db.collection('counter').findOne({name : '게시물갯수'}, (에러, 결과) => {
    let 총게시물갯수 = 결과.total

    db.collection('schedule').insertOne({
      _id : 총게시물갯수 + 1,
      제목 : 요청.body.title,
      날짜 : 요청.body.date
    }, (에러, 결과) => {
      console.log('저장완료')
      db.collection('counter').updateOne({name : '게시물갯수'}, {$inc : {total : 1} }, (에러, 결과) => {
        if(에러) return console.log(에러)
        console.log('total 업데이트 완료')
      })
      
    })

  })
})



5. DELETE 요청하기

<h3 class="text-center mt-3">해야할 일</h3>
  <ul class="list-group container">
    <% for(let i = 0; i < rows.length; i++) { %>
    <li class="list-group-item">
      <h5>제목 : <%= rows[i].제목 %></h5>
      <p>날짜 : <%= rows[i].날짜 %></p>
      <button type="button" class="btn btn-danger delete" data-id="<%= rows[i]._id %>">Delete</button>
    </li>
    <% } %>
  </ul>
  • data-id 로 버튼 태그에 id값 속성을 부여할 수 있음

  • 게시글 번호를 속성으로 부여하여, 게시글 번호를 통해 삭제시키는 원리


$('.delete').on('click', function(e) {
      let 글번호 = e.target.dataset.id
      let 지금누른거 = $(this)

      $.ajax({
        method : 'DELETE',
        url : '/delete',
        data : { _id : 글번호 }
      }).done(function(결과){
        console.log('html 삭제 성공')
        지금누른거.parent('li').fadeOut()
      }).fail(function(a, b, c){
        console.log(a, b, c)
      });
    })
  • e.target으로 클릭한 버튼의 id 속성을 글번호 변수에 저장

  • _id : 글번호를 서버로 delete 요청

  • 클릭한 버튼의 부모 태그를 fadeout하여 새로고침 없이 숨겨지게 하는 꼼수?

  • window.location.reload() 코드를 통해 새로고침 하는 방법도 있음


app.delete('/delete', function(요청, 응답){
  요청.body._id = parseInt(요청.body._id)
  db.collection('schedule').deleteOne(요청.body, (에러, 결과) => {
    console.log('삭제완료')
    응답.status(200).send({ message : '성공했습니다.'})
  })
})
  • parseInt는 문자열을 정수로 바꿔주는 고마운 친구

  • 문자열 id값을 정수로 변환해 저장

  • satatus 200은 http 상태 코드 '요청이 성공적으로 되었습니다. '는 뜻
    성공 메세지를 보내는 또 다른 방법



6. 상세페이지 만들기 (URL parameter)

app.get('/detail/:id', (요청, 응답) => {
  db.collection('schedule').findOne({_id : parseInt(요청.params.id)}, (에러, 결과) => {
    응답.render('detail.ejs', {data : 결과})
    console.log(결과)
  })
})
  • 주소창에 '/detail/ (번호)' 를 적으면
    db의 schedule 테이블에서 해당되는 _id 번호를 찾는다.

  • detail.ejs 출력함과 동시에 schedule 테이블의 정보를 data 변수에 넣어서
    ejs 파일로 보내준다.


<div class="container mt-3">
    <h4>상세페이지</h4>

    <div class="card" style="width: 100%;">
      <div class="card-body">
        <h5 class="card-title"><%= data.제목 %></h5>
        <h6 class="card-subtitle mb-2 text-muted"><%= data.날짜 %></h6>
        <p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
        <a href="#" class="card-link">Card link</a>
        <a href="#" class="card-link">Another link</a>
      </div>
    </div>
  </div>
  • 받아온 데이터를 웹 페이지에서 활용한 모습
profile
안녕하세요~!

0개의 댓글