之前有提過,MongoDB 的 Schema-less 特性、加上 BSON 結構很適合拿來用 Node.js 寫個 Side-project,所以今天要拿之前的 API 範例,實際串上 MongoDB 資料庫。
建議你要準備一個主機環境:
雖然 WSL 也可以,但可能會遇上一些問題
你還需要:
首先先來回顧一下 koa-api-example 的範例。我們使用 Koa 搭配 koa-router 寫了幾個路由,然後分別用 POST
、GET
、PATCH
、DELETE
對應到文章的 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', // 資料庫的名稱
}));
我們進到新增的部分:
原本是 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 那些事兒。
本篇文章同步發表在 Noob's Space。