前言
🐻大家好我是一溪风月
程序员界的搬砖工,上篇文章我们学习和了解了Express
框架,这个框架相对于直接使用HTTP
模块而言,极大的提升了开发的效率和架构能力,接下来我们将会学习另外一个相对于Express
框架而言更加轻量且强大的,被称为下一代node.js
框架的koa
框架,事实上koa
框架和Express
是同一个团队开发的一个新的框架,主要特点如下:
- 目前团队的核心开发者TJ的主要精力也在
koa
,express已经交给团队维护了。 - Koa旨在为Web应用程序和API提供更小、更丰富和更强大的能力。
- 相对于express具有更强的异步处理能力(后续我们再对比)
- Koa的核心代码只有1600+行,是一个更加轻量级的框架
- 我们可以根据需要安装和使用中间件;
一.koa初体验
🤡当我们学习了Express
其实koa
相对来讲就会比较简单,因为他们的核心是相同的就是中间件
,首先我们使用koa
来搭建一个服务然后创建一个接口。
js
const koa = require('koa')
// 初始化koa
const app = new koa()
// 第一个中间件
app.use((ctx, next) => {
console.log("第一个中间件")
next()
})
// 第二个中间件
app.use((ctx, next) => {
console.log("第二个中间件")
//ctx.body = "Hello World!!!"
ctx.response.body = "HelloWorld!!!"
})
app.listen(9000, () => {
console.log("koa服务运行在9000端口")
})
然后我们试着使用apifox
来请求下接口:
😎我们可以看到,koa
和Express
的区别在于中间件的参数不一样koa
提供了两个参数,其中的一个参数是ctx
,它被称为上下文对象。
- koa并没有像express一样,将req和res分开,而是将它们作为ctx的属性。
- ctx代表一次请求的上下文对象。
- ctx.request:获取请求对象(koa提供的,如果想用HTTP提供的使用
ctx.req
)。 - ctx.response:获取响应对象(koa提供的,如果想用HTTP提供的使用
ctx.res
);
🐻next
本质上是一个dispatch
和之前的功能基本相同。
二.koa中间件
🤡中间件可以说是koa的核心了,但是和Express
不同的是,koa
只能通过use
来注册中间件,并且没有提供methods
方式也没有提供path
中间件来匹配路径,那么开发的时候我们怎么将路径和methods分离哪?我们主要有两种出来方式。
- 根据
request
自己进行判断(不推荐)
js
const koa = require('koa')
// 初始化koa
const app = new koa()
app.use((ctx, next) => {
if (ctx.request.path === '/user') {
if (ctx.request.method === 'POST') {
ctx.response.body = "创建用户成功"
} else {
ctx.response.body = "查询用户列表成功"
}
} else {
ctx.response.body = "其他接口返回内容"
}
})
app.listen(9000, () => {
console.log("koa服务运行在9000端口")
})
- 使用第三方路由中间件(推荐):koa官方并没有给我们提供路由库,我们可以使用第三方库
koa-router
我们先进行安装一下npm install @koa/router
js
const koa = require('koa')
const koaRouter = require('@koa/router')
// 初始化koa
const app = new koa()
const useRouter = new koaRouter({ prefix: '/user' })
useRouter.get('/', (ctx, next) => {
ctx.body = "用户列表"
})
useRouter.post('/', (ctx, next) => {
ctx.status = 201
ctx.body = "用户创建"
})
app.use(useRouter.routes())
app.use(useRouter.allowedMethods())
app.listen(9000, () => {
console.log("koa服务运行在9000端口")
})
三.koa参数解析
🥱解析参数parmas
和query
。
js
// localhost:9000/user/123
useRouter.get('/:id', (ctx, next) => {
console.log(ctx.params.id)
ctx.body = "HelloWorld"
})
查看下控制台结果,没有问题,直接在koa中就可以解析。
接下来我们进行query
的解析。
js
//localhost:9000/user/?name=1000&que=ttttt
useRouter.get('/', (ctx, next) => {
console.log(ctx.request.query)
ctx.body = "query查询"
})
我们使用如下这种方式进行请求然后看下结果。
🫥json
和x-www-form-urlencoded
的参数解析:对这两个参数的解析koa
里面不能直接进行解析,所以需要安装对应的第三方插件来解析
js
npm install koa-bodyparser
然后我们将它注册为中间件app.use(bodyParser())
然后就可以对上述的参数进行解析了
js
const koa = require('koa')
const bodyParser = require('koa-bodyparser')
// 初始化koa
const app = new koa()
// 注册中间件
app.use(bodyParser())
app.use((ctx, next) => {
console.log(ctx.request.body)
})
app.listen(9000, () => {
console.log("koa服务运行在9000端口")
})
至于x-www-form-urlencoded
的参数解析就不进行演示了,和json
的一摸一样,可以自己尝试下。
🥱到此为止我们还有一个传参方式没有进行解析那就是form-data
,这种方式的解析和上面两种也不一样,我们需要通过multer
进行解析,这个我们也比较熟悉,需要注意的点是拿请求参数的是通过http
的res
来获取的。
js
npm install koa-multer
js
const koa = require('koa')
const multer = require('koa-multer')
// 初始化koa
const app = new koa()
const upload = multer({})
app.use(upload.any())
app.use((ctx, next) => {
console.log(ctx.req.body)
ctx.body = "Helloworld"
})
app.listen(9000, () => {
console.log("koa服务运行在9000端口")
})
四.使用multer上传文件
😎文件上传的功能我们应该都不陌生了,在Express
中我们已经通过multer
成功的完成了这个功能,那么现在我们使用koa
来进行实现一遍。
js
const koa = require('koa')
const multer = require('koa-multer')
const Router = require('@koa/router')
const app = new koa()
// 文件上传
const useRouter = new Router()
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './uploads')
},
filename: function (req, file, cb) {
cb(null, file.originalname)
}
})
const upload = multer({ storage })
useRouter.post("/upload", upload.single('file'), (ctx, next) => {
console.log(ctx.req.file)
ctx.body = 'ok'
})
// 注册路由
app.use(useRouter.routes())
app.use(useRouter.allowedMethods())
app.listen(9000, () => {
console.log("koa服务运行在9000端口")
})
发送请求,我们可以看到文件上传成功了。
五.静态文件服务器
🫥和Express
一样,我们也可以使用koa来作为一个静态文件服务器,我们需要安装下第三方库:
arduino
npm install koa-static
然后我们直接作为一个中间件使用以下这个下载的内容
js
// 静态文件服务器
const koa = require('koa')
const app = new koa()
const static = require('koa-static')
app.use(static('./dist'))
app.listen(9001, () => {
console.log("服务成功启动")
})
我们访问下这个端口,可以发现部署成功了,其实我们平时开发在本地起服务的时候底层也是这么做的,是不是发现了这些奇妙的关联~
六.数据的响应
🐻在koa中我们对数据的响应一般使用的是ctx.body
或者ctx.reponse.body
这两者其实是同样的东西,前者是后者的简写方式,我们使用哪个都可以,可以将响应结果设置为如下之一
- string:字符串数据
- Buffer:Buffer数据
- Stream:流数据
- Object|| Array:对象或者数组
- null :不输出任何内容
- 如果response.status尚未设置,Koa会自动将状态设置为200或204。
js
ctx.response.body = "HelloWorld"
ctx.body = {
name:"xxx",
age:12,
gender:'女'
}
ctx.body = ["a","b","c","d","e"]
响应状态的设置和上边使用方法一样。
ini
ctx.status = 201
ctx.response.status = 200
七.koa错误处理
😂koa中的错误处理方式和Express中的不一样,在koa中进行错误的处理需要进行如下的操作
js
const koa = require("koa")
const app = new koa()
app.use((ctx,next)=>{
ctx.app.emit('error',new Error("哈哈哈"),ctx)
})
app.on('error',(err,ctx)=>{
console.log(err.message)
ctx.response.body = "哈哈哈"
})
app.listen(8000,()=>{
console.log("错误处理启动成功")
})
八.总结
😊在本章中我们学习了koa的基本使用及其错误处理,在下一节我们将详细介绍koa和Express的区别,以及洋葱模型相关的知识,相信随着我们一点点的学习我们会不断的进步,进而达到对自己的期待。