그룹채팅 - Part1 채팅방 생성
ㆍProject Diary/Next.js + Prisma + MariaDB (KiloFlow)
새로운 그룹 채팅방을 만드는 방법에 대해 설명하겠습니다.
데이터베이스 스키마
chatrooms 테이블
model chatrooms {
id Int @id @default(autoincrement())
name String
tags String
image_url String?
max_members Int
created_at DateTime @default(now())
updated_at DateTime @updatedAt
owner_id Int
user users @relation(fields: [owner_id], references: [user_id], onDelete: Cascade, onUpdate: Cascade)
@@index([id])
}
- 채팅방의 이름(name), 태그(tags), 이미지 URL(image_url), 최대 멤버 수(max_members), 생성 시간(created_at), 업데이트 시간(updated_at), 방장 ID(owner_id)를 저장합니다.
- owner_id는 users 테이블과 관계를 맺고 있습니다.
프론트엔드
채팅방생성 컴포넌트
import { useState } from "react";
const CreateChatroom = () => {
// 상태 변수를 선언합니다.
const [name, setName] = useState(""); // 채팅방 이름을 관리하는 상태 변수
const [tags, setTags] = useState(""); // 채팅방 태그를 관리하는 상태 변수
const [maxMembers, setMaxMembers] = useState(10); // 최대 멤버 수를 관리하는 상태 변수
const [image, setImage] = useState(null); // 이미지 파일을 관리하는 상태 변수
// 폼 제출 시 호출되는 함수입니다.
const handleSubmit = async (e) => {
e.preventDefault(); // 기본 폼 제출 동작을 막습니다.
// 폼 데이터를 생성합니다.
const formData = new FormData();
formData.append("name", name); // 이름을 폼 데이터에 추가합니다.
formData.append("tags", tags); // 태그를 폼 데이터에 추가합니다.
formData.append("max_members", maxMembers); // 최대 멤버 수를 폼 데이터에 추가합니다.
formData.append("image", image); // 이미지를 폼 데이터에 추가합니다.
// 서버에 POST 요청을 보냅니다.
const res = await fetch("/api/chatrooms", {
method: "POST",
body: formData, // 폼 데이터를 요청 본문에 포함합니다.
});
// 응답이 성공적인 경우
if (res.ok) {
const data = await res.json(); // 응답 데이터를 JSON으로 변환합니다.
console.log("Chatroom created:", data); // 생성된 채팅방 정보를 콘솔에 출력합니다.
} else {
// 응답이 실패한 경우
console.error("Failed to create chatroom"); // 에러 메시지를 콘솔에 출력합니다.
}
};
return (
<form onSubmit={handleSubmit}> {/* 폼 제출 시 handleSubmit 함수를 호출합니다. */}
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)} // 입력값이 변경될 때 name 상태를 업데이트합니다.
placeholder="Chatroom Name" // 입력 필드의 자리 표시자입니다.
/>
<input
type="text"
value={tags}
onChange={(e) => setTags(e.target.value)} // 입력값이 변경될 때 tags 상태를 업데이트합니다.
placeholder="Tags" // 입력 필드의 자리 표시자입니다.
/>
<input
type="number"
value={maxMembers}
onChange={(e) => setMaxMembers(e.target.value)} // 입력값이 변경될 때 maxMembers 상태를 업데이트합니다.
placeholder="Max Members" // 입력 필드의 자리 표시자입니다.
/>
<input
type="file"
onChange={(e) => setImage(e.target.files[0])} // 파일이 선택될 때 image 상태를 업데이트합니다.
/>
<button type="submit">Create Chatroom</button> {/* 폼 제출 버튼입니다. */}
</form>
);
};
export default CreateChatroom;
(설명 : 주석참고)
<백엔드>
1. Multer 실행
const runMiddleware = (
req: NextApiRequest,
res: NextApiResponse,
fn: Function
) => {
return new Promise((resolve, reject) => {
fn(req, res, (result: any) => {
if (result instanceof Error) {
return reject(result); // 미들웨어 실행 중 오류가 발생하면 reject하여 에러를 처리합니다.
}
return resolve(result); // 미들웨어 함수의 실행이 완료될 때까지 기다리게 합니다.
});
});
};
(설명 : 주석참고)
2. 채팅방 생성 핸들러
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
if (req.method === "POST") {
try {
// Multer 미들웨어 실행
await runMiddleware(req, res, upload.single("image"));
// 요청 본문에서 필요한 데이터를 추출합니다.
const { name, tags, max_members, owner_id, image } = req.body;
// 이미지 파일이 업로드된 경우 해당 파일의 경로를 설정합니다.
const imageUrl = req.file ? `/uploads/${req.file.filename}` : image;
// Prisma Client를 사용하여 chatrooms 테이블에 새로운 채팅방 레코드를 생성합니다.
const chatroom = await prisma.chatrooms.create({
data: {
name, // 채팅방 이름 설정
tags, // 채팅방 태그 설정
image_url: imageUrl, // 이미지 URL 설정
max_members: Number(max_members), // 최대 멤버 수 설정
owner_id: Number(owner_id), // 방장 ID 설정
},
});
// 채팅방 생성이 성공적으로 완료되면 201 상태 코드와 생성된 채팅방 데이터를 클라이언트에 응답으로 보냅니다.
res.status(201).json(chatroom);
} catch (error) {
console.log(error);
// 예외가 발생할 경우 에러를 로그로 출력하고, 클라이언트에 500 상태 코드와 함께 에러 메시지를 응답으로 보냅니다.
res.status(500).json({ message: "Internal server error" });
}
} else {
// POST 요청 이외의 요청이 들어올 경우, 허용된 메서드를 명시하고 405 상태 코드와 함께 응답을 종료합니다.
res.setHeader("Allow", ["POST"]);
res.status(405).end(`Method ${req.method} Not Allowed`);
}
}
(설명 : 주석참고)