iT邦幫忙

2023 iThome 鐵人賽

DAY 10
1
自我挑戰組

初探全端之旅: 以MERN技術建立個人部落格系列 第 10

[Day10] 建立文章的Schema讓文章API與真實資料庫互動

  • 分享至 

  • xImage
  •  

昨天已經讓後端程式和正式資料庫連接起來,今天就要將原本的MOCK_POSTS移除,與真正的資料庫互動了。

大綱

  1. 建立文章的Schema&Model
  2. 調整API
    a. 新增文章
    b. 取得(單一)文章
    c. 更新文章
    d. 刪除文章

1.建立文章的Schema&Model

models的資料夾底下新增Post.js,透過mongoose建立文章的schema

//Post.js

const mongoose = require('mongoose');

const PostSchema = new mongoose.Schema({
  title: { 
    type: String, 
    required: true 
  },
  tags: {
    type: Array,
    required: true
  },
  content: { 
    type: String, 
    required: true 
  },
  //文章發布日期
  createdDate: {
    type: Date,
    default: Date.now
  },
  //文章作者Id
  authorId:{
    type: String, 
    required: true 
  }
});

module.exports = Post = mongoose.model('Post', PostSchema);

2.調整API

posts-controller.js裡引入我們剛剛建立的model,並逐個調整文章的API

//posts-controller.js

const Post = require('../models/Post');

a.新增文章

const createPost =  async (req,res,next) =>{
    try {
        const { title, tags, content, authorId } = req.body;

        if (!title || title.trim() === "") {
            return next(new HttpError('Title is required', 400));
        }
        
        if (!tags || !Array.isArray(tags) || tags.length === 0) {
            return next(new HttpError('Tags should be an array and cannot be empty', 400));
        }
        
        if (!content || content.trim() === "") {
            return next(new HttpError('Content is required', 400));
        }

        const post = new Post({
            title,
            tags,
            content,
            authorId,
        });
  
        await post.save();

        res.status(201).json(post);

    } catch (error) {
        next(new HttpError('伺服器錯誤', 500));
    }
} 

b.取得(單一)文章

exports.getPost = async (req, res, next) => {
  try {
    //取得文章的資料和作者
    const post = await Post.findById(req.params.postId).populate('author', 'fullName profileImage _id');

    if (!post) return next(new HttpError("Post not found", 404));
    
    res.json(post);

  } catch (error) {
    next(new HttpError("Server error", 500));
  }
};

c.更新文章

exports.updatePost = async (req, res, next) => {
  try {
    const { postId } = req.params; 

    if (!postId) {
      return next(new HttpError("PostId is required", 400));
    }

    const { title, tags, content, coverImage, authorId } = req.body;

    // 檢查文章是否存在
    const post = await Post.findById(postId);
    if (!post) {
      return next(new HttpError("Post not found", 404));
    }

    // 更新文章資料
    if (title && title.trim() !== "") {
      post.title = title;
    }

    if (tags && Array.isArray(tags) && tags.length !== 0) {
      post.tags = tags;
    }

    if (content && content.trim() !== "") {
      post.content = content;
    }

    if (coverImage) {
      post.coverImage = coverImage;
    }

    await post.save();

    res.status(200).json(post);
  } catch (error) {
    console.log(error);
    next(new HttpError("Server error", 500));
  }
};

d.刪除文章

const deletePost =  async (req,res,next) =>{
    try {
        const post = await Post.findById(req.params.postId);
  
        if (!post) return next(new HttpError('刪除失敗:此id的文章不存在', 404));
  
        await post.deleteOne();
  
        res.json({ message: '刪除成功' });
  
    } catch (error) {
        next(new HttpError('伺服器錯誤', 500));
    }
} 

參考資料:
https://mongoosejs.com/docs/guide.html
https://developer.mozilla.org/zh-TW/docs/Learn/Server-side/Express_Nodejs/mongoose


上一篇
[Day9]連接資料庫(使用MongoDB和Mongoose)
下一篇
[Day11] 登入、註冊API開發和HTTP Authentication(JWT)
系列文
初探全端之旅: 以MERN技術建立個人部落格31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言