Node.js 學(xué)習(xí)筆記 - express 的使用

以前一直使用 PHP+MySQL 做服務(wù)端的 API 服務(wù),后來用了 JavaScript 做前端開發(fā)后犯眠,發(fā)現(xiàn) JS 其實很好用谊娇,而且代碼庫非常豐富,尤其在云函數(shù)開發(fā)中使用了mongoDB后眶拉,更是欲罷不能千埃,所以決定后端也用 JS 來做開發(fā),并嘗試使用 mongoDB 作為數(shù)據(jù)庫忆植。后端 Node.js 開發(fā)很多都采用 express 來開發(fā) web 服務(wù)放可,所以我對在 express 中遇到的問題做了個學(xué)習(xí)筆記,以備自己查閱朝刊,也備同學(xué)們參考耀里!

1、安裝 express

首先在一個合適的位置建立目錄:express-demo拾氓;
在 windows 命令行界面(開始-運行-cmd)冯挎,運行 shell 命令:

cd express-demo
npm init -y  ;; 初始化
npm install express --save  ;; 安裝express

安裝完成!

2咙鞍、做一個最簡單的 express 網(wǎng)站

2.1织堂、創(chuàng)建服務(wù)主控文件

在當前目錄(express-demo)下叠艳,新建app.js文件:

/**
 * 初始三部曲:引入、實例化易阳、端口
 **/
const express = require(`express`) // 引入 express 模塊
const app = express() // 創(chuàng)建一個 express 應(yīng)用實例 app
const port = 3000 // 設(shè)置服務(wù)端口

//啟動監(jiān)聽
app.listen(port, () => {
    console.log(`express is running at port ${port}!`)
})

這樣就建立了一個追簡單的 express web 服務(wù)器附较!

2.2、執(zhí)行 app.js 啟動 web 服務(wù)

node app.js

啟動完成潦俺!
在瀏覽器里輸入:http://127.0.0.1:3000拒课,會出現(xiàn)錯誤提示:Cannot GET /
這其實是很正常的,因為我們還沒有設(shè)置路由呢事示!

2.3早像、增加一個路由

修改 app.js,添加 Api 調(diào)用肖爵,使用 express 的 get 方法卢鹦,訪問業(yè)務(wù)模塊的對應(yīng)功能

app.get('/', (req, res) => res.send('index page!'))

修改后 app.js 整體源碼是這樣的:

/**
 * 初始三部曲:引入、實例化劝堪、端口
 **/
const express = require(`express`) // 引入 express 模塊
const app = express() // 創(chuàng)建一個 express 應(yīng)用實例 app
const port = 3000 // 設(shè)置服務(wù)端口

// 添加 Api 調(diào)用冀自,使用 express 的 get 方法,訪問業(yè)務(wù)模塊的對應(yīng)功能
app.get('/', (req, res) => res.send('index page!'))

//啟動監(jiān)聽
app.listen(port, () => {
    console.log(`express is running at port ${port}!`)
})

修改 app.js 文件后秒啦,需要重啟服務(wù)才能起作用熬粗!在命令行窗口 ctrl+C 組合鍵停止 app.js 的運行,再重新運行:

node app.js

訪問 http://127.0.0.1:3000余境,訪問成功驻呐。
到此,一個最簡單的 web 服務(wù)器就搭起來了芳来,開發(fā)起來也很簡單吧含末?但功能也很有限不是,這只是個最基本操作步驟即舌,下面會繼續(xù)完善答渔!

2.4、【附加題】安裝 nodemon

有沒有發(fā)現(xiàn)每次修改源碼后侥涵,都要重啟服務(wù),是不是很麻煩宋雏?所以就裝一個專門的代碼監(jiān)控工具芜飘,當代碼變化時,自動重啟應(yīng)用磨总。這個工具就是nodemon嗦明,既然是 node 插件,安裝就必須很簡單了蚪燕,npm就可以:

npm install nodemon --save

安裝完成后娶牌,在命令行里奔浅,使用:nodemon app.js 來代替前面使用的:node app.js 即可!試試诗良,是不是很爽汹桦?

3、升級 -- 加入獨立的路由文件

3.1鉴裹、加入路由功能

上例中舞骆,app.get('/', (req, res) => res.send('index page!')),是 express 的 get 方法的使用径荔,不能算作是路由督禽。
而使用路由的模式,代碼更簡潔总处、模塊化更好狈惫,所以下面添加路由方法,在添加路由的過程中鹦马,會有很多變形胧谈。
在 app.js 文件里增加:

// 添加 users 路由器,路由到用戶管理模塊
const usersRouter = express.Router() // 創(chuàng)建一個子路由模塊 usersRouter

// 將路由器添加到應(yīng)用上,/users 是路由路徑,將路徑和子路由模塊 usersRouter 掛接起來
app.use('/users', usersRouter);

