koa2是什么
框架
- 封装原生代码的 API
- 规范流程和格式
- 让开发人员更加关注于业务代码,提高开发效率
框架frame和库lib的区别
- 框架是唯一的,库就可以共存,即:一个项目中只能使用一个框架,但可以同时多个库
- 框架关注全流程,库关注单个功能
- 类比 Vue 和 lodash
什么是koa2
koa2 是 nodejs web server 框架
- 官网和文档 https://koa.bootcss.com/
- 通过 async/await 语法【处理异步】高效编写web server
- 中间件机制,能合理拆分业务代码
单独使用koa插件
- 初始化项目 npm init
- 安装koa2 npm install koa --save
const Koa = require('koa') // 引入koa
const app = new Koa() // 实例化
app.use(async(ctx) => {
ctx.body = 'hello world'
})
app.listen(3000) // web server 监听的 3000端口
koa2环境搭建
- 全局安装脚手架
npm install -g koa-generator
- 查看版本
koa2 --version
- 创建项目
koa2 test
(test文件夹名称) - 启动项目
npm run dev
- 访问
localhost:3000
koa路由使用方式
- 创建路由
const router = require('koa-router')()
// 设置前缀
router.prefix('/api')
router.get('/list', function(ctx, next) {
ctx.body = 'api list'
})
router.post('/create', function(ctx, next) {
ctx.body = 'api create'
})
// 导出
module.exports = router
- app.js中引入路由
const comments= require('./routes/comments')
- app.js中注册路由
app.use(comments.routes(), comments.allowedMethods())
koa2处理http请求
ctx 即 res 和 req的集合,用来处理接收和返回数据
-
ctx.query
获取get请求的参数集合
-
ctx.request.body
获取post请求的参数集合
ctx.body
设置响应数据
koa2中间件
1、为什么使用中间件
- 拆分业务模块,使代码清晰
- 统一使用中间件,使得各业务代码都规范标准
- 扩展性好,易添加、易删除.
2、koa2业务代码都是中间件
- app.use(..)都属于中间件, 所有的请求都会经过中间件
- 路由也是中间件,只有满足路由规则才会进入这个中间件
3、中间件规则
- 不管是什么类型的中间件(路由的或者自定义的),它都是一个async函数。async函数的第一个参数是ctx,第二个参数是next。
模拟登陆 中间件
app.js中添加中间件逻辑代码
app.use(async(ctx, next) => {
const query = ctx.query
if (query.user === 'zhangsan') {
// 模拟登陆成功
await next() // 执行下一个重甲件
} else {
// 登陆失败
ctx.body = "请登录"
}
})
user参数正确时
koa2洋葱圈模型
- 中间件机制,是koa2的精髓
- 每个中间件都是async函数
- 中间件的运行机制,就像洋葱圈
洋葱圈模型和中间件模型的关系
- 中间件机制:业务模块的划分
- 洋葱圈模型:中间件的执行机制
- 两者要分开来看,不要混在一起
代码示例
// 演示 koa2 中间件的洋葱圈模型
const Koa = require('koa')
const app = new Koa()
// logger
app.use(async (ctx, next) => {
await next() // 执行下一个中间件
const rt = ctx.response.get('X-Response-Time') // 获取 时间差
console.log(`${ctx.method} ${ctx.url} - ${rt}`)
})
// x-response-time
app.use(async (ctx, next) => {
const start = Date.now()
await next() // 执行下一个中间件
const ms = Date.now() - start // 计算时间差,例如 80
ctx.set('X-Response-Time', `${ms}ms`) // 记录/设置 时间差
})
// response
app.use(async (ctx, next) => {
ctx.body = 'Hello world'
})
app.listen(3000)
console.log('koa2 已经开始监听 3000 端口')