之前有提過,MongoDB 的 Schema-less 特性、加上 BSON 結構很適合拿來用 Node.js 寫個 Side-project,所以今天要拿之前的 API 範例,實際串上 MongoDB 資料庫。

事前準備

建議你要準備一個主機環境:

雖然 WSL 也可以,但可能會遇上一些問題

你還需要:

撰寫 API

首先先來回顧一下 koa-api-example 的範例。我們使用 Koa 搭配 koa-router 寫了幾個路由,然後分別用 POSTGETPATCHDELETE 對應到文章的 CRUD。

如果你沒有跟到前面的文章又很懶得看的話,你可以直接 clone 我們的範例下來:

git clone https://github.com/noobtw/koa-api-example

當時是用一個大 Array 來維護所有文章,所以每次 JS 關掉就不見了,這次我們要真的把東西寫進資料庫裡面。

首先我們安裝 koa-mongo 這個套件:

npm install --save koa-mongo

接著要在 server.js 使用 koa-mongo 這個 middleware。這個 middleware 會自動幫我們連結 Mongo 資料庫,並把連結好的實體放在 ctx.db 這個物件裡面。

首先我們要在使用 router 之前先使用 mongo

const mongo = require('koa-mongo');

app.use(mongo({
  host: 'localhost',   // 預設為本機
  port: 27017,         // 預設 port 為 27017
  db: 'blog',          // 資料庫的名稱
}));

加上 MongoDB

我們進到新增的部分:

原本是 articles.push({...}) 塞進陣列裡,現在我們要把他塞進資料庫裡,可以這樣寫:

ctx.db.collection('articles').insertOne({
    title,
    body,
    author,
    time: new Date(),
});

我們把這筆資料塞進 articles 這個 collection 裡面。另外由於 MongoDB 會自動幫我們產生 _id,所以就不用再塞一個 id 進去了。

查詢的部分,我們要找出 _id 為 id 的一筆資料。但是 _id 不是一般的欄位,不可以直接用 find({_id: id}) 來查詢,要改用 find({_id: mongo.ObjectId(id)) 才行:

const article = await ctx.db.collection('articles').findOne({_id: mongo.ObjectId(id)});

修改的話,一樣先找出 {_id: mongo.ObjectId(id)} 的資料,然後再修改參數。例如:

ctx.db.collection('articles').update({_id: mongo.ObjectId(id)}, {$set: {
    title,
    body,
    author,
    time: new Date(),
}}

刪除的話則是和查詢一樣,只是改下 remove

ctx.db.collection('articles').remove({_id: mongo.ObjectId(id)});

最後可以看看 原始碼。有關為什麼要加 async/await,可以參考 我要學會 JS(三):callback、Promise 和 async/await 那些事兒

本篇文章同步發表在 iT邦幫忙

API 實作 目錄