Koa2基础笔记

news/2024/11/21 1:24:18/

目录

一、快速入门

二、中间件

链式调用

洋葱圈模型

异步处理

三、路由

koa-router

四、请求参数解析

处理URL参数

处理body参数

 五、错误处理

原生的错误处理

使用中间件


一、快速入门

新建文件夹使用VSCode打开,终端运行npm init -y生成package.json配置文件。安装koa,npm i koa。编写服务程序:src/start.js

1.导入koa包 2.实例化app对象 3.编写中间件 4.启动服务,监听3000端口

// 1.导入koa
const Koa=require('koa')
// 2.实例化对象
const app=new Koa()
// 3.编写中间件
app.use((ctx)=>{// ctx:context http请求的上下文(ctx.request:http请求 + ctx.response:http响应)ctx.body='hello koa2'
})
// 4.启动服务,监听3000端口
app.listen(3000,()=>{console.log('server is running on http://localhost:3000');
})

运行 node src/start.js 成功后显示http://localhost:3000

安装nodemon:npm i nodemon -D,运行 nodemon src/start.js。改变代码自动重启。

二、中间件

在请求和响应中间的处理程序;将从请求到响应的业务拆开成多个功能独立的函数,就是中间件;对于处理请求来说,在响应发出之前,可以在请求和响应之间做一些操作,并且将这个处理结果传递给下一个函数继续处理(类似工厂流水线)。

const Koa=require('koa')
const app=new Koa()
// 中间件
//简写可以省略app,写成app.use().use().use()
//在app.use中只能接收一个参数作为函数
app.use((ctx,next)=>{console.log('头部');next()
})
app.use((ctx,next)=>{console.log('身体');next()
})
app.use((ctx)=>{console.log('尾部');ctx.body='组装完成'
})
app.listen(3000,()=>{console.log('server is running on http://localhost:3000');
})

链式调用

app.use(function) 将给定的中间件方法添加到此应用程序;app.use()返回this,因此可以链式表达

洋葱圈模型

const Koa=require('koa')
const app=new Koa()
app.use((ctx,next)=>{console.log('1');next()console.log('2');
}).use((ctx,next)=>{console.log('3');next()console.log('4');
}).use((ctx,next)=>{console.log('5');ctx.body='处理完成'
})
// 输出 1 3 5 4 2
app.listen(3000,()=>{console.log('server is running on http://localhost:3000');
})

异步处理

依靠async await语法;async声明异步函数,await后跟promise对象。加了async的函数返回值会变为一个Promise对象

const Koa=require('koa')
const app=new Koa()
app.use(async (ctx,next)=>{
//middleware1中构造一个message=aactx.message='aa'await next()
//返回最终数据ctx.body=ctx.message
}).use(async (ctx,next)=>{
//middleware2中同步追加bbctx.message+='bb'await next()
}).use(async (ctx)=>{
//middleware3中异步追加ccconst res=await Promise.resolve('cc')ctx.message+=res
})
// 输出 aabbcc
app.listen(3000,()=>{console.log('server is running on http://localhost:3000');
})

三、路由

路由就是建立URL和处理函数之间的对应关系,用于根据不同的methods和URL返回不同的内容。

例如:使用postman测试接口,http://localhost:3000/users、GET方法返回’这是用户页’。

const Koa=require('koa')
const app=new Koa()
app.use((ctx)=>{// 编写时也可以省略request和response,直接写ctx.url ctx.bodyif(ctx.request.url=='/'){ctx.response.body='这是主页'}else if(ctx.request.url=='/users'){if(ctx.request.method=='GET')ctx.response.body='这是用户页'else if(ctx.request.method=='POST')ctx.response.body='创建用户'elsectx.response.status=405}else{ctx.response.status=404}
})
app.listen(3000)

koa-router

安装 npm i koa-router。使用:1.在koa的基础上导入koa-router包 2.实例化router对象 3.使用router处理路由 4.注册中间件

// 1.导入koa
const Koa=require('koa')
// 2.实例化对象
const app=new Koa()
// 3.使用koa-router
const Router=require('koa-router')
const router=new Router()
router.get('/',(ctx)=>{ctx.body='这是主页'
})
router.get('/users',(ctx)=>{ctx.body='这是用户页'
})
router.post('/users',(ctx)=>{ctx.body='创建用户'
})
// 4.注册中间件
app.use(router.routes())
// 支持返回405和501的错误
app.use(router.allowedMethods())
// 5.启动服务,监听3000端口
app.listen(3000,()=>{console.log('server is running on http://localhost:3000');
})

