# 【Day 13】Express 應用程式產生器(Express generater)、在 routes 設計路由
## :herb: <font color="#E58638">講義內容</font>
express 應用程式產生器可以快速產生一個應用程式架構
安裝步驟
- 先開好一個新專案
- 執行 `npm install express-generator -g`
- 接著切換到專案路徑下,執行 `express --no-view`
可參考[文件](https://expressjs.com/zh-tw/starter/generator.html)查看指令選項
注意:這裡需要選擇 `no view`,因最終作業最後設計出的 API 只需要回傳 JSON 資料,不會使用到 view 模板引擎
:::spoiler 指令選項
```
$ express -h
Usage: express [options][dir]
Options:
-h, --help output usage information
--version output the version number
-e, --ejs add ejs engine support
--hbs add handlebars engine support
--pug add pug engine support
-H, --hogan add hogan.js engine support
--no-view generate without view engine
-v, --view <engine> add view <engine> support (ejs|hbs|hjs|jade|pug|twig|vash) (defaults to jade)
-c, --css <engine> add stylesheet <engine> support (less|stylus|compass|sass) (defaults to plain css)
--git add .gitignore
-f, --force force on non-empty directory
```
:::
執行成功後應該會出現以下結構
:::spoiler 資料夾結構
```
├── app.js
├── bin
│ └── www
├── package.json
├── public
│ ├── images
│ ├── javascripts
│ ├── stylesheets
│ └── style.css
└── index.html
└── routes
├── index.js
└── users.js
```
:::
此結構已將 routes 的部分拆成獨立模組,並在 app.js 引入
在 routes 的 index.js 或 users.js,會使用 `const router = express.Router()`
並使用 `router` 來設定路由
```javascript
router.get('/', function(req, res, next) {
res.send('respond with a resource');
});
```
需注意在 app.js 引入使用時,就會自動帶入 `/users`,因此 users.js 中 path 可直接從 `/users` 之後開始(`router.get('/', ...)` 就會是 `/users`)
```
const usersRouter = require('./routes/users');
app.use('/users', usersRouter);
```
第一次啟用伺服器時需執行 `npm install` 安裝相關套件,並執行 `npm start`
若想使用 nodemon 運行也可自行在 package.json 加上指令,並使用 `npm run start:dev` 運行
```json
"scripts": {
"start": "node ./bin/www",
"start:dev": "nodemon ./bin/www"
},
```
### 參考資源
[Express 應用程式產生器](https://expressjs.com/zh-tw/starter/generator.html)
[Express - API](http://expressjs.com/zh-tw/api.html#express.router)
[Router 進階設定](https://courses.hexschool.com/courses/1670869/lectures/39299607) 到 [express-generator (下)](https://courses.hexschool.com/courses/1670869/lectures/39299612)(章節影片)
### 題目(將答案寫在 HackMD 並提交至回報區)
此[專案](https://github.com/dogwantfly/express-user)為使用 express generater 產生的結構,請嘗試在此 routes 資料夾的 users.js,設計新增及修改個人資料的路由(搭配動態路由),在註解處填上答案(可使用 POSTMAN 測試是否可正確運作),完成後將 users.js 的程式碼貼到 HackMD 並提交至回報區
---
## :herb: <font color="#E58638">作業回報</font>
```javascript
var express = require('express');
var router = express.Router();
const User = require('../models/usersModel')
/* GET */
router.get('/', function (req, res, next) {
res.send('respond with a resource');
});
/* POST 新增個人資料 */
router.post('/', async function (req, res, next) {
try {
const newUser = await User.create(req.body)
res.status(200).json({
status: "success",
data: newUser
})
} catch (error) {
res.status(400).json({
status: "false",
message: "欄位格式錯誤",
error: error.errors
})
}
});
/* PATCH 編輯個人資料 */
router.patch('/:id', async function (req, res, next) {
try {
// 先確認是否有資料
const hasId = await User.findById(req.params.id)
if (req.params.id && hasId) {
// 若無填寫 nickName,則回傳錯誤
if (!req.body.nickName) {
res.status(400).json({
status: "false",
message: "欄位格式錯誤",
error: ['暱稱 nickName 未填寫']
})
return
}
await User.findByIdAndUpdate(req.params.id, req.body)
const user = await User.findById(req.params.id)
res.status(200).json({
"status": "success",
"data": user
})
}
} catch (error) {
res.status(400).json({
status: "false",
message: "欄位格式錯誤",
error: error
})
}
});
module.exports = router;
```
---
###### tags: `Node.js 直播班 - 2022 春季班`