TIL 24일차: 노드 입문 개인과제 시작
0. 자주 뜨는 에러: 3000포트가 이미 사용중이어서 에러가 뜰 때 포트 삭제 방법
그냥 VS Code 터미널에서 입력하기
npx kill-port 3000
자주뜨는 에러: 키값을 추가 삭제하거나 unique 등을 없앴을 때 디비에 반영되지 않을 때:
studio 3t에서 컬렉션을 drop시켜준 다음 포트 다시 열여서 첨부터 다시 post하면 해결됨.
1. 일단 API를 예시 API에서 거의 베끼는 걸로 시작했다.
2. 서툴게 만들어본 노션.
Node 입문 개인과제 API 김수정
A new tool for teams & individuals that blends everyday work apps into one.
pale-target-69e.notion.site
3. 아직 몽고디비 연결 전. 임의의 데이터를 posts.js에 넣었고, 포트 열고 get해봤다.
dictionary structure를 만들었다. 근데 index는 어디에서 쓰이는고?
4. 몽고디비 연결해서 post와 get기능 실현
라우터 post.js의 GET과 POST METHOD
//Router는 클라의 요청을 처리하는 express.js 기능
const express = require("express")
const router = express.Router()
// post 스키마를 가져와서 Posts라는 변수에 할당. Posts는 API에서 사용됨.
const Posts = require("../schemas/post.js")
const Comment = require("../schemas/comment.js")
// localhost:3000/api/posts GET Method
// 구조: router.METHOD(PATH, HANDLER)
// express에서 http라우터를 사용하기 위해서 router.해당method 작성
router.get("/posts", async(req,res) => {
const posts = await Posts.find({})
const Ids = posts.map((post) => {
return post.postsId
})
const comments = await Comment.find({commentsId: Ids})
const postsdata = posts.map((post) => {
return{
"postsId": post.postsId, // 여기를 quantity처럼 새로운 값이 아니라 goods처럼 하나하나 찾는 값으로 바꿔야한다.
"user": post.user,
"title": post.title,
"content": post.content,
"createdAt": post.createdAt,
}
})
res.json({
"posts": postsdata,
})
})
// localhost:3000/api/posts POST Method
// 구조: router.METHOD(PATH, HANDLER)
// express에서 http라우터를 사용하기 위해서 router.해당method 작성
// post를 요청했을 때 body에 있는 데이터를 객체 구조분해 할당을 통해 가져온다.
router.post("/posts/", async(req,res) => {
const {postsId, user, title, content, createdAt} = req.body
// find로 게시글 조회
const postslist = await Posts.find({postsId})
if (postslist.length) {
return res.status(400).json({success:false, errorMessage:"이미 있는 게시글입니다."})
}
// Posts 스키마를 통해 데이터 생성, createdPosts에 할당.
const createdPosts = await Posts.create({postsId, user, title, content, createdAt})
res.json({ postslist: createdPosts})
})
라우터 comment.js의 GET METHOD
//Router는 클라의 요청을 처리하는 express.js 기능
const express = require("express")
const router = express.Router()
// comment 스키마를 가져와서 Comment라는 변수에 할당. Comment는 API에서 사용됨.
// comment가 게시된 post를 찾기 위해 post 스키마 가져와서 Posts라는 변수에 할당.
const Comment = require("../schemas/comment.js")
const Posts = require("../schemas/post.js")
// localhost:3000/api/comments GET Method
router.get("/comments", async(req,res) => {
// 모든 댓글 조회, Comment정보값을 comments에 할당.
const comments = await Comment.find({})
// 배열이 이런식으로 되어있을 때 postsId를 가져와야 함. postsIds라는 이름으로 할당함
// [
// {postsId, commentsId, user, title, content, createdAt},
// {postsId, commentsId, user, title, content, createdAt}
// ]
// map을 통해 배열 안의 값들을 하나씩 순회돌아 리턴된 결과값만 postsIds에 할당해줌
const postsIds = comments.map((comment) => {
// 반복문 돌때 postsId만 추출함. 리스트(배열)이 [1,4,8] 이런식으로 리턴됨
return comment.postsId
})
// 실제로 postsId에 해당하는 post를 가져오기
// postsId에 해당하는 값이 postsIds 리스트(배열)안에 있으면, Posts에 해당하는 모든 정보 가져오기
const posts = await Posts.find({postsId: postsIds})
// map 반복문을 통해 리턴값 posts라는 변수에 해당 post의 정보를 넣어줌.
const commentsdata = comments.map((comment) => {
return {
"commentsId": comment.commentsId,
"user": comment.user,
"title": comment.title,
"content": comment.content,
"createdAt": comment.createdAt,
//item에 해당하는 postsId와 comment에 해당하는 postsId가 일치할 때만 결과값을 리턴함
"posts": posts.find((item => item.postsId === comment.postsId))
}
})
res.json({
"comments": commentsdata
})
})
module.exports = router
게시글 POST 잘 연결되고
게시글과 댓글 GET도 잘 연결된다.
댓글은 아직 POST METHOD를 만들지 않아서 올라온 데이터가 없다.
5. 댓글 Post 메소드도 만듦, post와 comment 연결하는 것도 해결
// localhost:3000/api/comments POST Method
router.post("/comments", async(req,res) => {
const {postsId, commentsId, user, title, content, createdAt} = req.body
// find로 게시글 조회
const commentslist = await Comment.find({commentsId})
if (commentslist.length) {
return res.status(400).json({success:false, errorMessage:"이미 있는 댓글입니다."})
}
// Comment 스키마를 통해 데이터 생성, createdComments에 할당.
const createdComments = await Comment.create({postsId, commentsId, user, title, content, createdAt})
res.json({ commentslist: createdComments})
})
두번째 줄에서 postsId로 할당을 해줬어야 했다.
그리고 마지막에서 세번째 줄에서 Comment.create부분에서도 마찬가지로 postsId 할당.
결과 화면
댓글 GET 메소드에서 mongoose find를 통해 post의 상세정보까지 가져오는 것 완료
이제 이미 존재하는 게시글/댓글이라는 오류 메시지를 바꿔야 한다.
이 부분을 주석처리해줘서 오류메시지 안뜨게 함.
나중에 API에서 설정한 post와 comment 각각의 PUT에서 response(error) message를 설정해줘야한다.
{ “message”: '데이터 형식이 올바르지 않습니다.' }
6. 게시글과 댓글 auto increment시키기
const idAutoIncrement = require("id-auto-increment")
const postsSchema = new mongoose.Schema({
//게시글 post할때마다 postsId가 자동으로 +1씩 된다
postsId: idAutoIncrement(),
user: {
type: String,
required: true,
},
title: {
type: String,
},
content: {
type: String,
},
createdAt:{
type: String,
}
});
id-auto-increment
Auto generate increment id, unique guarantee, custom bit length, distributable, serverless, and customizable unique ID generator based on [Snowflake]. Latest version: 1.0.1, last published: 3 years ago. Start using id-auto-increment in your project by runn
www.npmjs.com
하지만 오류남
다른 방법
https://stackoverflow.com/a/58725224/20783271
MongoDB and Nodejs insert ID with auto increment
I am new to NodeJs and MongoDB, i want to insert row with auto increment primary key 'id'. also defined a function called getNextSequence on mongo server. this is working perfect on Mongodb serve...
stackoverflow.com
하지만 오류... 다시 전 commit으로 돌아감.
해결방법:
auto incremented 안해줘도 id값은 임의로 들어간다.
얘를 객체로 만들어주기
const {Types} = require("mongoose")
그리고 해당 값에
이런식으로 Types.ObjectId(변수이름) 써주기
// localhost:3000/api/posts PUT Method
router.put("posts/:_id", async(req, res) => {
const {_id} = req.params //라우터 매개 변수에 대한 정보가 담긴 객체
const {user} = req.body // request호출 시 body로 전달된 정보가 담긴 객체
const {password} = req.body
const {title} = req.body
const {content} = req.body
//user, password 같을 때만 수정 권한 주고싶다.
//postid를 사용해서 db에서 수정하려는 post를 가져오기, 그 post에 해당하는 pw가 일치하면 객체 보내주기
//postsId를 Object로 만들기
await Posts.findById(Types.ObjectId(_id), async (err, doc) => {
if (err) {
console.error(err)
}
const isPwRight = doc.password === password
if (isPwRight) {
await Posts.updateOne()
}
})
res.json({success:true})
})
7. PUT과 DELETE METHOD 구현하기