지난번에 만든 게시판에 crud 기능을 구현해 게시글을 추가하고, 수정하고, 삭제할 수 있게 만들어 보았다.
라우트를 위와 같이 추가해서 글쓰기/수정/삭제마다 이동할 수 있게 한다.
글쓰기
export default async function Write() {
return (
<div className="p-20">
<h4>글 쓰기</h4>
<form action="/api/post/new" method="POST">
<input name="title" placeholder="글제목" />
<input name="content" placeholder="글내용" />
<button type="submit">전송</button>
</form>
</div>
);
}
/write 경로로 가면 위와 같이 form에 글을 쓰고 action 속성에 지정해 준 경로로 POST 요청을 보내도록 했다.
요청을 받을 서버도 구현해야 하는데, 글 추가를 했을 때 데이터베이스에 바로 접근하도록 하면 위험하기 때문에 반드시 서버를 거쳐서 데이터베이스의 데이터를 추가하거나 변경/삭제할 수 있게 만들어야 한다.
서버를 위한 경로를 설정해주고
import { connectDB } from "@/util/database";
export default async function handler(req, res) {
if (req.method == "POST") {
const db = (await connectDB).db("forum");
let result = await db.collection("post").insertOne(req.body);
res.redirect(302, "/list");
}
}
위와 같이 요청을 받아 데이터베이스에 요청을 보낸다.
이렇게 입력하면..
한층 더 귀여워진... 결과물🥲
수정/삭제 기능 구현을 위해 아이콘도 달아 보았다.
수정하기
import { connectDB } from "@/util/database";
import { ObjectId } from "mongodb";
export default async function Edit(props) {
let db = (await connectDB).db("forum");
let result = await db
.collection("post")
.findOne({ _id: new ObjectId(props.params.postId) });
return (
<div className="p-20">
<h4>수정하기</h4>
<form action="/api/post/edit" method="POST">
<input name="title" defaultValue={result.title} />
<input name="content" defaultValue={result.content} />
<input
className="idField"
name="_id"
defaultValue={result._id.toString()}
/>
<button type="submit">전송</button>
</form>
</div>
);
수정 기능은 글쓰기 기능을 조금 변형하기만 하면 된다. 똑같이 제목과 내용이 있는 form에 데이터베이스로부터 해당 아이디의 글을 로드해서 각각의 필드에 미리 넣어주는 식이다. defaultValue 속성을 사용해서 내용을 미리 지정할 수 있다.
게시글 페이지를 만들 때와 마찬가지로 props로 url에 접근한다.
import { connectDB } from "@/util/database";
import { ObjectId } from "mongodb";
export default async function handler(req, res) {
if (req.method == "POST") {
const db = (await connectDB).db("forum");
let result = await db
.collection("post")
.updateOne(
{ _id: new ObjectId(req.body._id) },
{ $set: { title: req.body.title, content: req.body.content } }
);
res.redirect(302, "/list");
}
}
서버에서는 위와 같이 글 id를 가지고 해당하는 글을 찾아서 새로운 글로 업데이트한다.
삭제하기
삭제 요청은 ajax 요청을 통해 서버로 보내 보자.
글 리스트 표시하는 부분을 따로 분리해 별도 컴포넌트화하고,'use client'를 통해 클라이언트 컴포넌트로 바꿔 준다.
삭제 버튼을 누르면 쿼리 파라미터에 글의 id를 담아서 ajax 요청을 보낸다.
서버단에서 쿼리 파라미터에 담긴 id를 확인하고 데이터베이스에서 해당 글을 찾아 삭제하게 처리하면 된다.
"use client";
import Link from "next/link";
import axios from "axios";
export default function ListItem({ result }) {
return (
<div>
{result.map((post) => {
return (
<div className="list-item" id={post._id}>
(중략)
<button
className="icon"
onClick={() => {
axios.delete(`/api/delete/${post._id}`);
}}
>
🗑️
</button>
</div>
);
}
서버 경로를 아래와 같이 설정하면 쿼리 파라미터 값에 따라 동적으로 요청을 받는 서버 주소를 만들 수 있다.
import { connectDB } from "@/util/database";
import { ObjectId } from "mongodb";
export default async function handler(req, res) {
if (req.method == "DELETE") {
const db = (await connectDB).db("forum");
let result = await db
.collection("post")
.deleteOne({ _id: new ObjectId(req.query.postId) });
res.redirect(302, "/list");
}
}
서버에서 데이터베이스에 요청을 보내 삭제 처리하는 방식은 위와 같다.
이렇게 Next.js를 이용해 글을 추가/수정/삭제하는 간단한 CRUD 구현을 해보았다!
'Next.js' 카테고리의 다른 글
[Next.js] 라우팅 이론과 실습 (2) | 2023.05.08 |
---|---|
[Next.js] Next.js 장단점과 특징 (2) | 2023.05.05 |