[Node.js] CSR로 댓글 기능 구현하기
글 작성자: 망고좋아
반응형
🎯 CSR로 댓글 기능 구현하기
📝 CSR을 구현하는 방법
- 페이지 로드 시 필요한 리소스를 클라이언트에 선언
- 클라이언트에서 필요한 데이터를 비동기 호출
- 클라이언트가 전달받은 데이터를 가공, 리소스를 사용하여 화면에 표시
📝 클라이언트에 리소스 선언 - HTML Template
- 클라이언트에 리소스를 선언하기 위한 다양한 방법이 존재. (React.js, Vue.js 등)
- 본 강의에서는 간단하게 HTML Template 기능을 사용
- HTML Template 은 브라우저에 표시되지 않는 HTML Element를 작성 해 두고, JavaScript로 이를 화면에 반복적으로 그릴 수 있게 하는 기술
📝 댓글 화면 작성하기
🛠 posts/view.pug
...
table
thead
tr
td(colspan="2")
input#content(type="text")
td: button(onclick="writeComment()")
댓글 작성
tbody#comments
template#comment-template
tr
td.content
td.author
td.createdAt
- 게시글 상세 화면 하단에 댓글 작성, 목록 화면 추가
- HTML Template 사용하여 한 개의 댓글이 표시될 모양을 선언
- JavaScript로 조작하기 위해 id, class를 선언하는 것이 유용
📝 데이터 비동기 호출 - API 작성하기
- 지금까지의 구현들은 HTTP 응답으로 HTML을 전송하는 방식
- CSR을 구현하기 위해서는 HTML이 아닌, 데이터만 주고받을 수 있는 API를 구성해야 한다. (JSON 사용)
- 댓글 작성 API와 댓글 목록 API 만 구현
- 댓글 작성 시 댓글 목록을 다시 불러와 그리는 형식으로 구현
📝 게시글에 댓글 추가하기
const CommentSchema = new Schema({
content: String,
author: {
type: Schema.Types.ObjectId,
ref: 'User',
},
}, {
timestamps: true,
});
// -----------------------
const PostSchema = new Schema({
...
comments: [CommehtSchema],
...
- mongoose의 sub-schema를 이용하여 Post 스키마에 Comment를 배열로 추가
- populate를 사용할 때, ObjectID만 저장하는 것 과는 다르게 Comment의 내용을 게시글이 포함하게 됨
- sub-schema 내부에서도 populate 가능
📝 API 작성하기 - 댓글 작성
...
router.post('/posts/:shortId/comments', ... {
const { shortId } = req.params;
const { content } = req.body;
const author = await User
.findOne({ shortId: req.user.shortId });
await Post.updateOne({ shortId }, {
$push: { comments: {
content,
author,
}},
});
res.json({ result: 'success' });
});
...
- api 라우터를 추가하고, RESTful 하게 api/posts/{postId}/comments 경로로 댓글 작성 기능 구현
- 게시글 업데이트 시 $push를 사용하여 comments 배열에 새로 작성된 댓글 추가 →동시에 들어오는 요청에 대해 정확하게 처리하는 부분
- api는 render 하지 않고 json으로 응답
📝 API 작성하기 - 댓글 목록
...
router.get('/posts/:shortId/comments', ... {
const { shortId } = req.params;
const post = await Post
.findOne({ shortId });
await User.populate(post.comments, {
path: 'author'
});
res.json(post.comments);
});
...
- /api/posts/{postId}/comments로 RESTful 경로 설정
- find에 populate 하지 않고 User (model)의 populate를 사용하는 방법도 가능하다.
📝 데이터 비동기 호출 - fetch로 클라이언트에서 api 호출하기
- 브라우저는 비동기 HTTP 요청을 fetch 함수를 이용해 제공한다.
- jQuery의 ajax와 유사한 기능, jQuery를 사용하지 않고도 HTTP 요청 구현 가능
- fetch를 이용하면 간단하게 JavaScript로 HTTP 요청을 비동기 처리할 수 있다.
📝 fetch로 API 호출하고 처리하기 - 댓글 작성하기
...
script.
function writeComment() {
const input = document.querySelector('#content')
const content = input.value;
fetch('/api/posts/#{post.shortId}/comments', {
method: 'post'
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ content }),
})
.then(() => {
if (res.ok) {
input.value = '';
loadComments();
} else {
alert('오류가 발생했습니다.');
}
});
- 댓글 작성 버튼 클릭 시 writeComment() 실행
- input#content에서 내용을 읽어 fetch로 댓글 작성 api 호출
- 호출 결과의 성공 여부를 확인하여, 댓글 다시 불러오기 실행
📝 fetch로 API 호출하고 처리하기 - 댓글 목록 불러오기
// 댓글 목록 api 호출하기
script.
loadComments();
function loadComments() {
document.querySelector('#comments') .innerHTML = ''; // 이전 목록 삭제
fetch('/api/posts/#{post.shortId}/comments')
.then((res) => {
if (res.ok) {
return res.json();
} else {
throw new Error('댓글을 불러오지 못했습니다');
}
})
.then((comments) => {
comments.forEach(addComment);
});
.catch((err) => alert(err.message));
}
// HTML Template 사용하여 댓글 화면에 표시하기
function addComment(comment) {
const template = document.querySelector('#comment-template');
const node = document.importNode(template.content, true);
node.querySelector('.content').textContent = comment.content;
node.querySelector('.author').textContent = comment.author.name;
node.querySelector('.createdAt').textContent = comment.createdAt;
document.querySelector('#comments').appendChild(node);
}
반응형
'프로그래밍 > Node.js' 카테고리의 다른 글
[Node.js] JWT + Cookie 사용하기 (0) | 2021.12.15 |
---|---|
[Node.js] JWT란? (0) | 2021.12.15 |
[Node.js] 회원과 게시글의 연동 (0) | 2021.12.13 |
[Node.js] Session Store 사용하기 (0) | 2021.12.13 |
[Node.js] Passport.js와 로그인 (0) | 2021.12.13 |
댓글
이 글 공유하기
다른 글
-
[Node.js] JWT + Cookie 사용하기
[Node.js] JWT + Cookie 사용하기
2021.12.15 -
[Node.js] JWT란?
[Node.js] JWT란?
2021.12.15 -
[Node.js] 회원과 게시글의 연동
[Node.js] 회원과 게시글의 연동
2021.12.13 -
[Node.js] Session Store 사용하기
[Node.js] Session Store 사용하기
2021.12.13