优化:

将一个模块放在单独的文件中,分离出一个router路由层。

1.创建src/router/user.route.js

2.将上面有关路由部分的代码放入此文件并进行导出module.exports=router

3.并在原文件中导入

const userRoute=require('./router/user.route')

app.use(userRoute.routes()).use(userRoute.allowedMethods())

四、请求参数解析

后端需要解析请求的参数,作为数据库操作的条件。接口设计:

1.获取对应id的用户信息GET/user/:id

2.查询年龄18-20的用户信息 GET/users?start=18&end=20

3.解析注册信息保存至数据库 POST/users{name:’a’,age:22}

对于不同的http请求,需要使用不同的方式携带参数;get请求在URL中以键值对传递,post/put/patch/delete请求在请求体中传递。

处理URL参数

1.query:在GET请求中,如果以键值对的形式传参,可以通过query得到。

2.params:在GET请求中,有些参数可以通过路由传参,可以通过params得到。

// 1.导入koa
const Koa=require('koa')
// 2.实例化对象
const app=new Koa()
// 3.使用koa-router
const Router=require('koa-router')
// 统一前缀
const router=new Router({prefix:'/users'})
const db=[{id:1,name:'a',age:18},{id:2,name:'b',age:20},{id:3,name:'c',age:22},
]
// 获取对应年龄的用户信息
router.get('/',(ctx)=>{// 赋默认值,值为空时不会出错const {start=0,end=0}=ctx.query //ctx.request.queryconst res=db.filter((item)=>item.age>=start&&item.age<=end)res.length==0?ctx.throw(404):(ctx.body=res)
})
// 获取对应id的用户信息
router.get('/',(ctx)=>{const id=ctx.params.idconst res=db.filter((item)=>item.id==id)// 找不到id 抛出错误if(!res[0]) ctx.throw(404)ctx.body=res[0]
})
router.post('/',(ctx)=>{ctx.body='创建用户'
})
// 4.注册中间件
app.use(router.routes())
// 支持返回405和501的错误
app.use(router.allowedMethods())
// 5.启动服务,监听3000端口
app.listen(3000,()=>{console.log('server is running on http://localhost:3000');
})

处理body参数

安装koa-body或koa-bodyparser,npm i koa-body

// 1.导入koa
const Koa=require('koa')
// 引入类要实例化,此处是函数,所以不需要
const { koaBody } = require('koa-body');
// 2.实例化对象
const app=new Koa()
// 在所有中间件注册前注册KoaBody
app.use(koaBody())
// 3.使用koa-router
const Router=require('koa-router')
// 统一前缀
const router=new Router({prefix:'/users'})
const db=[{id:1,name:'a',age:18},{id:2,name:'b',age:20},{id:3,name:'c',age:22},
]
router.post('/',(ctx)=>{db.push(ctx.request.body)ctx.body=db
})
// 4.注册中间件
app.use(router.routes())
// 支持返回405和501的错误
app.use(router.allowedMethods())
// 5.启动服务,监听3000端口
app.listen(3000,()=>{console.log('server is running on http://localhost:3000');
})

 五、错误处理

原生的错误处理

一般Koa中的错误分三类

1.404,当请求的资源找不到,或者没有通过ctx.body返回时,由koa自动返回。

2.手动抛出,通过ctx.throw手动抛出。

3.500,运行错误

Koa类是继承Node的Emitter类,因此可以通过emit提交一个错误,通过on进行统一错误处理。

// 1.导入koa
const Koa=require('koa')
// 引入类要实例化,此处是函数,所以不需要
const { koaBody } = require('koa-body');
// 2.实例化对象
const app=new Koa()
// 在所有中间件注册前注册KoaBody
app.use(koaBody())
// 3.使用koa-router
const Router=require('koa-router')
// 统一前缀
const router=new Router({prefix:'/users'})
router.get('/:id/article/:aid',(ctx)=>{console.log(ctx.params);if(false){ctx.body={id:1,title:'文章1',content:'文章1'}}else{return ctx.app.emit('error',{code:404,message:'Resource is not found'},ctx)}
})
// 4.注册中间件
app.use(router.routes())
// 支持返回405和501的错误
app.use(router.allowedMethods())
app.on('error',(err,ctx)=>{console.error(err)ctx.body=err
})
// 5.启动服务,监听3000端口
app.listen(3000,()=>{console.log('server is running on http://localhost:3000');
})

