iT邦幫忙

2025 iThome 鐵人賽

DAY 18
0
自我挑戰組

API 全攻略系列 第 18

Day 18: 使用資料庫的 API(以 MongoDB 為例)

  • 分享至 

  • xImage
  •  

前言

昨天我們完成了一個 記憶體版的 Todo CRUD API,但資料只存在程式執行時,伺服器一關閉資料就消失。在真實專案中,我們需要 資料庫(Database) 來持久儲存資料。今天我們將使用 MongoDB 搭配 Mongoose 來改寫 Todo API。


為什麼選擇 MongoDB?

  • NoSQL 資料庫 :使用文件(Document)格式儲存資料,與 JSON 很像。
  • 靈活性高 :欄位結構不需要事先固定。
  • 社群龐大 :有許多套件與教學資源。

安裝 MongoDB 與 Mongoose

  1. 用 MongoDB Atlas 建立免費雲端資料庫。
  2. 在專案中安裝套件:
npm install mongoose

建立 MongoDB 連線

修改 index.js:

const express = require('express');
const mongoose = require('mongoose');
const app = express();
const port = 3000;

app.use(express.json());

// 連線到 MongoDB
mongoose.connect('mongodb://127.0.0.1:27017/todo_api')
  .then(() => console.log('✅ Connected to MongoDB'))
  .catch(err => console.error('❌ MongoDB connection error:', err));

// 定義 Todo Schema
const todoSchema = new mongoose.Schema({
  task: { type: String, required: true },
  done: { type: Boolean, default: false }
});

// 建立 Model
const Todo = mongoose.model('Todo', todoSchema);

// ===== Create =====
app.post('/api/todos', async (req, res) => {
  try {
    const todo = new Todo({ task: req.body.task });
    const saved = await todo.save();
    res.status(201).json(saved);
  } catch (err) {
    res.status(400).json({ error: err.message });
  }
});

// ===== Read =====
app.get('/api/todos', async (req, res) => {
  const todos = await Todo.find();
  res.json(todos);
});

app.get('/api/todos/:id', async (req, res) => {
  try {
    const todo = await Todo.findById(req.params.id);
    if (!todo) return res.status(404).json({ error: 'Todo not found' });
    res.json(todo);
  } catch (err) {
    res.status(400).json({ error: 'Invalid ID format' });
  }
});

// ===== Update =====
app.put('/api/todos/:id', async (req, res) => {
  try {
    const updated = await Todo.findByIdAndUpdate(
      req.params.id,
      req.body,
      { new: true } // 回傳更新後的資料
    );
    if (!updated) return res.status(404).json({ error: 'Todo not found' });
    res.json(updated);
  } catch (err) {
    res.status(400).json({ error: 'Invalid ID format' });
  }
});

// ===== Delete =====
app.delete('/api/todos/:id', async (req, res) => {
  try {
    const deleted = await Todo.findByIdAndDelete(req.params.id);
    if (!deleted) return res.status(404).json({ error: 'Todo not found' });
    res.json(deleted);
  } catch (err) {
    res.status(400).json({ error: 'Invalid ID format' });
  }
});

app.listen(port, () => {
  console.log(`🚀 Server running at http://localhost:${port}`);
});

測試 API

  1. 啟動伺服器:
node index.js
  1. 在 Postman 測試:
  • 建立
POST http://localhost:3000/api/todos
Body: { "task": "寫 Day 18 文章" }
  • 讀取所有
GET http://localhost:3000/api/todos
  • 更新
PUT http://localhost:3000/api/todos/<id>
Body: { "done": true }
  • 刪除
DELETE http://localhost:3000/api/todos/<id>

小結

今天我們把 API 從記憶體升級到 MongoDB ,實現了完整的 CRUD + 永續儲存 。至此,我們的 Todo API 已經達到一個「可實際使用」的基本版本。


上一篇
Day 17: API 的 CRUD 設計(建立、讀取、更新、刪除)
系列文
API 全攻略18
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言