使用 Node.js 與 RESTful API 架構來串接 mongoDB 並部署到 Heroku
網站組成通常是前端加後端、資料庫,簡單來說,前端主要是畫面加上操作介面,包含了一些前端語言及框架,後端則處理使用者請求控制回應,例如登入,後台管理…等等,後端語言常見的有 PHP、Java、ASP.NET、Node.js、Python…等等。資料庫則有 MySQL、MSSQL、MongoDB…。
因前端不斷的演進,畫面處理需快速變化,傳送資料方式也大都改用 Web API 的方式來提供服務。所以後端(server)就負責建立 API,透過串接 API 處理資料。
這邊就要來使用 Node.js 搭配 express 架構 RESTful API,連接 MongoDB,並部署到 server。
MongoDB
是開源的 NoSQL 資料庫,不需先制定每張資料表的結構、畫出 ER Model,因此不管是用來做個人專案,還是用來處理較大量資料都可以。
MongoDB 是用 Key-value 的方式來儲存資料:
1 | { |
另外 MongoDB 不是 JSON 格式,而是 BSON。它的 key 和 value 是有區分大小寫。但 MongoDB 大都是用 JSON 格式來儲存資料。
ps.BSON(Binary JSON),是 JSON 的擴充,因此可使用 Binary data 等。
MongoDB 跟傳統資料庫大致上對應的關係:
DB | MongoDB | MySQL |
---|---|---|
資料名稱 | Document | Row |
資料存放區名稱 | Collection | Table |
資料庫名稱 | Database | Database |
RESTful API
REST(Resource Representational State Transfer 具象狀態變化傳輸),API(Application Programming Interface 應用程式介面)。
RESTful API 可以理解成具有 Rest 架構的 Web API,是一種設計風格。意思大致上是,由發送的 HTTP 請求中所包含的資訊,就可以容易解讀出這請求會收到什麼類型的資料。用淺顯易懂的方式來解釋,就是只看 API 的格式就可以看得懂。
由於 API 設計方式跟 HTTP 請求及資料庫資料操作有關,因此就簡略說明一下:
常見的 HTTP 請求方式:
GET:取得資料
POST:新增一筆新的資料(如果存在會新增一筆新的)
PUT:更新一筆資料,如果存在這筆資就會覆蓋過去
PATCH:部分更新資料
DELETE:刪除資料
資料庫基本操作 CRUD:
Create(新增)
Read(讀取)
Update(更新)
Delete(刪除)
常見的 HTTP method 正好會對應到資料庫基本操作。
假設有一組待辦事項的 API,或許會用以下方式來設計:
獲得資料GET /getData
新增資料POST /createData
刪除資料DELETE /deleteData/1
以 REST 風格來開發 RESTful API:
獲得資料GET /data
新增資料POST /data
刪除資料DELETE /data/1
兩者差異是在於 RESTful API 充分地使用了 HTTP Protocol Method,達到:
1.直觀簡潔的資源 URI
2.並且善用 HTTP Verb
3.達到對資源的操作
4.並使用 Web 所接受的資料類型: JSON, XML, YAML 等,最常見的是 JSON。
前置工作
1.建立 heroku 上的 mongoDB 資料庫
2.heroku 建立新 App
3.安裝 mlab 套件
要填寫信用卡資料(才能用 Add-ons)
首先到我們要安裝插件的應用程式頁面,點選「Configure Add-ons」
在搜尋列打上「mlab」,並安裝
4.建立使用者
5.記得連線 URL
mlab 建立後,可在畫面上找到。
格式:"mongodb://dbuser:dbpass@host1:port1,host2:port2/dbname"
6.
接下來就是程式處理方面。
建立 nodejs server
先建立專案資料夾
npm init
npm install express --save
建立 index.js
1 | // 引用 express |
建立 index.html
1 | <!DOCTYPE html> |
package.json 加上
1 | "scripts": { |
測試一下,終端機下執行 npm start
,在瀏覽器網址輸入 http://localhost:3000/ 。看畫面是否成功出現 welcome 字樣。
連線 mongodb
1.安裝 mongodb
npm install mongodb --save
index.js 加上以下內容:
1 | // 引用 |
測試一下,終端機下執行 npm start
,終端機畫面上是否顯示 Listening on 3000 字樣。
若產生以下字樣
(node:39803) DeprecationWarning: current Server Discovery and Monitoring engine is deprecated, and will be removed in a future version. To use the new Server Discover and Monitoring engine, pass option { useUnifiedTopology: true } to the MongoClient constructor.
修改連線內容
1 | // 連線 mongoDB |
MongoDB 加上一筆資料
修改 index.js
1 | // 連線 mongoDB |
執行 npm start
,畫面上會顯示 1 document inserted。
heroku 的 mlab 頁面上會有新增的資料。
Get API-取得資料
index.js
1 | //GET API 從 http://localhost:3000/comments 取得資料 |
終端機輸入 npm start
,打開瀏覽器 http://localhost:3000/comments, 可以看到畫面顯示資料。
POST API-新增資料
下載 body-parser 套件,來處理資料格式,將其轉型別成 JSON。
npm install body-parser --save
index.js 加上
1 | const bodyParser = require('body-parser'); |
執行 npm start
,打開瀏覽器輸入網址 localhost:3000,在 console 輸入:
JavaSript fetch post
1 | fetch('http://localhost:3000/comments', { |
ps. 顯示 (node:3970) DeprecationWarning: collection.save is deprecated. Use insertOne, insertMany, updateOne, or updateMany instead.
修改 save() 為提示中的函式 insertOne()…等等
DELETE API-刪除資料
利用 網址:id
來帶參數,方便維運 API。若要使用 MongoDB 預設的 _id
當作查詢刪除,需要使用 ObjectID 處理來 value,但如果使用其他物件來作查詢,就不需使用 ObjectID。
index.js
1 | const ObjectID = require('mongodb').ObjectID; |
ps. 顯示 (node:3826) DeprecationWarning: collection.remove is deprecated. Use deleteOne, deleteMany, or bulkWrite instead.
修改 remove() 為提示中的函式 deleteOne()…等
PUT API-更新(UPDATE)資料
用 updateOne(obj, newvalues, function(err, obj){})
來更新資料,前面兩個參數分別帶查詢條件及更新資料。
index.js
1 | server.put('/comments/:id', (req, res) => { |
建立 config.json
可以將連線字串、帳密…環境變數等,放在這再引用,方便修改管理。
config.json
1 | { |
index.js 加上
const { DB_URL: url } = require('./config.json');
postman 測試
處理完 RESTful API 部分後,可以使用 postman 來測試。
GET
% asset_img postman_get.png This is an image %}
POST(記得依照標頭輸入設定來調整)
PUT(記得依照標頭輸入設定來調整)
DELETE
部署到 Heroku
部署到 server 上,可方便使用 API。
終端機輸入:
- heroku config set
1 | $ heroku config:set PROD_MONGODB=mongodb://dbuser:dbpass@host1:port1,host2:port2/dbname |
2.登入 heroku
heroku login
3.建立 GIT
git init
git add .
git commit -m "nodejs"
4.設定連結的 heroku 遠端主機
heroku git:remote -a (Heroku 上 的 App 名稱)
5.push remote
git push heroku master
heroku open
打開瀏覽器,輸入 heroku 的 app 路徑加上 /comments。
接著處理前端及畫面互動就可以做其他運用了。
CORS
若是其他應用要連線 heroku 取用 API 資料時,有可能會發生 CORS 問題。可用以下方式處理。
1.後端 API 開放跨網域 cors 權限
安裝 cors
npm install cors
index.js 加上
const cors = require('cors')
server.use(cors());
也可以單一 API 使用
1 | server.get('/', (req, res) => { |
2.使用第三方資源來協助存取使用 cors-anywhere、bypasscors
將 cors-anywhere 所提供的 API 放前面,後面加上要訪問的 API。
e.g.
1 | // use cors-anywhere to fetch api data |
參考:
https://iandays.com/2018/10/11/nodejsapi/
https://blog.johlmike.com/2016/08/05/heroku-cha-jian-mlab-mongodb-zi-liao-ku/
https://blog.johlmike.com/2016/07/12/mongoose-node-js-上連接-mongodb/#more-453
https://ithelp.ithome.com.tw/articles/10186483
https://dotblogs.com.tw/felixblog/2019/12/11/171324
https://medium.com/%E4%BC%81%E9%B5%9D%E4%B9%9F%E6%87%82%E7%A8%8B%E5%BC%8F%E8%A8%AD%E8%A8%88/express-restfulapi%E8%B5%B7%E6%89%8B%E6%95%99%E5%AD%B83-77206cd64ebb
https://i5ting.github.io/node-http/
https://progressbar.tw/posts/53
https://medium.com/itsems-frontend/api-是什麼-restful-api-又是什麼-a001a85ab638
https://ithelp.ithome.com.tw/articles/10157431
https://ithelp.ithome.com.tw/articles/10157674
https://noob.tw/mongodb/
https://medium.com/@des75421/cors-跨來源資源共用cors-191d4bfc4735
https://andy6804tw.github.io/2017/12/27/middleware-tutorial/#中介軟體
https://andy6804tw.github.io/2019/09/21/fix-cors-problem/