使用中间件

安装 npm i koa-json-error

基础用法

const Koa=require('koa')
const app=new Koa()
// 注册并使用
const error=require('koa-json-error')
app.use(error())
app.use((ctx)=>{ctx.body='a'
})
app.listen(3000)

高级用法

const Koa=require('koa')
const app=new Koa()
// 注册并使用
const error=require('koa-json-error')
app.use(error({format:(err)=>{return {code:err.status,message:err.message,result:err.stack}},// obj是format的对象,将format返回的三个值解构postFormat:(err,obj)=>{const {result,...rest}=obj// 生产环境只返回code和message,开发环境下将错误堆栈result也一并返回// 要实现功能,需安装npm i cross-env,配置package.json文件:// "scripts":{//     "dev":"nodemon src/index.js"//     "prod":"NODE_ENV=production node src/index.js"// }// 生产环境运行npm run prod 开发环境运行npm run devreturn process.env.NODE_ENV=='production'?rest:obj}
}))
app.use((ctx)=>{ctx.body='a'
})
app.listen(3000)

(视频:B站杰哥课堂)


http://www.ppmy.cn/news/724.html

相关文章

SSM框架学习记录-Spring_day01

1.核心概念 当前项目中的问题 下面代码的实现十分简单&#xff0c;但是业务层需要调用数据层的方法&#xff0c;就要在业务层new数据层的对象&#xff0c;如果数据层的实现类发生变化&#xff0c;业务层的代码也需要跟着改变&#xff0c;意味着要编译打包和重新部署 // 数据层实…

TF-IDF

2.TF - IDF&#xff1a;作用&#xff1a;提取出来一句话中词的重要性&#xff0c;分成两个部分&#xff1a; tf: 词频(某一类中词条出现的次数 / 该类中所有词条数目) idf: 逆文档频率&#xff08;作用&#xff1a;去掉逗号&#xff0c;的等&#xff09;公式&#xff1a;idf l…

Android S(31) APP 页面绘制流程

接上一篇app 启动流程调用OnCreate方法&#xff0c;页面布局绘制进入setContentView 1、加载布局setContentView() 这里getWindow()直接返回mWindow&#xff0c;这个早在onCreate 调用前Activity#attach里面完成初始化。 进入attach方法&#xff0c;构建一个窗体对象PhoneWind…

365天深度学习训练营-第P2周:彩色图片识别

目录 一、前言 二、我的环境 三、代码实现 1、数据下载以及可视化 2、CNN模型 3、训练结果可视化 4、随机图像预测 四、模型优化 1、CNN模型 2、VGG-16模型 3、Alexnet模型 4、Resnet模型 一、前言 >- **&#x1f368; 本文为[&#x1f517;365天深度学习训练营]…

12.01 M4-UART-IT实验

1.使用CORTEX-M4核&#xff0c;实验中断实验和串口实验结合--->上传到CSDN 按键触发时&#xff0c;LED灯状态取反&#xff0c;并且在串口工具打印一句话 KEY1按键按下&#xff0c;LED1状态取反&#xff0c;串口工具打印key1 down!!!! 主要代码gpio.c void HAL_GPI…

SpringBoot实用开发之热部署

目录 热部署 手动启动热部署 自动启动热部署 热部署范围布置 关闭热部署 热部署 能学到spring boot实用开发篇的相信都已经对IDEA和maven了如指掌了&#xff0c;我就基于这些前置知识来说一下热部署&#xff0c;其实也很简单。 手动启动热部署 首先可以在你的pom.xml文…

第二证券|汽车板块现涨停潮!多只地产债再涨到临停

在昨日大幅上涨后&#xff0c;今日上午A股商场持续上行&#xff0c;不过涨势放缓&#xff0c;到上午收盘&#xff0c;上证指数上涨0.21%。 昨日带动大市上行的地产板块今日上午涨势减缓&#xff0c;包含福星股份、世茂股份在内的多只地产股涨停。不过也有极少数地产股逆势跌落&…

Rust机器学习之Plotters

Rust机器学习之Plotters 本文将带领大家学习Plotters的基础用法。重点学习Plotters的图表元素和常用图表的使用。 本文是“Rust替代Python进行机器学习”系列文章的第四篇&#xff0c;其他教程请参考下面表格目录&#xff1a; Python库Rust替代方案教程numpyndarrayRust机器…