그저 내가 되었고
항해99) 5주차:: 주특기 심화; 팀과제 전체코드(JS) 본문
app.js
더보기
const express = require("express");
const likeRouter = require("./routes/like.routes.js");
const postsRouter = require("./routes/posts.routes.js");
const commentsRouter = require("./routes/comments.routes.js");
const userRouter = require("./routes/user.routes.js");
const app = express();
const router = express.Router();
app.use(express.json());
// 👆🏻JSON 이라는 규격의 body 데이터를 손쉽게 사용할 수 있게 도와주는 미들웨어
app.use("/", express.urlencoded({ extended: false }), router);
// 👆🏻form-urlencoded 라는 규격의 body 데이터를 손쉽게 사용할 수 있게 도와주는 미들웨어
app.use("/", [likeRouter, postsRouter, commentsRouter, userRouter]);
app.listen(8080, () => {
console.log("서버가 요청을 받을 준비가 됐어요");
});
user.routes.js
더보기
const express = require('express');
const userRouter = express.Router();
const UserController = require('../controllers/user.controller'); //⭐
const userController = new UserController(); //⭐AuthController에 대한 클래스 선언해서 authController에 담음
const authMiddleware = require("../middlewares/auth-middlewares");
userRouter.post('/signup', userController.signup); //⭐②createPost 메소드로 연결
userRouter.post('/login', userController.login); //⭐②createPost 메소드로 연결
module.exports = userRouter;
posts.routes.js
더보기
const express = require('express');
const router = express.Router();
const PostsController = require('../controllers/posts.controller'); //⭐
const postsController = new PostsController(); //⭐PostsController에 대한 클래스 선언해서 postsController에 담음
router.get('/posts', postsController.getPosts); //⭐①getPosts 메소드로 연결; http 메소드가 겟이고, 기본 url로 들어왔을 때, postsController의 getPosts 메소드가 실행된다~!
router.get('/posts/:postId', postsController.getPostById); //❤
router.post('/posts', postsController.createPost); //⭐②createPost 메소드로 연결
router.put('/posts/:postId', postsController.updatePost); //❤
router.delete('/posts/:postId', postsController.deletePost); //❤
module.exports = router;
like.routes.js
더보기
const express = require('express');
const router = express.Router();
const authMiddleware = require("../middlewares/auth-middlewares");
const LikeController = require('../controllers/like.controller'); //⭐
const likeController = new LikeController(); //⭐PostsController에 대한 클래스 선언해서 postsController에 담음
router.get('/posts/like', authMiddleware, likeController.getLikedPosts); //❤
router.put('/posts/:postId/like', authMiddleware, likeController.updateLike); //❤
module.exports = router;
comments.routes.js
더보기
const express = require('express');
const router = express.Router();
const CommentsController = require('../controllers/comments.controller');
const commentsController = new CommentsController();
router.get('/comments/:postId', commentsController.getComments);
router.post('/comments/:postId', commentsController.createComment);
router.put('/comments/:commentId', commentsController.updateComment);
router.delete('/comments/:commentId', commentsController.deleteComment);
module.exports = router;
user.controller.js
더보기
const UserService = require('../services/user.service');
const Joi = require('joi');
const schema = Joi.object({
nickname: Joi.string().min(2).max(15).required(),
password: Joi.string().min(4).max(20).required(),
confirm: Joi.string().min(4).max(20).required(),
});
class UserController {
userService = new UserService();
signup = async (req, res, next) => {
try {
const verifyFormat = await schema.validateAsync(req.body)
//console.log(verifyFormat);
const registerUser = await this.userService.signup(verifyFormat);
res.status(200).json({data: registerUser})
} catch (error) {
console.log(`${error.message}`);
res.status(400).send({errorMessage: "요청한 데이터 형식이 올바르지 않습니다."});
}
};
login = async (req, res, next) => {
try {
const {nickname, password} = req.body;
const user = await this.userService.login(nickname, password);
// console.log(user)
res.status(200).json({data: user});
} catch (error) {
console.log(`${error.message}`);
res.status(400).send({errorMessage: "요청한 데이터 형식이 올바르지 않습니다."});
}
};
}
module.exports = UserController;
posts.controller.js
더보기
const PostService = require('../services/posts.service');
// Post의 컨트롤러(Controller)역할을 하는 클래스
class PostsController {
postService = new PostService(); // Post 서비스 클래스를/컨트롤러 클래스의/멤버 변수로 할당
getPosts = async (req, res, next) => { //①getPosts 메소드
// 서비스 계층에 구현된 findAllsPost 로직을 실행합니다.
const posts = await this.postService.findAllPosts(); //PostsController 클래스에서 멤버 변수로 정의한 postService에서 findAllPosts 메소드를 실행하고 그 결괏값을 posts라는 변수에 할당하는 코드
res.status(200).json({data: posts}) //위에서 할당한 결괏값을 사용자에게 리턴하는 코드
}
getPostById = async (req, res, next) => {
const {postId} = req.params
const post = await this.postService.findPostById(postId);
res.status(200).json({data: post});
};
createPost = async (req, res, next) => { //②createPost 메소드
const {nickname, password, title, content} = req.body; //body 데이터를 객체구조분해할당해서 4개의 인자들을 변수로 선언
// 서비스 계층에 구현된 createPost 로직을 실행합니다.
const createPostData = await this.postService.createPost(nickname, password, title, content); //위의 인자들을 createPost라는 로직으로 구현, 로직 실행 후 결괏값을 createPostData라는 변수에 할당하고
res.status(201).json({data: createPostData}); //할당값을 http 스테이러스 코드 201로 사용자에게 리턴
}
updatePost = async (req, res, next) => {
const { postId } = req.params;
const { password, title, content } = req.body;
const updatePost = await this.postService.updatePost(
postId,
password,
title,
content
);
res.status(200).json({data: updatePost});
};
deletePost = async (req, res, next) => {
const { postId } = req.params;
const { password } = req.body;
const deletePost = await this.postService.deletePost(postId, password);
res.status(200).json({data: deletePost});
};
}
module.exports = PostsController;
like.controllers.js
더보기
const LikeService = require('../services/like.service');
const PostService = require('../services/posts.service');
class LikeController {
likeService = new LikeService(); // Post 서비스 클래스를/컨트롤러 클래스의/멤버 변수로 할당
getLikedPosts = async (req, res, next) => {
const { nickname } = res.locals.user;
const likedPosts = await this.likeService.getLikedPosts(nickname);
res.status(200).json({data: likedPosts});
};
updateLike = async (req, res, next) => {
const { postId } = req.params;
const { nickname } = res.locals.user;
const isLiked = await this.likeService.didILikeThis(postId, nickname);
/*취소*/
if (isLiked) {
const cancelLike = await this.likeService.cancelLike(postId, nickname);
res.status(200).json({data: cancelLike});
}
/*신규*/
else {
const addLike = await this.likeService.addLike(postId, nickname);
res.status(200).json({data: addLike});
}
}
}
module.exports = LikeController;
comments.controllers.js
더보기
const CommentService = require('../services/comments.service')
// Post의 컨트롤러(Controller)역할을 하는 클래스
class CommentsController {
commentService = new CommentService(); // Post 서비스 클래스를/컨트롤러 클래스의/멤버 변수로 할당
getComments = async (req, res, next) => { //①getPosts 메소드
// 서비스 계층에 구현된 findAllPost 로직을 실행합니다.
const { postId } = req.params;
const comments = await this.commentService.findAllComments(postId); //PostsController 클래스에서 멤버 변수로 정의한 postService에서 findAllPost 메소드를 실행하고 그 결괏값을 posts라는 변수에 할당하는 코드
res.status(200).json({data: comments}) //위에서 할당한 결괏값을 사용자에게 리턴하는 코드
}
createComment = async (req, res, next) => { //②createPost 메소드
const { postId } = req.params;
const { nickname, comment, password } = req.body; //body 데이터를 객체구조분해할당해서 4개의 인자들을 변수로 선언
// 서비스 계층에 구현된 createPost 로직을 실행합니다.
const createCommentData = await this.commentService.createComment(postId, nickname, comment, password); //위의 인자들을 createPost라는 로직으로 구현, 로직 실행 후 결괏값을 createPostData라는 변수에 할당하고
res.status(201).json({data: createCommentData}); //할당값을 http 스테이러스 코드 201로 사용자에게 리턴
}
updateComment = async (req, res, next) => {
const { commentId } = req.params;
const { nickname, comment, password } = req.body;
const updateComment = await this.commentService.updateComment(
commentId,
nickname,
comment,
password
);
res.status(200).json({data: updateComment});
};
deleteComment = async (req, res, next) => {
const { commentId } = req.params;
const { password } = req.body;
const deleteComment = await this.commentService.deleteComment(commentId, password);
res.status(200).json({data: deleteComment});
};
}
module.exports = CommentsController;
user.services.js
더보기
const UserRepository = require('../repositories/user.repository');
const jwt = require("jsonwebtoken");
const { User } = require("../models");
class UserService {
userRepository = new UserRepository();
signup = async (verifyFormat) => {
try {
if (verifyFormat.password !== verifyFormat.confirm) {
throw new Error("패스워드와 패스워드 확인란이 다릅니다")
}
console.log(verifyFormat)
const existsUser = await this.userRepository.findUserByNickname(verifyFormat);
if (existsUser) {
throw new Error("중복된 닉네임입니다.")
}
await this.userRepository.signup(verifyFormat.nickname, verifyFormat.password);
return "회원가입에 성공하였습니다.";
} catch (error) {
console.log(`${error.name} : ${error.message}`);
throw new Error(error);
}
};
login = async (nickname, password) => {
const user = await this.userRepository.login(nickname, password);
if (!user || password !== user.password || nickname !== user.nickname) {
return "닉네임 또는 패스워드를 확인해주세요."
}
let token = jwt.sign({userId: user.userId}, "mySecretKey");
return { message: "로그인 성공", token: token };
}
}
module.exports = UserService;
/*router.post("/signup", async (req, res) => {
try {
const {nickname, password, confirm} = await userSchema.validateAsync(req.body);
const existsUsers = await Users.findOne({where: { nickname }})
if (password.search(nickname) === nickname) {
res.status(400).send({ errorMessage: "형식에 맞지 않는 비밀번호입니다." });
return;
}
if (password !== confirm) {
res.status(400).send({ errorMessage: "패스워드가 패스워드 확인란과 다릅니다." });
return;
}
if (existsUsers) {
res.status(400).send({ errorMessage: "중복된 닉네임입니다." });
return;
}
await Users.create({nickname, password});
res.status(201).send({message: "회원가입에 성공하였습니다."});
} catch (error) {
a
}
});*/
posts.services.js
더보기
const PostRepository = require('../repositories/posts.repository'); //서비스 계층은 실제로 db 안의 정보를 사용하며, 그러기 위해서는 하위 계층의 repository모듈을 호출.
class PostService { //PostService 클래스 내부에
postRepository = new PostRepository(); //멤버 변수로 postRepository 선언, 그 변수는 postRepository 클래스를 만든 인스턴스
findAllPosts = async () => { //①findAllPost 메소드 하나
// 저장소(Repository)에게 데이터를 요청합니다.
const allPosts = await this.postRepository.findAllPosts(); //레파지토리에서 findAllPost라는 메소드 실행해서 가져온 데이터들을 allPost라는 변수에 할당함
// 호출한 Post들을 가장 최신 게시글 부터 정렬합니다.
allPosts.sort((a, b) => { //그리고 위에서 repository에서 가져온 모든 게시글들을 정렬함
return b.createdAt - a.createdAt;
})
// 비즈니스 로직을 수행한 후 사용자에게 보여줄 데이터를 가공합니다.
return allPosts.map(post => { //정렬된 데이터를 맵으로 가공 후 컨트롤러에 반환. 맵 실행하면 결과는 배열로 나오고, 거기다가 내부의 각각 하나의 데이터(postId 등)들은 큰 array 안의 각각의 post 객체에서 가져왔다(그니까.. password는 빼고 보여줘야 할 것 아님? 그거심)
return { //data 가공해서 컨트롤러에 전달 위한 부분
postId: post.postId,
nickname: post.nickname,
title: post.title,
createdAt: post.createdAt,
updatedAt: post.updatedAt
}
});
}
findPostById = async (postId) => {
const post = await this.postRepository.findPostById(postId);
return { //data 가공해서 컨트롤러에 전달 위한 부분
postId: post.postId,
nickname: post.nickname,
title: post.title,
createdAt: post.createdAt,
updatedAt: post.updatedAt
};
};
createPost = async (nickname, password, title, content) => { //②createPost 메소드 둘. 네 개의 인자를 받아 실제로 post 생성함.
// 저장소(Repository)에게 데이터를 요청합니다.
const createPostData = await this.postRepository.createPost(nickname, password, title, content); //받은 데이터로 바로 포스트 생성해버림. repository에 createPost라는 메소드 호출해서 실제로 단순하게 게시글 작성하는 문법. 작성된 결괏값을 createPostData에 할당
// 비즈니스 로직을 수행한 후 사용자에게 보여줄 데이터를 가공합니다.
return { //createPostData를 이 로직으로 아래와 같이 가공하여 컨트롤러에 반환함.
postId: createPostData.null,
nickname: createPostData.nickname,
title: createPostData.title,
content: createPostData.content,
createdAt: createPostData.createdAt,
updatedAt: createPostData.updatedAt,
};
}
updatePost = async (postId, password, title, content) => {
const findPost = await this.postRepository.findPostById(postId);
if (!findPost) throw new Error("Post doesn't exist");
await this.postRepository.updatePost(postId, password, title, content);
const updatePost = await this.postRepository.findPostById(postId);
return {
postId: updatePost.postId,
nickname: updatePost.nickname,
title: updatePost.title,
content: updatePost.content,
createdAt: updatePost.createdAt,
updatedAt: updatePost.updatedAt,
};
};
deletePost = async (postId, password) => {
const findPost = await this.postRepository.findPostById(postId);
if (!findPost) throw new Error("Post doesn't exist");
await this.postRepository.deletePost(postId, password);
return {
postId: findPost.postId,
nickname: findPost.nickname,
title: findPost.title,
content: findPost.content,
createdAt: findPost.createdAt,
updatedAt: findPost.updatedAt,
};
};
}
module.exports = PostService;
like.services.js
더보기
const LikeRepository = require('../repositories/like.repository'); //서비스 계층은 실제로 db 안의 정보를 사용하며, 그러기 위해서는 하위 계층의 repository모듈을 호출.
const PostRepository = require('../repositories/posts.repository');
class LikeService { //PostService 클래스 내부에
likeRepository = new LikeRepository();
postRepository = new PostRepository();
//멤버 변수로 postRepository 선언, 그 변수는 postRepository 클래스를 만든 인스턴스
getLikedPosts = async (nickname) => {
const likedPosts = await this.likeRepository.getLikedPosts(nickname);
const arrPostId = likedPosts.map((post) => {
return post.postId;
})
// const forPostId
const getLikedPosts = await this.postRepository.getLikedPosts(arrPostId);
const mapPosts = getLikedPosts.map((post) => {
return {
postId: post.postId,
nickname: post.nickname,
title: post.title,
likes: post.likes,
createdAt: post.createdAt,
updatedAt: post.updatedAt,
}
})
return mapPosts;
};
didILikeThis = async (postId, nickname) => {
const likedOrNot = await this.likeRepository.didILikeThis(postId, nickname);
return likedOrNot
};
addLike = async (postId, nickname) => {
await this.likeRepository.addLike(postId, nickname);
await this.postRepository.plusLikesNum(postId);
return ("좋아요 등록");
};
cancelLike = async (postId, nickname) => {
await this.likeRepository.cancelLike(postId, nickname);
await this.postRepository.minusLikesNum(postId);
return ("좋아요 취소");
};
}
module.exports = LikeService;
comments.services.js
더보기
const commentRepository = require('../repositories/comments.repository'); //서비스 계층은 실제로 db 안의 정보를 사용하며, 그러기 위해서는 하위 계층의 repository모듈을 호출.
class CommentService {
commentRepository = new commentRepository(); //멤버 변수로 postRepository 선언, 그 변수는 postRepository 클래스를 만든 인스턴스
findAllComments = async (postId) => { //①findAllPost 메소드 하나
const allComments = await this.commentRepository.findAllComments(postId);
allComments.sort((a, b) => {
return b.createdAt - a.createdAt;
})
// 비즈니스 로직을 수행한 후 사용자에게 보여줄 데이터를 가공합니다.
return allComments.map(comment => { //정렬된 데이터를 맵으로 가공 후 컨트롤러에 반환. 맵 실행하면 결과는 배열로 나오고, 거기다가 내부의 각각 하나의 데이터(postId 등)들은 큰 array 안의 각각의 post 객체에서 가져왔다(그니까.. password는 빼고 보여줘야 할 것 아님? 그거심)
return { //data 가공해서 컨트롤러에 전달 위한 부분
postId: comment.postId,
commentId: comment.commentId,
nickname: comment.nickname,
createdAt: comment.createdAt,
updatedAt: comment.updatedAt
}
});
}
createComment = async (postId, nickname, password, comment) => { //②createPost 메소드 둘. 네 개의 인자를 받아 실제로 post 생성함.
// 저장소(Repository)에게 데이터를 요청합니다.
const createCommentData = await this.commentRepository.createComment(postId, nickname, password, comment); //받은 데이터로 바로 포스트 생성해버림. repository에 createPost라는 메소드 호출해서 실제로 단순하게 게시글 작성하는 문법. 작성된 결괏값을 createPostData에 할당
// 비즈니스 로직을 수행한 후 사용자에게 보여줄 데이터를 가공합니다.
return { //createPostData를 이 로직으로 아래와 같이 가공하여 컨트롤러에 반환함.
postId: createCommentData.postId,
commentID: createCommentData.commentID,
nickname: createCommentData.nickname,
comment: createCommentData.comment,
createdAt: createCommentData.createdAt,
updatedAt: createCommentData.updatedAt,
};
}
updateComment = async (commentId, nickname, comment, password) => {
const findComment = await this.commentRepository.findCommentById(commentId);
if (!findComment) throw new Error("Comment doesn't exist");
await this.commentRepository.updateComment(commentId, nickname, comment, password);
const updateComment = await this.commentRepository.findCommentById(commentId);
return {
commentId: updateComment.commentId,
nickname: updateComment.nickname,
comment: updateComment.comment,
createdAt: updateComment.createdAt,
updatedAt: updateComment.updatedAt,
};
};
deleteComment = async (commentId, password) => {
const findComment = await this.commentRepository.findCommentById(commentId);
if (!findComment) throw new Error("Comment doesn't exist");
await this.commentRepository.deleteComment(commentId, password);
return {
postId: findComment.postId,
commentId: findComment.commentId,
nickname: findComment.nickname,
content: findComment.content,
createdAt: findComment.createdAt,
updatedAt: findComment.updatedAt,
};
};
}
module.exports = CommentService;
user.repositories.js
더보기
const { User } = require("../models");
class UserRepository {
findUserByNickname = async (verifyFormat) => {
const nickname = verifyFormat.nickname;
const user = await User.findOne({where: {nickname}});
return user;
};
signup = async (nickname, password) => {
const registerUser = await User.create( {nickname, password});
return registerUser;
console.log(registerUser)
}
login = async (nickname, password) => {
const findUser = await User.findOne({where: {nickname, password}});
return findUser;
}
}
module.exports = UserRepository;
posts.repositories.js
더보기
// repositories/posts.repository.js
const {Posts} = require('../models'); //⓪models 안의 Posts 모듈을 가져옴. 왜? 이 repository에서 sequelize를 통해서 Posts 테이블에 접근을 하기 위해서
class PostRepository { //PostRepository클래스는 ORM인 Sequelize에서 Posts 모델의 findAll 메소드를 사용해 데이터를 요청
findAllPosts = async () => { //①findAllPost메소드와
const posts = await Posts.findAll(); //⓪에서 가져온 Posts에서 실제 db에 접근하여 데이터 사용. Posts 라는 모델에서 findAll 이용해서 데이터(게시글) 몽땅 찾아서 posts란 변수에 할당 후
return posts; //걔를 리턴
}
findPostById = async (postId) => {
const post = await Posts.findByPk(postId);
return post;
};
createPost = async (nickname, password, title, content) => { //②createPost 메소드를 가짐
// ORM인 Sequelize에서 Posts 모델의 create 메소드를 사용해 데이터를 요청합니다.
const createPostData = await Posts.create({nickname, password, title, content});
return createPostData;
}
updatePost = async (postId, password, title, content) => {
const updatePostData = await Posts.update({title, content}, {where: {postId, password}}
);
return updatePostData;
};
deletePost = async (postId, password) => {
const updatePostData = await Post.destroy({Where: {postId, password}});
return updatePostData;
};
}
module.exports = PostRepository;
like.repositories.js
더보기
// repositories/posts.repository.js
const { Like } = require('../models'); //⓪models 안의 Posts 모듈을 가져옴. 왜? 이 repository에서 sequelize를 통해서 Posts 테이블에 접근을 하기 위해서
class LikeRepository {
getLikedPosts = async (nickname) => {
const likedPosts = await Like.findAll({ where: { nickname } })
return likedPosts;
}
didILikeThis = async (postId, nickname) => {
const hereItIs = await Like.findOne({ where: { postId, nickname } });
return hereItIs;
};
addLike = async (postId, nickname) => {
const updateLikeData = await Like.create({ postId, nickname });
return updateLikeData;
};
cancelLike = async (postId, nickname) => {
const updateLikeData = await Like.destroy({where: {postId, nickname}});
return updateLikeData;
};
}
module.exports = LikeRepository;
comments.repositories.js
더보기
const { Comments } = require('../models'); //⓪models 안의 Posts 모듈을 가져옴. 왜? 이 repository에서 sequelize를 통해서 Posts 테이블에 접근을 하기 위해서
class CommentRepository {
findAllComments = async (postId) => {
const comments = await Comments.findAll({where: {postId}});
return comments;
}
findCommentById = async (commentID) => {
const comment = await Comments.findByPk(commentID);
return comment;
}
createComment = async (postId, nickname, comment, password) => {
const createCommentData = await Comments.create({postId, nickname, comment, password});
return createCommentData;
}
updateComment = async (commentId, nickname, comment, password) => {
const updateCommentData = await Comments.update({ comment }, {where: {commentId, nickname, password}}
);
return updateCommentData;
};
deleteComment = async (commentId, password) => {
const updateCommentData = await Comments.destroy({where: {commentId, password}});
return updateCommentData;
};
}
module.exports = CommentRepository;
'개발 > 항해99 9기' 카테고리의 다른 글
항해99) 6주차:: 미니 프로젝트; 📚CORS (0) | 2022.10.23 |
---|---|
항해99) 5주차:: 주특기 심화; 📚객체 지향 & 추상화 & 클래스와 인스턴스 (0) | 2022.10.19 |
항해99) 5주차:: 주특기 심화; 📚Socket.io (0) | 2022.10.15 |
항해99) 4주차:: 주특기 숙련; 개인과제 전체코드(JS)(ver.Sequelize) (0) | 2022.10.13 |
항해99) 4주차:: 주특기 숙련; 📚미들웨어 (0) | 2022.10.12 |