게시판 - Back End 개발

소스코드

이 게시물에는 코드작성이 포함되어 있습니다. 소스코드를 받으신 후 진행해 주세요. MEAN Stack/개발 환경 구축에서 설명된 프로그램들(git, npm, atom editor)이 있어야 아래의 명령어들을 실행할 수 있습니다.

이 게시물의 소스코드는 게시판 만들기 / 게시판 - 프로젝트 생성 및 navbar에서 이어집니다.

board.git 을 clone 한 적이 있는 경우: 터미널에서 해당 폴더로 이동 후 아래 명령어들을 붙여넣기합니다. 폴더 내 모든 코드가 이 게시물의 코드로 교체됩니다. 이를 원치 않으시면 이 방법을 선택하지 마세요.

git reset --hard
git pull
git reset --hard 79ba957
git reset --soft 1cd61b1
npm install
atom .

board.git 을 clone 한 적이 없는 경우: 터미널에서 코드를 다운 받을 폴더로 이동한 후 아래 명령어들을 붙여넣기하여 board.git 을 clone 합니다.

git clone https://github.com/a-mean-blogger/board.git
cd board
git reset --hard 79ba957
git reset --soft 1cd61b1
npm install
atom .

- Github에서 소스코드 보기: https://github.com/a-mean-blogger/board/tree/79ba9572170952bd888d5a4de98c37875505fb07


이제 게시판 CRUD를 만들텐데 두 파트로 나누어서 이번 글에서 back end 코드를 작성하고, 다음 글에서 front end 코드를 작성하겠습니다.

게시판이라고 해도 주소록 만들기와 크게 다르지 않습니다. 게시판도 결국 데이터를 생성하고, 보여주고, 수정하고, 지우는 CRUD 기능이니까요.

이번 글에서는 Post(게시물) model을 만들고 back end CRUD를 구현해 봅시다.

폴더구조

코드

// models/Post.js

var mongoose = require('mongoose');

// schema
var postSchema = mongoose.Schema({ // 1
  title:{type:String, required:true},
  body:{type:String, required:true},
  createdAt:{type:Date, default:Date.now}, // 2
  updatedAt:{type:Date},
});

// model & export
var Post = mongoose.model('post', postSchema);
module.exports = Post;

1. Post의 schema는 title, body, createdAt, updatedAt으로 구성이 되어 있습니다.

2. default 항목으로 기본 값을 지정할 수 있습니다. 함수명을 넣으면 해당 함수의 return이 기본값이 됩니다.
(Date.now는 현재시간을 리턴하는 함수입니다)

// routes/posts.js

var express  = require('express');
var router = express.Router();
var Post = require('../models/Post');

// Index 
router.get('/', function(req, res){
  Post.find({})                  // 1
  .sort('-createdAt')            // 1
  .exec(function(err, posts){    // 1
    if(err) return res.json(err);
    res.render('posts/index', {posts:posts});
  });
});

// New
router.get('/new', function(req, res){
  res.render('posts/new');
});

// create
router.post('/', function(req, res){
  Post.create(req.body, function(err, post){
    if(err) return res.json(err);
    res.redirect('/posts');
  });
});

// show
router.get('/:id', function(req, res){
  Post.findOne({_id:req.params.id}, function(err, post){
    if(err) return res.json(err);
    res.render('posts/show', {post:post});
  });
});

// edit
router.get('/:id/edit', function(req, res){
  Post.findOne({_id:req.params.id}, function(err, post){
    if(err) return res.json(err);
    res.render('posts/edit', {post:post});
  });
});

// update
router.put('/:id', function(req, res){
  req.body.updatedAt = Date.now(); //2
  Post.findOneAndUpdate({_id:req.params.id}, req.body, function(err, post){
    if(err) return res.json(err);
    res.redirect("/posts/"+req.params.id);
  });
});

// destroy
router.delete('/:id', function(req, res){
  Post.deleteOne({_id:req.params.id}, function(err){
    if(err) return res.json(err);
    res.redirect('/posts');
  });
});

module.exports = router;

route은 1, 2번을 제외하면 주소록 만들기예제의 contacts route와 형태가 거의 같습니다. 앞으로도 CRUD 기능을 만들게 된다면 항상 거의 이 형태를 사용하게 됩니다.

1. 나중에 생성된 data가 위로 오도록 정렬합니다. find와 function 사이에 sort함수가 들어간 형태인데요,
원래 모양은

Post.find({}, function(err, posts){ ... })

이였는데

Post.find({})
  .sort('-createdAt')
  .exec(function(err, posts){ ... })

이렇게 바뀌었죠. 사실 원래모양 역시

Post.find({})
  .exec(function(err, posts){ ... })

를 줄인 표현인데요, .exec함수 앞에 DB에서 데이터를 어떻게 찾을지, 어떻게 정렬할지 등등을 함수로 표현하고, exec안의 함수에서 해당 data를 받아와서 할일을 정하는 구조입니다.

.sort()함수는 string이나 object를 받아서 데이터 정렬방법을 정의하는데요, 문자열로 표현하는 경우 정렬할 항목명을 문자열로 넣으면 오름차순으로 정렬하고, 내림차순인 경우 -를 앞에 붙여줍니다. 두가지 이상으로 정렬하는 경우 빈칸을 넣고 각각의 항목을 적어주면 됩니다. object를 넣는 경우 {createdAt:1}(오름차순), {createdAt:-1}(내림차순) 이런식으로 넣어주면 됩니다.

2. post를 수정하는 경우 수정된 날짜를 updateAt에 기록합니다.

// index.js

...

// Routes
app.use('/', require('./routes/home'));
app.use('/posts', require('./routes/posts')); // 1

...

1. 마지막으로 posts route를 index.js에 추가해 줍니다.

실행결과

아직 views가 없으니 생성한 route를 실행해 볼 수가 없죠. 실행결과는 다음 포스트에서..!

마치며...

model/ route주소록 만들기과 거의 똑같죠?
7 actions로 route를 한번 잘 만들어 놓으면 새로운 route을 만들때 필요한 부분만 수정해서 쓸 수 있습니다.
다음 포스트에서는 이번에 만든 back end를 사용하여 실제 page들을 만들어 보겠습니다.

댓글

댓글쓰기

이 글에 댓글을 다시려면 SNS 계정으로 로그인하세요. 자세히 알아보기

UP