Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 58 additions & 23 deletions express/app.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,64 @@
// express 모듈을 불러옵니다.
const express = require('express');
// express 애플리케이션을 생성합니다.
// app.js
import express from 'express';
import session from 'express-session';

const app = express();
// 웹 서버가 사용할 포트 번호를 정의합니다.
const port = 3000;

app.use(express.json());
app.use(express.urlencoded({extended: true}));

/**
* 루트 경로('/')에 대한 GET 요청을 처리
* 요청이 오면 'Hello World!' 문자열을 응답
*/
app.get('/', (request, response) => {
// 응답.보내다('Hello World!');
response.send('Hello World!');

app.use(express.json()); // JSON 요청 본문을 파싱하기 위해

app.use(
session({
secret: 'yourSecretKey',
saveUninitialized: true,
resave: false,
cookie: {
maxAge: 24 * 60 * 60 * 1000, // 쿠키 유효 시간 (예: 1일)
},
}),
);

// 로그인 API
app.post('/users/login', (request, response) => {
const { email, password } = request.body;

if (!email || !password) {
return response.status(400).json({
status: 400,
message: '이메일 또는 패스워드를 제공해주세요.',
data: null,
});
}

request.session.email = email;
return response.status(200).json({
status: 200,
message: `환영합니다, ${email}님!`,
data: {
sessionID: request.sessionID,
},
});
});

app.post('/users', (request, response) => {
const name = request.body.name;
const email = request.body.email;
// 로그아웃 API
app.get('/users/logout', (request, response) => {
request.session.destroy(error => {
if (error) {
return response.status(500).json({
status: 500,
message: '로그아웃 중 문제가 발생했습니다.',
data: null,
});
}

return response.send(`${name}, ${email}`);
return response.status(200).json({
status: 200,
message: '성공적으로 로그아웃되었습니다.',
data: null,
});
});
});

app.listen(port, () => {
console.log(`Example app listening on port ${port}`);
});
const PORT = 3000;
app.listen(PORT, () => {
console.log(`서버가 ${PORT}번 포트에서 실행중입니다.`);
});
100 changes: 100 additions & 0 deletions express/controller/commentController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// Dummy data, JSON 구조
const comments = [
{
comment_id: 1,
comment_content: '좋은 글이네요.',
post_id: 1,
user_id: 2,
nickname: '밥',
created_at: '2024-12-10T10:00:00Z',
updated_at: '2024-12-10T10:00:00Z',
deleted_at: null,
},
{
comment_id: 2,
comment_content: '감사합니다!',
post_id: 1,
user_id: 1,
nickname: '앨리스',
created_at: '2024-12-10T10:05:00Z',
updated_at: '2024-12-10T10:05:00Z',
deleted_at: null,
},
];

/**
* 댓글 조회
* 댓글 작성
* 댓글 수정
* 댓글 삭제
*/

// 댓글 조회
exports.getComments = (request, response) => {
const postId = parseInt(request.params.post_id, 10);
const filteredComments = comments.filter(comment => comment.post_id === postId && !comment.deleted_at);
return response.status(200).json({ data: filteredComments });
};

// 댓글 작성
exports.writeComment = (request, response) => {
const postId = parseInt(request.params.post_id, 10);
const userId = parseInt(request.headers.userid, 10);
const { commentContent } = request.body;

const newComment = {
comment_id: comments.length + 1,
comment_content: commentContent,
post_id: postId,
user_id: userId,
nickname: '사용자',
created_at: new Date().toISOString(),
updated_at: new Date().toISOString(),
deleted_at: null,
};

comments.push(newComment);
return response.status(201).json({ data: newComment });
};

// 댓글 수정
exports.updateComment = (request, response) => {
const postId = parseInt(request.params.post_id, 10);
const commentId = parseInt(request.params.comment_id, 10);
const { commentContent } = request.body;

const comment = comments.find(comment =>
comment.post_id === postId &&
comment.comment_id === commentId &&
!comment.deleted_at
);

if (!comment) {
return response.status(404).json({ data: null });
}

comment.comment_content = commentContent;
comment.updated_at = new Date().toISOString();

return response.status(200).json({ data: comment });
};

// 댓글 삭제
exports.softDeleteComment = (request, response) => {
const postId = parseInt(request.params.post_id, 10);
const commentId = parseInt(request.params.comment_id, 10);

const comment = comments.find(comment =>
comment.post_id === postId &&
comment.comment_id === commentId &&
!comment.deleted_at
);

if (!comment) {
return response.status(404).json({ data: null });
}

comment.deleted_at = new Date().toISOString();

return response.status(200).json({ data: null });
};
208 changes: 208 additions & 0 deletions express/controller/postController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
const postModel = require('../model/postModel.js');
const {
STATUS_CODE,
STATUS_MESSAGE
} = require('../util/constant/httpStatusCode');

/**
* 게시글 작성
* 게시글 목록 조회
* 게시글 상세 조회
* 게시글 수정
* 게시글 삭제
*/

// 게시글 작성
exports.writePost = async (request, response, next) => {
const { userid: userId } = request.headers;
const { postTitle, postContent, attachFilePath } = request.body;

try {
if (!postTitle) {
const error = new Error(STATUS_MESSAGE.INVALID_POST_TITLE);
error.status = STATUS_CODE.BAD_REQUEST;
throw error;
}

if (postTitle.length > 26) {
const error = new Error(STATUS_MESSAGE.INVALID_POST_TITLE_LENGTH);
error.status = STATUS_CODE.BAD_REQUEST;
throw error;
}

if (!postContent) {
const error = new Error(STATUS_MESSAGE.INVALID_POST_CONTENT);
error.status = STATUS_CODE.BAD_REQUEST;
throw error;
}

if (postContent.length > 1500) {
const error = new Error(STATUS_MESSAGE.INVALID_POST_CONTENT_LENGHT);
error.status = STATUS_CODE.BAD_REQUEST;
throw error;
}

const requestData = {
userId,
postTitle,
postContent,
attachFilePath: attachFilePath || null,
};
const responseData = await postModel.writePost(requestData);

if (responseData === STATUS_MESSAGE.NOT_FOUND_USER) {
const error = new Error(STATUS_MESSAGE.NOT_FOUND_USER);
error.status = STATUS_CODE.NOT_FOUND;
throw error;
}

if (!responseData) {
const error = new Error(STATUS_MESSAGE.WRITE_POST_FAILED);
error.status = STATUS_CODE.INTERNAL_SERVER_ERROR;
throw error;
}

return response.status(STATUS_CODE.CREATED).json({
message: STATUS_MESSAGE.WRITE_POST_SUCCESS,
data: responseData,
});
} catch (error) {
next(error);
}
};

// 게시글 목록 조회
exports.getPosts = async (request, response, next) => {
const { offset, limit } = request.query;

try {
if (!offset || !limit) {
const error = new Error(STATUS_MESSAGE.INVALID_OFFSET_OR_LIMIT);
error.status = STATUS_CODE.BAD_REQUEST;
throw error;
}
const requestData = {
offset: parseInt(offset, 10),
limit: parseInt(limit, 10),
};
const responseData = await postModel.getPosts(requestData);

if (!responseData || responseData.length === 0) {
const error = new Error(STATUS_MESSAGE.NOT_A_SINGLE_POST);
error.status = STATUS_CODE.NOT_FOUND;
throw error;
}

return response.status(STATUS_CODE.OK).json({
message: STATUS_MESSAGE.GET_POSTS_SUCCESS,
data: responseData,
});
} catch (error) {
next(error);
}
};

// 게시글 상세 조회
exports.getPost = async (request, response, next) => {
const { post_id: postId } = request.params;

try {
if (!postId) {
const error = new Error(STATUS_MESSAGE.INVALID_POST_ID);
error.status = STATUS_CODE.BAD_REQUEST;
throw error;
}

const requestData = {
postId
};
const responseData = await postModel.getPost(requestData, response);

if (!responseData) {
const error = new Error(STATUS_MESSAGE.NOT_A_SINGLE_POST);
error.status = STATUS_CODE.NOT_FOUND;
throw error;
}

return response.status(STATUS_CODE.OK).json({
message: null,
data: responseData
});
} catch (error) {
return next(error);
}
};

// 게시글 수정
exports.updatePost = async (request, response, next) => {
const { post_id: postId } = request.params;
const { userid: userId } = request.headers;
const { postTitle, postContent, attachFilePath } = request.body;

try {
if (!postId) {
const error = new Error(STATUS_MESSAGE.INVALID_POST_ID);
error.status = STATUS_CODE.BAD_REQUEST;
throw error;
}

if (postTitle.length > 26) {
const error = new Error(STATUS_MESSAGE.INVALID_POST_TITLE_LENGTH);
error.status = STATUS_CODE.BAD_REQUEST;
throw error;
}

const requestData = {
postId,
userId,
postTitle,
postContent,
attachFilePath: attachFilePath || null,
};
const responseData = await postModel.updatePost(requestData);

if (!responseData) {
const error = new Error(STATUS_MESSAGE.NOT_A_SINGLE_POST);
error.status = STATUS_CODE.NOT_FOUND;
throw error;
}

return response.status(STATUS_CODE.OK).json({
message: STATUS_MESSAGE.UPDATE_POST_SUCCESS,
data: responseData,
});
} catch (error) {
next(error);
}
};

// 게시글 삭제
exports.softDeletePost = async (request, response, next) => {
const { post_id: postId } = request.params;

try {
if (!postId) {
const error = new Error(STATUS_MESSAGE.INVALID_POST_ID);
error.status = STATUS_CODE.BAD_REQUEST;
throw error;
}

const requestData = {
postId
};
const results = await postModel.softDeletePost(requestData);

if (!results) {
const error = new Error(STATUS_MESSAGE.NOT_A_SINGLE_POST);
error.status = STATUS_CODE.NOT_FOUND;
throw error;
}

return response.status(STATUS_CODE.OK).json({
message: STATUS_MESSAGE.DELETE_POST_SUCCESS,
data: null
});
} catch (error) {
return next(error);
}
};
Loading