// usersRouter 的路由條目設(shè)置中符。注意這時候再加路由爪瓜,就可以不帶前面的/users路徑了
usersRouter.get('/', function (req, res) {
    res.send('后臺獲取用戶列表數(shù)據(jù),并通過此接口返回');
});

在瀏覽器訪問:http://127.0.0.1:3000/users末融,顯示返回字符串:“后臺獲取用戶列表數(shù)據(jù),并通過此接口返回”,說明路由配置且工作正常键袱。
分析:新增的代碼有三行:
第一行:創(chuàng)建一個 Router
第二行:將 Router 掛接起來
第三行:增加路由映射,執(zhí)行業(yè)務(wù)邏輯
到此時摹闽,app.js 的整體代碼為:

/**
 * 初始三部曲:引入蹄咖、實例化、端口
 **/
const express = require(`express`) // 引入 express 模塊
const app = express() // 創(chuàng)建一個 express 應(yīng)用實例 app
const port = 3000 // 設(shè)置服務(wù)端口

// 添加 Api 調(diào)用付鹿,使用 express 的 get 方法澜汤,訪問業(yè)務(wù)模塊的對應(yīng)功能
app.get('/', (req, res) => res.send('index page!'))

// 添加 users 路由器,路由到用戶管理模塊
const usersRouter = express.Router() // 創(chuàng)建一個子路由模塊 usersRouter

// 將路由器添加到應(yīng)用上舵匾,/users 是路由路徑俊抵,將路徑和子路由模塊 usersRouter 掛接起來
app.use('/users', usersRouter);

// usersRouter 的路由條目設(shè)置。注意這時候再加路由坐梯,就可以不帶前面的/users路徑了
usersRouter.get('/', function (req, res) {
    res.send('后臺獲取用戶列表數(shù)據(jù)徽诲,并通過此接口返回');
});

//啟動監(jiān)聽
app.listen(port, () => {
    console.log(`express is running at port ${port}!`)
})

3.2、加入獨立的路由文件

上例中,userRouter 寫在 app.js 入口文件中谎替,這樣當路由增多時偷溺,app.js 文件會變得異常臃腫,所以考慮將模塊路由從 app.js 中獨立出來钱贯,只在 app.js 引用即可挫掏。

3.2.1、在項目根目錄下(和app.js 文件平級)建立 routers 目錄喷舀,在目錄下創(chuàng)建一個文件 users.js 砍濒,表示這是一個 users 相關(guān)的路由文件,內(nèi)容為:

const express = require('express'); // 導(dǎo)入 express 服務(wù)對象
const router = express.Router(); // 獲取 express 的路由對象

// 注意:下面的路由路徑為子路徑硫麻,此例中實際路徑需要加上前綴/users

router.get('/', (req, res) => {
    res.send('users list page!')
})

router.get('/:id', (req, res) => {
    res.send(`id 為:${req.params.id} 的用戶信息!`)
})

module.exports = router

3.2.2爸邢、修改 app.js 文件中的 路由定義和 use 語句,將

const userRouter = express.Router()
app.use('/users', userRouter)
userRouter.get('/', function(req, res){
    res.send('后臺獲取用戶列表數(shù)據(jù)拿愧,并通過此接口返回')
})

修改為:

app.use('/users', require('./routers/users'))

測試運行杠河,沒有問題,這樣就成功把路由文件剝離出來了浇辜。

3.3券敌、加入 routers.js

按上面的做法,增加另外一個 router 柳洋,比如訂單路由: orders 待诅。
先增加路由文件 orders.js ,內(nèi)容如下:

const express = require('express'); // 導(dǎo)入 express 服務(wù)對象
const router = express.Router(); // 獲取 express 的路由對象

// 注意:下面的路由路徑為子路徑熊镣,此例中實際路徑需要加上前綴/orders

router.get('/', (req, res) => {
    res.send('orders list page!')
})

router.get('/:id', (req, res) => {
    res.send(`id 為:${req.params.id} 的訂單信息!`)
})

module.exports = router

同樣卑雁,還是需要修改 app.js 文件,需要加上一行:

app.use('/orders', require('./routers/orders'))

雖然不是很復(fù)雜绪囱,但每次增加路由模塊测蹲,都會修改 app.js ,感覺還是不爽鬼吵,還是需要升級扣甲,繼續(xù)變形看看...,具體做法就是

3.3.1齿椅、增加一個路由匯總定義文件: ./routers.js

var routers = function(app){
    app.use('/users', require('./routers/users'))
    app.use('/orders', require('./routers/orders'))
}

module.exports = routers

3.3.2琉挖、修改 app.js 文件

將 app.js 里的兩個對 /users 和 /orders 兩個路由的 use 語句刪除掉,增加一句涣脚,將路由匯總文件 routers.js 導(dǎo)入

require('./routers.js')(app) // app作為參數(shù)傳遞給 routers() 函數(shù)

