JS全棧後端Server部分 (1)-初始化及分類接口編寫
關於初始化和路徑參考JS全棧前端後臺管理部分筆記(1)- 初始化及分類CURD.md
切換到server
目錄並啓動項目
npm run serve
安裝主要依賴
npm install express@next mongoose cors
注意,安裝express時必須指定next,表示下一個版本,用來支持async和await的ES6新語法。
主程序
//index.js
路由
按照模塊來建立路由文件,創建routes/amdin/index.js
//index.js
module.exports = app =>{
const express = require("express");
const router = express.Router();//子路由
router.post("/categories",async(req,res)=>{
......
})
app.use("/admin/api",router)//將子路由掛在到實例上
}
-
文件導出使用一個函數,目的是傳入express實例,
-
router.post("/categories"… 表示定義一個categoreis接口,允許的方法是post。
-
app.use("/admin/api",router) 意思是使用express提供的Router函數生成子路由router,最後掛載到app上。 use的第一個參數是定義整個路由文件中請求的前半部分,也就是請求
/amdin/api/categoreis
才能訪問到上一個接口。簡化接口定義,不用重複寫前邊一樣的路徑了。
導入同時傳入express實例
//index.js
require("./routes/admin")(app)
數據庫
與路由文件相同,單獨建立plugins/db.js
文件,
//db.js
module.exports = app => {
const mongoose = require("mongoose");
mongoose.connect("mongodb://127.0.0.1:27017/node-vue-moba", {
useNewUrlParser: true,//連接參數
});
}
導入
//index.js
require("./plugins/db.js")(app)
模型
根目錄新建models
文件夾,建立Category.js
//Category.js
const mongoose = require("mongoose");
const schema = new mongoose.Schema({
name:{type:String}
})
module.exports = mongoose.model("Category",schema);
-
schema的意思是模式,我的理解是對數據庫的抽象,定義了數據表collecitons要保存的數據格式,如String類型的type字段。
-
最後導出利用了mongoose的model方法定義一個名稱爲Category,類型爲schema的model。
注意,最後導出的model就是對mongoDB中數據表collection的js化,mongoose在中間做了一層映射,我們對model的操作最後會轉換爲對MongoDB對應collection的操作。
導入並使用
//routes/admin/index.js
const Category = require("../../models/Category.js")
router.post("/categories", async (req, res) => {
const model = await Category.create(req.body)//將提交內容保存到mongoDB中
res.send(model);
})
-
導入後,在接口處理函數中創建記錄。
-
新增一條記錄document的方法是create,其中req.body是請求內容,由於是post方式提交的,如果要直接使用req.body來提取到提交內容,必須使用express.json()中間件。
//index.js
app.use(express.json())
注意這裏使用了await語法,目的是異步實現用同步語法來編寫,如果不用的話,上述實現會變爲
Category.create(req.body,function(data){
const model = data;
res.send(model)
}){//將提交內容保存到mongoDB中
res.send(model);
},
async和await能減少回調函數編寫,避免回調地獄。
跨域
express實例使用cors模塊作爲中間件實現
//index.js
app.use(require("cors")())//跨域用
編寫完成後,利用前端網頁想數據庫增加分類數據。
其他接口實現
注意:上面內容多爲基礎配置,下面爲具體實現,只記錄自己不會或者新學到的知識點。
分類列表接口
增加分類列表請求處理接口
//routes/admin/index.js
router.get("/categories", async (req, res) => {
const items = await Category.find().limit(10);//查詢,限制10條
res.send(items);
})
- find() 爲查詢方法,這裏暫時使用limit方法限制結果爲前10條。
分類詳情接口
//分類詳情
router.get("/categories/:id", async (req, res) => {
const model = await Category.findById(req.params.id);
res.send(model);
})
- findById 是mongoose提供的根據id查數據的方法。
- router.get("/categories/:id"…中:id代表匹配的路由,最後一個字符串是id
- get請求方的id具體內容通過req.params.id來得到。
編輯分類接口
//編輯分類
router.put("/categories/:id", async (req, res) => {
const model = await Category.findByIdAndUpdate(req.params.id, req.body);
res.send(model);
})
-
使用put請求方法來更新
-
使用 findByIdAndUpdate 方法來update,第一個參數是url中的id,第二個是更新的內容
子類別(無限極分類)
類別下面有子類別,有些子類別下邊有孫子類別,爲了實現這樣的層次,需要對數據庫進行修改。分類無論多少層級,在數據庫中都是平行存儲的,父子類別的關係就需要想辦法來體現。
一般可以用一個類別的屬性與另一個類別相關聯,子類別與父類別的關係是多對一。
在現有類別模型中新增一個parent屬性,這個屬性指向(綁定)他的父類別的id。
//models/Category.js
const schema = new mongoose.Schema({
name: { type: String },
parent: { type: mongoose.Types.ObjectId }
})
- parent是新增的屬性,用於關聯父類別,
- 注意parent的類型,雖然在數據庫中_id不是字符串,而是 mongoose.Types.ObjectId
- 關聯操作利用ref來實現,ref表示該字段關聯的哪個模型,這裏是自己本身。關聯之後,查詢一條記錄就可以連帶查詢出關聯記錄,類似於MySQL中的外鍵。
增加父級類別後,爲在前端顯示,需要修改分類列表接口
const items = await Category.find().populate("parent") .limit(10);//查詢,限制10條
- populate是關聯查詢,參數是關聯字段,使用此方法後會把關聯的對象也查出來。
以下是不加populate的查詢結果,
[
以下是加了populate的查詢結果
明顯可以看出populate把有關聯的類別整體查了出來,這樣就能提供給前端顯示父級類別的名稱了。
無論是多少級,都可以使用這樣id綁定的方法來建立關係,而且還能保證數據庫存儲的平行性。