iT邦幫忙

2022 iThome 鐵人賽

DAY 12
3

Day12 自己做一個價值幾十萬的動態網站

第十二課:新的開始 學習資料連動Api串接
node.js Api介紹與實作、async function 與try{} catch介紹

了解何謂Api運作原理與實作

先前Day1時有簡單介紹到api與http的關係,那邊有稍微帶到express與node.js mongoDB懶人包

所以連接前後端資料的Api最重要的部分就是CRUD的資料操作,那放在實作上面,我們會利用express module,來操作一切所需要的資料傳輸行為,並配合mongoDB noSql類非關聯式資料庫來實作,這邊會需要先知道mongoDB是資料庫故名思議,他就只是存放資料的地方,有關所有資料需要的操作都將會使用node.js 中express來達成,包括宣告資料庫裡面的資料需要的物件型態,比如說住宿Hotel需要有那些基本資料,包括:名稱、地點、類型...等等的,與這些資料怎麽做資料統計等等的,都會在下方實作操作。

創建node.js Api folder

首先直接創建Api folder,並在其中創建index.js我們將從這邊開始,
並一一解釋這些步驟的原因


並在api folder裡面啟動terminal或是cmd來安裝啟動node.js等,所以首先我們不是像創建react一樣直接creat-react-app就可以直接接到package.json並npm i,如果這邊有點忘記的話,

歡迎複習day2那邊有對package.json與package-lock.json的介紹,但這邊一樣情況我們必須要有package.json才能安裝node_module,所以我們直接使用

npm init -y

npm init -y可以直接安裝一個預設的package.json檔,這邊的init就是啟動,並-y容易忘記但必須照著打,是-yes的縮寫所以常常忘記。
並安裝好package.json

安裝後並打上我們要使用的express 套件,並會一起下載好node_module,跟建置前台時的npm i 不太一樣

npm i express

這邊我們將在package.json裡面新增"type":"module"

commonjs是舊版本node.js的產物,而module為js推出新版本通用的產物,所以module適用於新的瀏覽器與新的ES6等等的,而舊版本的瀏覽器,可能只有讓commonjs能使用,而module不行,但我們還是跟上潮流使用module。
所以下面我們也盡量都會以import等ES6新版本的寫法帶入

這邊官方詳細教學如何一開始設置到本地伺服器,與以下示範組
https://expressjs.com/en/starter/hello-world.html

//const express = require('express')
const app = express()
const port = 3000

app.get('/', (req, res) => {
  res.send('Hello World!')
})

app.listen(port, () => {
  console.log(`Example app listening on port ${port}`)
})

所以這邊可以從範例看出規律,首先const app = express()啟動函數,並設置當地的伺服器編號為3000,而我們會使用5000做出區別,3000已給UI測試使用

並使用第一個get method,通過拿到這個url可以得到想要的資訊,req是request要求的資料,get只需要拿資料不需要再附加什麼資訊,除非之後遇到的是管理員才能看到的資料,我們才會附上token管理員憑證等等的,所以有分拿資料與有條件的拿資料與res是response就是回來的資料是什麼。


所以原本打下列預設指令也能啟動

node index.js

但我們將它重新設置指令,讓他npm start也可以做到以下操作,所以這邊就可以打上你更改好的start指令
這邊每次開啟terminal都要cd到api folder的覺得很麻煩的,vscode可以直接開api folder就不用開bookingChallenge還要再到下一層api folder麻煩


阿這邊你會發現當你修改index.js裡面的東西時,你也想樣直接儲存command+s看到有沒有修改成功,修改成功就會在跑出connected to 5000 backend 等訊息因為不像瀏覽器可以直接看到結果只能在terminal上觀看,所以我們可以讓他不用每次都需要重新執行npm start/node index.js 我們可以使用nodemon插件,所以打上下方指令

npm i nodemon




這邊完成後就可以來安裝mongoDB並連結它開始進到資料實作的部分

理解mongoDB

在網路上架設網站,你一定需要一個伺服器,並在上面建立資料庫來管理資料,為了現在的敏捷開發,一個人就可以搞定的全端網站,那mongoDB很適合我們,它支援免費雲端資料庫,管理與架設快安全性又高,也很適合剛要創業的人想要擁有自己的小型軟體進行管理,如下在Day1時我們有對資料庫做比對

現在我們就要來實際操作來應證mongoDB的強大,所以首先先附上他們的官方連結
https://www.mongodb.com/cloud/atlas/register
進去後可以註冊一下

mongoDB連接操作












這邊注意的是最後面那個要複製的,如我的是

mongodb+srv://samChallenge:<password>@cluster0.jld0x30.mongodb.net/?retryWrites=true&w=majority

並要加入兩個特別的認證與判別,一個是我們一開始創的管理員密碼與資料庫名稱,所以比如說我的密碼設立為12345678(我舉例不是真的我的密碼所以不能用這個來連)與上面有寫到資料庫名稱叫做BookingChallenge加上這串後應該是

