JS全栈后端Server部分笔记 (1)-初始化及分类接口编写

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的查询结果,

[20200208130340290
以下是加了populate的查询结果

在这里插入图片描述

明显可以看出populate把有关联的类别整体查了出来,这样就能提供给前端显示父级类别的名称了。

无论是多少级,都可以使用这样id绑定的方法来建立关系,而且还能保证数据库存储的平行性。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章