1. ๊ฒ์๋ฌผ ์์
- ๊ฒ์๋ฌผ ๋ณธ๋ฌธ์ ์์ ํ๊ฑฐ๋, ์ฒจ๋ถ๋ ์ด๋ฏธ์ง ์ญ์ .
1) ์ฝ๋
const express = require("express");
const router = express.Router();
router.use(express.json());
const { Post } = require("../../models/Post");
const { auth } = require("../auth");
const cookieParser = require("cookie-parser");
router.use(cookieParser());
const multer = require("multer");
const storage = multer.memoryStorage();
const upload = multer({ storage }).array("images", 10); // ์ต๋ 10์ฅ์ ์ด๋ฏธ์ง ์
๋ก๋
const s3 = require("../../config/s3"); // S3 ํด๋ผ์ด์ธํธ ๊ฐ์ ธ์ค๊ธฐ
const { DeleteObjectCommand } = require("@aws-sdk/client-s3");
// ๊ฒ์๋ฌผ ์์
router.patch("/:id", auth, upload, async (req, res) => {
const { id } = req.params;
const { text, imagesToDelete } = req.body; // ์์ ํ ํ
์คํธ, ์ญ์ ํ ์ด๋ฏธ์ง
try {
const post = await Post.findById(id);
if (!post)
return res.status(404).json({ message: "๊ฒ์๋ฌผ์ ์ฐพ์ ์ ์์ต๋๋ค." });
if (post.user.toString() !== req.user._id.toString())
return res.status(403).json({ message: "๊ถํ์ด ์์ต๋๋ค." });
// ๋ณธ๋ฌธ ๋ด์ฉ ์์
if (text) {
post.text = text;
}
// ์ด๋ฏธ์ง ์ญ์ ๋ก์ง
if (imagesToDelete && post.images.length > 1) {
for (const imageUrl of imagesToDelete) {
// S3์์ ์ด๋ฏธ์ง ์ญ์
const key = imageUrl.split("/").pop(); // URL์์ ํ์ผ ์ด๋ฆ ์ถ์ถ
const bucket = "post-jae";
console.log("Deleting image:", imageUrl);
console.log("Key for S3:", key);
const deleteParams = {
Bucket: bucket,
Key: key,
};
await s3.send(new DeleteObjectCommand(deleteParams));
// DB์์ ํด๋น ์ด๋ฏธ์ง URL ์ญ์
post.images = post.images.filter((img) => img !== imageUrl);
}
} else if (imagesToDelete && post.images.length <= 1) {
return res
.status(400)
.json({ message: "์ด๋ฏธ์ง๊ฐ 1์ฅ ์ด์ ๋จ์์ผ ํฉ๋๋ค." });
}
await post.save(); // ์์ ๋ ๊ฒ์๋ฌผ ์ ์ฅ
return res.status(200).json({ message: "๊ฒ์๋ฌผ์ด ์์ ๋์์ต๋๋ค.", post });
} catch (err) {
return res.status(500).json({
message: "๊ฒ์๋ฌผ ์์ ์ค ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค.",
error: err.message,
});
}
});
module.exports = router;
2) ๊ธฐ๋ฅ ์ค๋ช
- ๋ผ์ฐํธ ์ค์ : router.patch("/:id", auth, upload, async (req, res) => {...})๋ ํน์ ๊ฒ์๋ฌผ์ ์์ ํ๊ธฐ ์ํ API ์๋ํฌ์ธํธ.
- :id๋ ์์ ํ ๊ฒ์๋ฌผ์ ID๋ฅผ ๋ํ๋ ๋๋ค.
- ๊ฒ์๋ฌผ ๊ฒ์: const post = await Post.findById(id);๋ฅผ ์ฌ์ฉํ์ฌ MongoDB์์ ํด๋น ID์ ๊ฒ์๋ฌผ์ ๊ฒ์.
- ๊ฒ์๋ฌผ์ด ์กด์ฌํ์ง ์์ ๊ฒฝ์ฐ 404 ์ํ ์ฝ๋๋ฅผ ๋ฐํ.
- ์ฌ์ฉ์ ๊ถํ ํ์ธ: ์ฌ์ฉ์๊ฐ ํด๋น ๊ฒ์๋ฌผ์ ์์ฑ์์ธ์ง ํ์ธํ๊ธฐ ์ํด, if (post.user.toString() !== req.user._id.toString())๋ฅผ ์ฌ์ฉ.
- ๊ถํ์ด ์์ผ๋ฉด 403 ์ํ ์ฝ๋๋ฅผ ๋ฐํ.
- ๋ณธ๋ฌธ ๋ด์ฉ ์์ : ์ฌ์ฉ์๊ฐ ์ ๋ ฅํ ์๋ก์ด ํ ์คํธ๊ฐ ์กด์ฌํ๋ ๊ฒฝ์ฐ post.text = text;๋ฅผ ํตํด ๊ฒ์๋ฌผ์ ๋ณธ๋ฌธ ๋ด์ฉ์ ์์ .
- ์ด๋ฏธ์ง ์ญ์ ๋ก์ง: if (imagesToDelete && post.images.length > 1) ์กฐ๊ฑด๋ฌธ์ ํตํด ์ญ์ ํ ์ด๋ฏธ์ง๊ฐ ์๊ณ , ๊ฒ์๋ฌผ์ ๋จ์ ์๋ ์ด๋ฏธ์ง๊ฐ 1์ฅ ์ด์์ผ ๊ฒฝ์ฐ์๋ง ์ญ์ ๋ฅผ ์งํ.
- ์ญ์ ํ ์ด๋ฏธ์ง๋ S3์์ ์ญ์ ๋๊ณ , ๋ฐ์ดํฐ๋ฒ ์ด์ค์์๋ ํด๋น ์ด๋ฏธ์ง URL์ด ์ ๊ฑฐ๋จ.
- ์๋ต ์ฒ๋ฆฌ: ์์ ์ด ์๋ฃ๋๋ฉด 200 ์ํ ์ฝ๋์ ํจ๊ป ์์ ๋ ๊ฒ์๋ฌผ ์ ๋ณด๋ฅผ ๋ฐํ.
- ์ค๋ฅ๊ฐ ๋ฐ์ํ ๊ฒฝ์ฐ 500 ์ํ ์ฝ๋์ ํจ๊ป ์ค๋ฅ ๋ฉ์์ง๋ฅผ ๋ฐํ.
2. ๊ฒ์๋ฌผ ์ญ์
- ์ฌ์ฉ์๊ฐ ๊ฒ์๋ฌผ์ ์ญ์ ํ ๋, ํด๋น ๊ฒ์๋ฌผ์ด ์กด์ฌํ๋์ง ํ์ธํ๊ณ , ์ฌ์ฉ์ ๊ถํ์ ์ฒดํฌํ ํ S3์ ์ ์ฅ๋ ์ด๋ฏธ์ง๋ ํจ๊ป ์ญ์ .
1) ์ฝ๋
const express = require("express");
const router = express.Router();
router.use(express.json());
const { Post } = require("../../models/Post");
const { auth } = require("../auth");
const cookieParser = require("cookie-parser");
router.use(cookieParser());
const { DeleteObjectCommand } = require("@aws-sdk/client-s3");
const s3 = require("../../config/s3");
// ๊ฒ์๋ฌผ ์ญ์
router.delete("/:id", auth, async (req, res) => {
const { id } = req.params;
try {
const post = await Post.findById(id);
if (!post)
return res.status(404).json({ message: "๊ฒ์๋ฌผ์ ์ฐพ์ ์ ์์ต๋๋ค." });
if (post.user.toString() !== req.user._id.toString())
return res.status(403).json({ message: "๊ถํ์ด ์์ต๋๋ค." });
// S3์์ ์ด๋ฏธ์ง ์ญ์
for (let imageUrl of post.images) {
const key = imageUrl.split(".com/")[1]; // URL์์ ํค ์ถ์ถ
const deleteParams = {
Bucket: "post-jae",
Key: key,
};
await s3.send(new DeleteObjectCommand(deleteParams)); // S3์์ ์ด๋ฏธ์ง ์ญ์
}
await Post.findByIdAndDelete(id); // DB์์ ๊ฒ์๋ฌผ ์ญ์
return res.status(200).json({ message: "๊ฒ์๋ฌผ์ด ์ญ์ ๋์์ต๋๋ค." });
} catch (err) {
return res.status(500).json({
message: "๊ฒ์๋ฌผ ์ญ์ ์ค ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค.",
error: err.message,
});
}
});
module.exports = router;
2) ๊ธฐ๋ฅ ์ค๋ช
- ๋ผ์ฐํธ ์ค์ : router.delete("/:id", auth, async (req, res) => {...})๋ ํน์ ๊ฒ์๋ฌผ์ ์ญ์ ํ๊ธฐ ์ํ API ์๋ํฌ์ธํธ์.
- :id๋ ์ญ์ ํ ๊ฒ์๋ฌผ์ ID.
- ๊ฒ์๋ฌผ ๊ฒ์: const post = await Post.findById(id);๋ฅผ ์ฌ์ฉํ์ฌ MongoDB์์ ํด๋น ID์ ๊ฒ์๋ฌผ์ ๊ฒ์.
- ๊ฒ์๋ฌผ์ด ์กด์ฌํ์ง ์์ ๊ฒฝ์ฐ 404 ์ํ ์ฝ๋๋ฅผ ๋ฐํ.
- ์ฌ์ฉ์ ๊ถํ ํ์ธ: ์ฌ์ฉ์๊ฐ ํด๋น ๊ฒ์๋ฌผ์ ์์ฑ์์ธ์ง ํ์ธํ๊ธฐ ์ํด, if (post.user.toString() !== req.user._id.toString())๋ฅผ ์ฌ์ฉ.
- ๊ถํ์ด ์์ผ๋ฉด 403 ์ํ ์ฝ๋๋ฅผ ๋ฐํ.
- S3์์ ์ด๋ฏธ์ง ์ญ์ : ๊ฒ์๋ฌผ์ด ์กด์ฌํ๊ณ ์ฌ์ฉ์๊ฐ ๊ถํ์ด ํ์ธ๋๋ฉด, for (let imageUrl of post.images) {...}๋ฅผ ์ฌ์ฉํ์ฌ ๊ฒ์๋ฌผ์ ์ฒจ๋ถ๋ ๋ชจ๋ ์ด๋ฏธ์ง URL์ ๋ฐ๋ณตํ๋ฉฐ S3์์ ์ญ์ .
- ์ด๋ฏธ์ง ํค๋ URL์์ ์ถ์ถํ์ฌ DeleteObjectCommand๋ฅผ ์ฌ์ฉํ์ฌ ์ญ์ .
- ๊ฒ์๋ฌผ ์ญ์ : ๋ชจ๋ ์ด๋ฏธ์ง๊ฐ ์ญ์ ๋ ํ await Post.findByIdAndDelete(id);๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์๋ ๊ฒ์๋ฌผ์ ์ญ์ .
- ์๋ต ์ฒ๋ฆฌ: ์ญ์ ๊ฐ ์๋ฃ๋๋ฉด 200 ์ํ ์ฝ๋์ ํจ๊ป ์ฑ๊ณต ๋ฉ์์ง๋ฅผ ๋ฐํ.
- ์ค๋ฅ ๋ฐ์ ์ 500 ์ํ ์ฝ๋์ ํจ๊ป ์ค๋ฅ ๋ฉ์์ง๋ฅผ ๋ฐํ.
3. ๊ฒฐ๊ณผ ๐
1) ๊ฒ์๋ฌผ ์์
- ๊ฒ์๊ธ ์์
- ์ฌ์ง ์ญ์
- ๊ฒ์๋ฌผ์ ๋จ์ ์๋ ์ด๋ฏธ์ง๊ฐ 1์ฅ ์ด์์ผ ๊ฒฝ์ฐ์๋ง ์ญ์ ๋ฅผ ์งํ
2) ๊ฒ์๋ฌผ ์ญ์