至此示辈,對于路由的修改,基本就不用動 app.js 文件了涩澡,需要增加新的路由時,添加新的路由文件,并修改 ./router.js 的相應(yīng)內(nèi)容即可妙同。

備注:此例子中的 app.get('/',.....) 也可以改成路由器模式射富,再建立一個 indexRouter 就可以了,如果 index 的功能很簡單的話粥帚,index 部分不建立路由器胰耗,直接使用 express 的 get、post等方法也沒問題芒涡。

4柴灯、升級 -- 路由文件和業(yè)務(wù)分離

4、升級 -- 路由文件和業(yè)務(wù)分離
由前所述费尽,路由文件由 ./routers.js 匯總定義文件和 routers 目錄下的具體路由模塊文件組成赠群,路由結(jié)構(gòu)清晰多了,但目前路由模塊文件里還是涉及到很多的業(yè)務(wù)邏輯旱幼,能否將業(yè)務(wù)和路由剝離呢查描?經(jīng)測試,答案是肯定的柏卤。具體做法如下:

4.1冬三、在項目根目錄下建立文件夾 controllers

在此目錄下,為每個路由模塊建立一個控制器模塊缘缚,例如此例中的 users.js 和 orders.js:

users.js

var controller = {}

// list 方法對應(yīng) get('/users/',....) 路由
controller.list=function(req, res){
    res.send('users list page!')
}

// info 方法對應(yīng) get('/users/:id',...) 路由
controller.info=function(req, res){
    res.send(`id 為:${req.params.id} 的用戶信息!`)
}

module.exports = controller

orders.js

var controller = {}

// list 方法對應(yīng) get('/orders/',....) 路由
controller.list=function(req, res){
    res.send('orders list page!')
}

// info 方法對應(yīng) get('/orders/:id',...) 路由
controller.info=function(req, res){
    res.send(`id 為:${req.params.id} 的訂單信息!`)
}

module.exports = controller

4.2勾笆、修改子路由文件

修改路由模塊文件里的 router.get()方法,如下:

./routers/users.js

var controller = require('../controllers/users')
router.get('/', controller.list)
router.get('/:id', controller.info)

./routers/orders.js

var controller = require('../controllers/orders')
router.get('/', controller.list)
router.get('/:id', controller.info)

從上面的修改可以看出桥滨,路由模塊的引用很單純窝爪,除了模塊名稱不同、應(yīng)用文件不同该园,其他都差不多酸舍。而和邏輯有關(guān)的代碼都放到controllers下面去了,如果后面再加上數(shù)據(jù)模塊 models 里初,是不是和以前 PHP 的 MVC 很類似啃勉?這樣,express 和路由相關(guān)的架構(gòu)就基本確定双妨,后續(xù)就可以將重點放到邏輯代碼的開發(fā)上了淮阐。

后續(xù)如果有時間,會繼續(xù)研究一下數(shù)據(jù)模塊 models 的構(gòu)建模式刁品。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末泣特,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子挑随,更是在濱河造成了極大的恐慌状您,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異膏孟,居然都是意外死亡眯分,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進店門柒桑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來弊决,“玉大人,你說我怎么就攤上這事魁淳∑” “怎么了?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵界逛,是天一觀的道長昆稿。 經(jīng)常有香客問我,道長仇奶,這世上最難降的妖魔是什么貌嫡? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮该溯,結(jié)果婚禮上岛抄,老公的妹妹穿的比我還像新娘。我一直安慰自己狈茉,他們只是感情好夫椭,可當我...
    茶點故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著氯庆,像睡著了一般蹭秋。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上堤撵,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天仁讨,我揣著相機與錄音,去河邊找鬼实昨。 笑死洞豁,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的荒给。 我是一名探鬼主播丈挟,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼志电!你這毒婦竟也來了曙咽?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤挑辆,失蹤者是張志新(化名)和其女友劉穎例朱,沒想到半個月后孝情,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡洒嗤,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年咧叭,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片烁竭。...
    茶點故事閱讀 40,115評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖吉挣,靈堂內(nèi)的尸體忽然破棺而出派撕,到底是詐尸還是另有隱情,我是刑警寧澤睬魂,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布终吼,位于F島的核電站,受9級特大地震影響氯哮,放射性物質(zhì)發(fā)生泄漏际跪。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一喉钢、第九天 我趴在偏房一處隱蔽的房頂上張望姆打。 院中可真熱鬧,春花似錦肠虽、人聲如沸幔戏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽闲延。三九已至,卻和暖如春韩玩,著一層夾襖步出監(jiān)牢的瞬間垒玲,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工找颓, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留合愈,地道東北人。 一個月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓叮雳,卻偏偏與公主長得像想暗,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子帘不,可洞房花燭夜當晚...
    茶點故事閱讀 45,055評論 2 355