koa 是非常精简的框架, 其中的精粹思想就是洋葱模型(中间件模型), koa 框架的中间件模型非常好用并且简洁, 但是也有自身的缺陷, 一旦中间件数组过于庞大, 性能会有所下降,我们需要结合自身的情况与业务场景作出最合适的选择.
* Node 主要用在开发 Web 应用,koa 是目前 node 里最流行的 web 框架。*
1. 安装koa koa-router
npm install koa koa-router -S
npm install nodemon -D
- 使用
require()引入koa-router,并且对其实例化(支持传递参数),然后使用获取到的路由实例router设置一个路径 - Nodemon是一个实用程序,它将监视源中的任何更改并自动重新启动服务器 使用koa koa-body代码如下
// app.js
const Koa = require('koa'); // 引入koa
const Router = require('koa-router'); // 引入koa-router
const app = new Koa(); // 创建koa应用
const router = new Router(); // 创建路由,支持传递参数
// 调用router.routes()来组装匹配好的路由,返回一个合并好的中间件
// 调用router.allowedMethods()获得一个中间件,当发送了不符合的请求时,会返回 `405 Method Not Allowed` 或 `501 Not Implemented`
app.use(router.routes()); //拆分路由要用的 下面有提到
app.use(router.allowedMethods({
// throw: true, // 抛出错误,代替设置响应头状态
// notImplemented: () => '不支持当前请求所需要的功能',
// methodNotAllowed: () => '不支持的请求方式'
})); //拆分路由要用的 下面有提到
// 启动服务监听本地3000端口
app.listen(3000, () => {
console.log('应用已经启动,http://localhost:3000');
})
package.json需要添加一条nodemon的命令,第8行
"scripts":{
"server":"nodemon app.js"
}
2.使用 Koa-router (如果要拆分的话 需要注意注释的语句 )
拆分路由模块
创建一个routes的文件夹
创建一个user.js
Koa-router 请求方式: get 、 put 、 post 、 patch 、 delete 、 del ,而使用方法就是 router.方式() ,比如 router.get() 和 router.post() 。而 router.all() 会匹配所有的请求方法。
const Router = require("koa-router");
const router = new Router({ prefix: "/users" });
const { register, login, find } = require("../controllers/user.js");
// router.get("/test", (ctx) => {
// ctx.body = "我是test";
// });
router.post("/register", register); //登录接口
router.post("/login", login); //注册接口
module.exports = router.routes();
3 登录接口的内容 根目录新建一个controllers文件夹
//controllers/users.js 路径
const User = require("../models/Users.js");
const { encryptPW, isRightPW } = require("../config/utils.js");
const jwt = require("jsonwebtoken");
const { secretKEY } = require("../config/key.js");
class ginS {
async register(ctx) {
console.log(ctx.request.body);
ctx.body = ctx.request.body;
//存储到数据库
const findResult = await User.find({ email: ctx.request.body.email });
if (findResult.length > 0) {
ctx.body = { msg: "邮箱已经存在!!!" };
} else {
//没查到
const newUser = new User({
name: ctx.request.body.name,
email: ctx.request.body.email,
password: encryptPW(ctx.request.body.password),
});
//存储到数据库
await newUser
.save()
.then((res) => {
ctx.body = newUser;
})
.catch((err) => {
console.log(err);
});
}
}
async login(ctx) {
const findResult = await User.find({ email: ctx.request.body.email });
if (findResult.length === 0) {
ctx.status = 404;
ctx.body = { email: "用户不存在!!!" };
} else {
const user = findResult[0];
const password = ctx.request.body.password;
// 返回true和false
const result = isRightPW(password, user.password);
console.log(result);
if (result) {
// 返回token
const userInfo = { id: user.id, name: user.name };
//生成token
const token = jwt.sign(userInfo, secretKEY, { expiresIn: "1h" });
ctx.status = 200;
ctx.body = { msg: "登录成功!!!", token: "Bearer " + token };
} else {
ctx.status = 400;
ctx.body = { msg: "登录失败!!!" };
}
}
}
// 获取数据
async find(ctx) {
ctx.body = await User.find();
}
}
module.exports = new ginS();
4 需要引入的登录或数据的类型 根目录新建 models文件 /models/Users.js
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const UserChema = new Schema({
name: { type: String, required: true },
email: { type: String, required: true },
password: { type: String, required: true },
date: { type: Date, default: Date.now },
});
module.exports = mongoose.model("Admin", UserChema, "wens");
5. 需要的话 还能设置路由前缀
可以通过调用 router.prefix(prefix) 来设置路由的前缀,也可以通过实例化路由的时候传递参数设置路由的前缀,比如在 RESTful 接口里面,往往会为接口设置一个 api 前缀,如:
router.prefix('/api')
// 或者
const router = new Router({
prefix: '/api'
})
当然也支持设置参数:
router.prefix('/路径/:参数')
**6. 还可以拆分路由 主文件app.js添加
//app.js
const Koa = require('koa'); // 引入koa
const Router = require('koa-router'); // 引入koa-router
+const routeing = require("./routers/index.js"); //创建的index.js文件夹 在 routers下面创建
+/* index.js 的内容
const fs = require("fs");
module.exports = (router) => {
fs.readdirSync(__dirname).forEach((file) => {
if (file === "index.js") return false;
const route = require(`./${file}`);
router.use(route);
});
};*/
const app = new Koa(); // 创建koa应用
const router = new Router(); // 创建路由,支持传递参数
//+ routeing(router);
app.use(router.routes()).use(router.allowedMethods());
// 启动服务监听本地3000端口
app.listen(3000, () => {
console.log('应用已经启动,http://localhost:3000');
})
7. 路由重定向
使用 router.redirect(source, destination, [code]) 可以对路由进行重定向,例子:
router.redirect('/login', 'sign-in');
等价于:
router.all('/login', ctx => {
ctx.redirect('/sign-in');
ctx.status = 301;
});
8. koa配合mongoose(数据库的操作)使用
安装
npm install mongoose --save
可以在app.js引入
const mongoose = require("mongoose");
const { connectionStr } = require("./config/key.js"); //./config/key.js 链接数据库的文件
// 连接数据库
mongoose.connect(connectionStr, (err) => {
if (err) console.log("mongonDB连接失败了");
console.log("mongonDB连接成功了");
});`
config/key.js
module.exports = {
connectionStr:'这个主要是启动的下面的这个软件(mongoDB)'
}
总结
koa 是非常精简的框架, 其中的精粹思想就是洋葱模型(中间件模型), koa 框架的中间件模型非常好用并且简洁, 但是也有自身的缺陷, 一旦中间件数组过于庞大, 性能会有所下降,我们需要结合自身的情况与业务场景作出最合适的选择.