了解koa
之前有写过一次用koa去搭建http服务。现在觉得我当时搭建的那个服务是真的垃圾,koa的灵魂东西没有用上。
首先,创建一个文件夹,打开命令行输入 npm init 生成一个package.json文件,从事前端人员都应该晓得这个是干嘛用的
然后创建一个app.js文件,这个文件是我们的主入口。
为什么说我之前写的是个垃圾呢?我个人感觉我之前没有把koa的生态圈插件和next方法玩转,尤其是next()方法。用过后才知道是真的好用。创建后目录如下:
接下来需要安装几个包
koa、koa-router、koa-bodyparser、nodemon
安装koa如:npm i koa
{
"name": "gyc",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "nodemon app.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"koa": "^2.12.1",
"koa-body": "^4.2.0",
"koa-bodyparser": "^4.3.0",
"koa-router": "^9.0.1",
"moment": "^2.26.0",
"nodemon": "^2.0.4"
}
}
把scripts 的start 改成用nodemon启动app.js
nodemon是一个热更新插件,意思就是修改文件后自动重启服务
接下来开始写app.js里面的东西
const Koa = require('koa')
const bodyParser = require('koa-bodyparser')
const koaBody = require('koa-body') // 解析文件
const app = new Koa()
app.proxy = true
app.use(koaBody({
multipart: true // 启用文件传输
}))
// 配置中间件
app.use(bodyParser())
app.use(async (ctx, next) => { // 初始接口记录日志
ctx.status = 200
ctx.body = 'hello koa'
})
app.on('error', (err, ctx) => {
console.error('server error', err, ctx)
})
app.listen(8011)
这个时候 使用npm run start 命令进行启动服务
我这边端口开的是8011 项目启动后 在浏览器上输入http://127.0.0.1:8011/
地址
将会出现我们写的返回值 ‘hello koa’
当页面返回正确后就表明我们这个服务已经搭成一个基础的案例了;
在这个例子中,我们只用输入http://127.0.0.1:8011
就会有响应 如果想变成 http://127.0.0.1:8011/login
就需要加上路由,路由就是刚才下载过的koa-router
接下来就可以看他的用法
首先,先引入router,注册一个请求为get的路由用router.get
参数1接收一个路径,参数2接收一个函数。注意看我第二个参数的函数 是不是和之前
app.use(async (ctx, next) => { // 初始接口记录日志 ctx.status = 200 ctx.body = 'hello koa' })
这个传入的一样。
然后我们用app.use()注册一下router 要不然路由写好了没有挂载到koa上也没用 对吧,怎么挂载呢直接就 app.use(router.routes())
router.allowedMethods() //若ctx.status为空或者404的时候,丰富response对象的header头.
接下来我们请求一下 http://127.0.0.1:8011/login
如果我们还有很多很多二级路径该咋整呢,比如 /index 、/app、/del
之类的总不能都写在app.js里面吧
那接下来就进行整改,整改完的目录如下
先看demo-app.js文件
这个应该不用详细讲解了,接下来看Index.js
这个router.use是在注册一级路由现在的路径变成了 http://127.0.0.1:8011/demo-app/login
,这样的分层级有利于项目的扩展,一般的话是一个功能一个文件,一个文件下面会有很多的api 比如 一个功能模块的增删改查,注册 ,登录 ,删除之类的。。。
在index.js中注册 完成后 我们去看app.js
这个时候引入的就不在是router模块了 而是我们刚才自己配置的router文件夹中的Index.js文件,index.js相当于一级路由 所有的子路由都需要在他那里注册
比如我现在新加了一个web模块,那我就创建一个demo-web.js的文件
然后再去index.js注册一下
就可以访问http://127.0.0.1:8011/demo-web/web-login
这个时候有没有发现代码还可以再继续优化下,我们先单看demo-app.js这个文件
好像可以把
async(ctx,next)=>{
ctx.status = 200
ctx.body = 'hello koa'
}
统一放在一个地方集中管理
先建一个controllers文件夹里面建一个demo-app.js文件,目录如下
把刚才router里面的逻辑代码放在demo-app.js里面
在routes里面的demo-app.js进行引入
ok 直接重启服务
接下来详细讲解下next()的用法
创建一个文件夹mimiddleware里面创建一个resultHandle文件
加上next()
再进行引入
再次请求
从第一个中间件开始执行,遇到next进入下一个中间件,如果没有了则回到原来的地方。
按照目前这个项目http://127.0.0.1:8011/demo-app/login
来理解,
先加载demo-app.js里面的方法 遇见了next() 加载 resultHandle里面的方法,如果没有了则回到dem-app.js里面继续运行,由于我的next()是在最下面进行调用的所以体会不出来,想要看效果则可以 在next()下面加个console然后在resultHandle里面加一个console就可以看出来了
tip:router.get('/login',DemoAppApi.demo_app,resultHandle)
后面可以跟无数个 resultHandle.
假如 router.get('/login',DemoAppApi.demo_app,resultHandle,a,b,c)
顺序则是
demo_app->resultHandle->a->b->c->demo_app
可以自己试试玩玩