mongodb+srv://samChallenge:12345678@cluster0.jld0x30.mongodb.net/BookingChallenge?retryWrites=true&w=majority

這邊是第一個管理員所以他是可以擁有所有權限,之後也可以設立那種管理員是只能讀取等等的限制權限管理員,中間 帳samChallenge密12345678 換掉就好了,下面就會利用這個來設立環境變數連線。

連接本地

搞定mongoDB那邊的雲端連接後,我們回到vscode,首先我們在上面弄出的那串憑證的,我們要創立一個專門放這個的file,為.env,(environment縮寫)前面有一點是因為執行檔的概念,env意思就是環境變數的意思,環境變數故名思義不同的環境下所有未來要放在函數裡面得變數都可以放在這邊,所以有什麼有關伺服器、雲端管理員、連線權限等等的之後都可以放在這邊

了解.env環境變數


所以.env裡面應該是,回到index.js去import dotenv這樣

MONGODB=mongodb+srv://samChallenge:12345678@cluster0.jld0x30.mongodb.net/BookingChallenge?retryWrites=true&w=majority

環境變數在應用面上都會應用在Api上,如到時候我們會使用的postman與insomnia都是專門操作Api的軟體,設立環境變數可以為Api常用的一些憑證等等需要連結的東西

接下來就是把環境變數進行連線實作

這邊的process.env是固定用法,才拿叫到.env folder裡面宣告的變數值

了解async function 與try{} catch是什麼

async function 非同步函數,相對於sync同步(async不同步),網路上的講解有非常多,這邊解釋常常會讓人搞不懂,以白話文來說,sync函數,他是同步函數,也就是在必須確保今天被需要的全部東西都完成才會往下的函數,而今天得談到的非同步就是可以不用需求都被完成就繼續往下,那這邊重點在應用上面,為什麼node.js都是需要以非同步為預設,原因是因為當使用非同步函數,就算還沒等到資料還是可以做其他事,就像youtube在跑的時候會先預覽整個畫面,不會等到他一定抓到資料才呈現整個畫面,所以非同步才是較合理且常被需要使用的方式,那什麼時候會需要用到同步函數sync
可以看我們這次實作的範例,async雖然是非同步,但配搭上await就可以是同步函數,就是先等他做完,這次沒做完不能先做其他事不能往下,就像同步的概念

const connect = async() => {
    try{
     await mongoose.connect(process.env.MONGODB)
        console.log("Connected to mongoDB")
    }catch(error){
        throw error
        console.log("disconnected to mongoDB")
    }
}

你也可以使用 async function expression 沒有加await來定義一個非同步函式。

try and catch,就像字面上的意思,先嘗試,如果不行我就抓取錯誤顯示給你看,負責在確定try裡面的東西會不會發生錯誤,如果有錯誤就回傳錯誤訊息回報。

並把這邊把這邊寫好的connect 寫在app.listen啟動

那了解了這些後我們算是主動第一次連上資料庫了,那後續我們也希望他可以是自動化告訴我們資料庫的連接是怎麼樣的,但不可能這邊一直不斷的連線與確認,所以我們要用到"mongoose"lib 讓他自動連上告訴我們斷掉了。

一樣安裝

npm i mongoose

並使用連接connection.on 這邊都是官方定義的所以會需要跟著這個方式寫,所以比如說中間的"connected"就不能寫成"Connected"大小寫也有影響,所以最後應該會長下面那樣 index.jsx

import mongoose from "mongoose"
//ES6後import 與export 取代了原本舊版的require
import express  from "express"; 
import dotenv from "dotenv"
const app = express()
dotenv.config()
const connect = async() => {
    try{
     await mongoose.connect(process.env.MONGODB)
        console.log("Connected to mongoDB")
    }catch(error){
        console.log("disconnected to mongoDB")
    }
}
mongoose.connection.on("connected",()=>{
    console.log("MongoDB connected!")
})
mongoose.connection.on("disconnected",()=>{
    console.log("MongoDB disconnected!")
})
const port =5000;
app.listen(port,()=>{
     connect();
    console.log(`connected to ${port} backend`)
    //並要像npm start 一樣啟動它,
})

這邊就恭喜你成功連上資料庫,下一天就可以來做資料串接的部分

結論

今天做的部分與以往不同,會進入到很多邏輯函數的部分,首先我們成功連上資料庫,明天我們將會開始做基本的Api串接,與Api為何這樣設置的邏輯解說,與UI介面不同,Api關心的是資料傳遞的合理性與安全性,所以反而有些Api會有固定的做法或是可能會有最好的表示法,跟UI介面的各種排版邏輯上,雖然內容不多,不會有太多的coding,少量但卻有更多的邏輯需要思考。


上一篇
「全端挑戰」useRef與gsap介紹與應用,hover彈跳comment視窗與Slider 滑動banner特效
下一篇
「全端挑戰」 express用法 建立Api schema CRUD 的練習與熟悉 part1
系列文
自己做一個價值幾十萬的動態網站,學會Mern開發、前台UI設計各式觀念與各式Lib、typescript你該學會的前端技術30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言