💡 게시글 생성 API 비즈니스 로직
title, content를 body로 전달받습니다.PostsRouter를 등록한 app.js
// src/app.js
import express from 'express';
import cookieParser from 'cookie-parser';
import LogMiddleware from './middlewares/log.middleware.js';
import ErrorHandlingMiddleware from './middlewares/error-handling.middleware.js';
import UsersRouter from './routes/users.router.js';
import PostsRouter from './routes/posts.router.js';
const app = express();
const PORT = 3018;
app.use(LogMiddleware);
app.use(express.json());
app.use(cookieParser());
app.use('/api', [UsersRouter, PostsRouter]);
app.use(ErrorHandlingMiddleware);
app.listen(PORT, () => {
console.log(PORT, '포트로 서버가 열렸어요!');
});
게시글 생성 API
// src/routes/posts.router.js
import express from 'express';
import { prisma } from '../utils/prisma/index.js';
import authMiddleware from '../middlewares/auth.middleware.js';
const router = express.Router();
/ 게시글 생성 API /
router.post('/posts', authMiddleware, async (req, res, next) => {
const { userId } = req.user;
const { title, content } = req.body;
const post = await prisma.posts.create({
data: {
UserId: userId,
title,
content,
},
});
return res.status(201).json({ data: post });
});
export default router;
2) 게시글 조회 API
게시글 목록 조회 API
// src/routes/posts.router.js
/ 게시글 목록 조회 API /
router.get('/posts', async (req, res, next) => {
const posts = await prisma.posts.findMany({
select: {
postId: true,
title: true,
createdAt: true,
updatedAt: true,
},
orderBy: {
createdAt: 'desc', // 게시글을 최신순으로 정렬합니다.
},
});
return res.status(200).json({ data: posts });
});
게시글 상세 조회 API
// src/routes/posts.router.js
/ 게시글 상세 조회 API /
router.get('/posts/:postId', async (req, res, next) => {
const { postId } = req.params;
const post = await prisma.posts.findFirst({
where: {
postId: +postId,
},
select: {
postId: true,
title: true,
content: true,
createdAt: true,
updatedAt: true,
},
});
return res.status(200).json({ data: post });
});
👉 댓글 기능은 게시글 기능과 부모-자식 간의 관계로 구성됩니다.
일반적인 사이트를 생각해보더라도, 게시글과 별도로 댓글이 존재하는 사이트는 많이 존재하지 않을 것 입니다. 이는 댓글이 그 자체로 독립적으로 존재하기보다는 특정 게시글에 대한 하위 개념으로 존재하기 떄문입니다.
그렇기 때문에, 댓글 기능을 구현하기 위해서는 거의 필수적으로 게시글이 필요하게 될 것입니다. 댓글은 특히 게시글에 종속되므로, 댓글 API는 게시글 API의 하위에 구현되어야 합니다.
즉, 댓글 API의 URL은 게시글 API의 URL을 기반으로 작성되어야 합니다. 예를 들어, 댓글을 생성하는 API의 경우 POST /api/posts/**:postId**/comments와 같이 작성할 수 있습니다. 이렇게 작성하면, URL만 보더라도 “특정 게시글 내부에 댓글을 작성하겠다.”라는 것을 명확하게 이해할 수 있을 것입니다.
댓글 생성 API
💡 댓글 생성 API 비즈니스 로직
postId를 Path Parameters로 전달받습니다.content를 body로 전달받습니다.CommentsRouter를 등록한 app.js
// src/app.js
import express from 'express';
import cookieParser from 'cookie-parser';
import LogMiddleware from './middlewares/log.middleware.js';
import ErrorHandlingMiddleware from './middlewares/error-handling.middleware.js';
import UsersRouter from './routes/users.router.js';
import PostsRouter from './routes/posts.router.js';
import CommentsRouter from './routes/comments.router.js';
const app = express();
const PORT = 3018;
app.use(LogMiddleware);
app.use(express.json());
app.use(cookieParser());
app.use('/api', [UsersRouter, PostsRouter, CommentsRouter]);
app.use(ErrorHandlingMiddleware);
app.listen(PORT, () => {
console.log(PORT, '포트로 서버가 열렸어요!');
});
댓글 생성 API
// src/routes/comments.router.js
import express from 'express';
import authMiddleware from '../middlewares/auth.middleware.js';
import { prisma } from '../utils/prisma/index.js';
const router = express.Router();
/ 댓글 생성 API /
router.post(
'/posts/:postId/comments',
authMiddleware,
async (req, res, next) => {
const { postId } = req.params;
const { userId } = req.user;
const { content } = req.body;
const post = await prisma.posts.findFirst({
where: {
postId: +postId,
},
});
if (!post)
return res.status(404).json({ message: '게시글이 존재하지 않습니다.' });
const comment = await prisma.comments.create({
data: {
UserId: +userId, // 댓글 작성자 ID
PostId: +postId, // 댓글 작성 게시글 ID
content: content,
},
});
return res.status(201).json({ data: comment });
},
);
export default router;
댓글 조회 API
// src/routes/comments.router.js
/ 댓글 조회 API /
router.get('/posts/:postId/comments', async (req, res, next) => {
const { postId } = req.params;
const post = await prisma.posts.findFirst({
where: {
postId: +postId,
},
});
if (!post)
return res.status(404).json({ message: '게시글이 존재하지 않습니다.' });
const comments = await prisma.comments.findMany({
where: {
PostId: +postId,
},
orderBy: {
createdAt: 'desc',
},
});
return res.status(200).json({ data: comments });
});
💪 ‘역할과 책임’에 대한 이야기는 프로그래밍을 하면서 자주 나오는 주제입니다.
하나의 코드가 많은 역할과 책임을 가질 때 발생하는 문제와 하나의 코드가 단 하나의 역할과 책임만 가질 때의 장점에 대한 고민은 많은 개발자들이 아직까지도 고민하고 풀고자하는 문제 중 하나입니다.
이러한 고민을 돕기 위해 “클린 코드(Clean Code)”와 리팩토링(Refactoring)이라는 책이 오랜시간 사랑받아 왔고, 아직까지도 많은 인기를 가지고 있습니다.