Backend ๐Ÿ“š/Node.js

[Node]Instagram Clone - 6. MongoDB Populate์„ ์‚ฌ์šฉํ•œ ๊ฒŒ์‹œ๋ฌผ ์กฐํšŒ API

leejaejae 2024. 11. 3. 08:24
  • ์ด๋ฒˆ ํฌ์ŠคํŠธ์—์„œ๋Š” MongoDB์˜ populate ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฒŒ์‹œ๋ฌผ ์กฐํšŒ ์‹œ ๋Œ“๊ธ€๋„ ํ•จ๊ป˜ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ฒ ์Œ!

1. ์Šคํ‚ค๋งˆ ์„ค๊ณ„

  • ์šฐ์„ , ๊ฒŒ์‹œ๋ฌผ(Post)๊ณผ ๋Œ“๊ธ€(Comment)์˜ ์Šคํ‚ค๋งˆ๋ฅผ ์ •์˜ํ•ด์•ผ ํ•จ. 

1) ๊ฒŒ์‹œ๋ฌผ ์Šคํ‚ค๋งˆ

// post.js

const mongoose = require("mongoose");

const postSchema = new mongoose.Schema({
  user: {
    type: mongoose.Schema.Types.ObjectId,
    ref: "User",
    required: true,
  },
  text: {
    type: String,
    required: false,
    trim: true,
  },
  images: [
    {
      type: String,
      required: true,
    },
  ],
  createdAt: {
    type: Date,
    default: Date.now,
  },
  comments: [{ // ๋Œ“๊ธ€์„ ์œ„ํ•œ ํ•„๋“œ ์ถ”๊ฐ€
    type: mongoose.Schema.Types.ObjectId,
    ref: "Comment",
  }],
});

const Post = mongoose.model("Post", postSchema);
module.exports = { Post };


2) ๋Œ“๊ธ€ ์Šคํ‚ค๋งˆ

// comment.js

const mongoose = require("mongoose");

const commentSchema = new mongoose.Schema({
  post: {
    type: mongoose.Schema.Types.ObjectId,
    ref: "Post",
    required: true,
  },
  user: {
    type: mongoose.Schema.Types.ObjectId,
    ref: "User",
    required: true,
  },
  text: {
    type: String,
    required: true,
  },
  createdAt: {
    type: Date,
    default: Date.now,
  },
});

const Comment = mongoose.model("Comment", commentSchema);
module.exports = { Comment };

 

2. ๊ฒŒ์‹œ๋ฌผ ์กฐํšŒ ๊ธฐ๋Šฅ ๊ตฌํ˜„

  • ๊ฒŒ์‹œ๋ฌผ ์กฐํšŒ API๋ฅผ ๊ตฌํ˜„ํ•˜์—ฌ, ํŠน์ • ๊ฒŒ์‹œ๋ฌผ๊ณผ ๊ทธ ๊ฒŒ์‹œ๋ฌผ์— ๋‹ฌ๋ฆฐ ๋Œ“๊ธ€์„ ํ•จ๊ป˜ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€.
  • ์ด๋ฅผ ์œ„ํ•ด populate ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ๊ฑฐ์ž„.
  • populate ๋ฉ”์„œ๋“œ๋Š” ์–ด๋–ค ์ปฌ๋ ‰์…˜์—์„œ ObjectId๋ฅผ ์ด์šฉํ•ด์„œ ๋‹ค๋ฅธ ์ปฌ๋ ‰์…˜์˜ ์ •๋ณด๋ฅผ ๋‹ด์•„ ์ถœ๋ ฅํ•  ์ˆ˜ ์žˆ์Œ
  • ์ž์„ธํ•œ ์„ค๋ช…

1) ๊ฒŒ์‹œ๋ฌผ ์กฐํšŒ ๋ผ์šฐํ„ฐ

// getPost.js

const express = require("express");
const router = express.Router();
const { Post } = require("../../models/Post");

// ๊ฒŒ์‹œ๋ฌผ ์กฐํšŒ
router.get("/:id", async (req, res) => {
  const { id } = req.params;

  try {
    // ๊ฒŒ์‹œ๋ฌผ๊ณผ ๋Œ“๊ธ€์„ ํ•จ๊ป˜ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ ์œ„ํ•ด populate ์‚ฌ์šฉ
    const post = await Post.findById(id).populate("comments");
    if (!post) {
      return res.status(404).json({ message: "๊ฒŒ์‹œ๋ฌผ์„ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค." });
    }
    return res.status(200).json({ post });
  } catch (error) {
    return res.status(500).json({
      message: "๊ฒŒ์‹œ๋ฌผ ์กฐํšŒ ์ค‘ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.",
      error: error.message,
    });
  }
});

module.exports = router;

 

3. ๊ฒŒ์‹œ๋ฌผ ์กฐํšŒ ์˜ˆ์‹œ

  • ์œ„์˜ API๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด, ๊ฒŒ์‹œ๋ฌผ์˜ ๋‚ด์šฉ๊ณผ ํ•จ๊ป˜ ๋Œ“๊ธ€๋“ค์ด ํฌํ•จ๋œ ๊ฒฐ๊ณผ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Œ. 
# ์ถœ๋ ฅ ์˜ˆ์‹œ

{
  "post": {
    "_id": "๊ฒŒ์‹œ๋ฌผ ์•„์ด๋””",
    "user": "์‚ฌ์šฉ์ž ์•„์ด๋””",
    "text": "๊ฒŒ์‹œ๋ฌผ ํ…Œ์ŠคํŠธ",
    "images": ["<https://example.com/image1.jpg>"],
    "createdAt": "2024-11-02T06:59:29.107Z",  # ๊ฒŒ์‹œ๋ฌผ ์ƒ์„ฑ์ผ 
    "comments": [
      {
        "_id": "๋Œ“๊ธ€ ์•„์ด๋””",
        "user": "์‚ฌ์šฉ์ž ์•„์ด๋””",
        "text": "์ฒซ ๋Œ“๊ธ€์ž…๋‹ˆ๋‹ค!",
        "createdAt": "2024-11-02T07:00:00.000Z"  # ๋Œ“๊ธ€ ์ƒ์„ฑ์ผ
      },
      {
        "_id": "๋Œ“๊ธ€ ์•„์ด๋””",
        "user": "์‚ฌ์šฉ์ž ์•„์ด๋””",
        "text": "๋‘ ๋ฒˆ์งธ ๋Œ“๊ธ€์ž…๋‹ˆ๋‹ค!",
        "createdAt": "2024-11-02T07:05:00.000Z"  # ๋Œ“๊ธ€ ์ƒ์„ฑ์ผ
      }
    ]
  }
}

 

4. ๊ฒฐ๊ณผ ๐ŸŽ‰  

  • ๋‹ค์Œ ํฌ์ŠคํŠธ์—์„œ๋Š” ๋Œ“๊ธ€ ์ƒ์„ฑ ๊ธฐ๋Šฅ์— ๋Œ€ํ•ด ๋‹ค๋ค„๋ณผ๊ฑฐ์ž„!!