ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

KOA框架基础知识分享

2021-12-22 11:00:31  阅读:277  来源: 互联网

标签:const KOA 中间件 app ctx 基础知识 koa router 分享


Koa 就是一种简单好用的 Web 框架,node可以在ssr服务端渲染,bff层,接口聚合,削减api,或处理api数据等方面应用,减小前端代码复杂度,为企业节省成本,让吞吐率更高。

 

本文是我在实际业务中,用koa框架作为BFF层(Back-end For Front-end),也叫中间层,聚合接口,压缩图片,提高系统页面性能实践后,针对其他同学,普及node、koa基础知识的文档。

 

本次分享的目的:

  • 让大家对node不再陌生
  • 能上手利用node参与一些性能优化,
  • 提升个人的技术能力和技术视野

 

以下是正文

 

一、简介

koa 是由 Express 原班人马打造的,致力于成为一个更小、更富有表现力、更健壮的 Web 框架。使用 koa 编写 web 应用,通过组合不同的 generator,可以免除重复繁琐的回调函数嵌套,并极大地提升错误处理的效率。koa 不在内核方法中绑定任何中间件,它仅仅提供了一个轻量优雅的函数库,使得编写 Web 应用变得得心应手。

 

二、KOA代码结构

koa 非常小巧,总共就 4 个文件,每个文件的功能也十分单一,文件名也清楚的反应了文件功能。

koa 的文件结构

├── application.js
├── context.js
├── request.js
└── response.js
复制代码
  • request.js

    主要针对 http 的 request 对象提供了改对象的大量的 get 方法,文件主要是用来获取 request 对象属性。

  • response.js

    主要针对 http 的 response 对象提供了该对象的大量 set 方法;该文件主要是用来设置 response 对象属性。

  • context.js

    koa 引入了上下文对象的概念,即 ctx,这里所谓的上下文对象实际上是 request 和 response 两个对象的并集,request 和 response 分别通过代理的形式,将自己的方法委托给 ctx。那样我们就可以用 ctx 同时操作两个对象,来简化操作。

  • application.js

    该文件是整个 koa 的核心,简单来说主要有两大功能: 挂载真实请求到 ctx 下,封装中间件的执行顺序

 

三、KOA和express的区别

于是二者的使用区别通过表格展示如下:

  koa(Router = require('koa-router')) express(假设不使用app.get之类的方法)
  koa(Router = require('koa-router')) express(假设不使用app.get之类的方法)
初始化 const app = new koa() const app = express()
实例化路由 const router = Router() const router = express.Router()
app级别的中间件 app.use app.use
路由级别的中间件 router.get router.get
路由中间件挂载 app.use(router.routes()) app.use('/', router)
监听端口 app.listen(3000) app.listen(3000)

上表展示了二者的使用区别,从初始化就看出koa语法都是用的新标准。在挂载路由中间件上也有一定的差异性,这是因为二者内部实现机制的不同。其他都是大同小异的了。

与 express,hapi,eggjs 比起来,koa 真的十分小巧,以至于不能称作一种框架,可以看做一种库,但这并不妨碍 koa 生态的发展。

express 当初也是大而全的框架,慢慢的把各种功能已中间件的形式抽离出来,koa 可以看做这种思想的一种实现。大而全的框架主要存在起初的学习成本高,功能冗余等问题,使用 koa 对于初次使用 nodejs 开发 web 的人员非常友好,对于初学者来说,建议从 koa 入手,使用不同的中间件来实现不同的功能,对于了解 web 开发有很大帮助。

四、中间件

1、什么是中间件?

中间件就是匹配路由(匹配任何路由或者特定的路由,其作用比如打印日志,查看权限)之前或者匹配路由完成之后所得一系列操作,功能有:
1.执行任何代码
2.修改请求和和响应对象
3.终结请求-响应循环
4.调用堆栈中的下一个中间件
通过next来实现

在express 中间件(Middleware) 是一个函数,它可以访问请求对象(request object(req)),响应对象(response object()res)和web应用中处理请求-相应循环流程中的中间件,一般被命名为next的变量。在Koa中中间件和express有点类似。

 

经典的洋葱图概念能很好的解释next的执行,请求从最外层进去,又从最里层出来。

 

 

中间件的功能包括:

  • 执行任何代码

  • 修改请求和响应请求对象

  • 终结请求-响应循环

  • 调用堆栈中的下一个中间件

如果get、post回调函数中,没有next参数,那么就匹配上第一个路由,就不会往下匹配了。如果想往下匹配的话,那么就需要写next()。

app.use('/',function(){});

  不管app.userouter的书写顺序如何,都是先执行app.use再执行router

Koa应用可以使用如下几种中间件:

  • 应用级中间件

  • 路由级中间件

  • 错误处理中间件

  • 第三方中间件

可以写两个参数,第一个是匹配的路径,第二个是回调函数,第一个参数可以省略

 

五、实践

1、安装

检查node版本

$ node -v
v14.15.1

Koa 必须使用 7.6 以上的版本。如果你的版本低于这个要求,就要先升级 Node。

你可以使用自己喜欢的版本管理器快速安装支持的 node 版本:

$ nvm install 7
$ npm i koa
$ node my-koa-app.js

2、架设HTTP服务

const Koa = require('koa');
const app = new Koa();

// 本地服务
app.listen(3000, ()=>{
  console.log('http://localhost:3000')
})

显示Not Found,因为我们没有给内容,所以显示这个。

3、Context 对象

Koa 提供一个 Context 对象,表示一次对话的上下文(包括 HTTP 请求和 HTTP 回复)。

demo如下:

const Koa = require('koa');
const app = new Koa();

const main = ctx => {
  ctx.body = 'Hello 星火组';
};

app.use(main);
// 本地服务
app.listen(3000, ()=>{
  console.log('http://localhost:3000')
})

 

HTTP Response类型:

const Koa = require('koa');
const app = new Koa();
const fs = require('fs');

// const main = ctx => {
//   ctx.body = 'Hello 星火组';
// };

//HTTP Response 的类型
// const main = ctx => {
//   if (ctx.request.accepts('xml')) {
//     ctx.response.type = 'xml';
//     ctx.response.body = '<data>Hello World</data>';
//   } else if (ctx.request.accepts('json')) {
//     ctx.response.type = 'json';
//     ctx.response.body = { data: 'Hello World' };
//   } else if (ctx.request.accepts('html')) {
//     ctx.response.type = 'html';
//     ctx.response.body = '<p>Hello World</p>';
//   } else {
//     ctx.response.type = 'text';
//     ctx.response.body = 'Hello World';
//   }
// };

const main = ctx => {
  ctx.response.type = 'html';
  ctx.response.body = fs.createReadStream('template.html');
};

app.use(main);
// 本地服务
app.listen(3000, ()=>{
  console.log('http://localhost:3000')
})

 

node 项目实操查看ctx返回

https://koajs.com/#context。官方文档介绍。

 

4、router 路由

上面代码中,根路径/的处理函数是main/about路径的处理函数是about

const Koa = require('koa');
const route = require('koa-route');
const app = new Koa();

const about = ctx => {
  ctx.response.type = 'html';
  ctx.response.body = '<a href="/">Index Page</a>';
};

const main = ctx => {
  ctx.response.body = 'Hello World';
};

app.use(route.get('/', main));
app.use(route.get('/about', about));
app.listen(3000, ()=>{
  console.log('http://localhost:3000')


})

 5、中间件

// 引入Koa模块
const Koa = require('koa');
// 引入Koa-router
const Router = require('koa-router');
 
// 实例化Koa模块
const app = new Koa();
// 实例化路由模块
const router = new Router();
 
// Koa 中间件
// app.use('/',function(){});   //可以写两个参数,第一个是匹配的路径,第二个是回调函数,第一个参数可以省略
 
// 匹配任何路由之前打印日期
app.use(async (ctx,next)=>{
  console.log(new Date());
  await next();  //当前路由匹配完成以后继续向下匹配
});
 
// 配置路由
// ctx 上下文 context,  包含了request和response等信息
router.get('/',async (ctx)=>{
  ctx.body = '网站首页';  //返回数据    相当于:原生里面的res.writeHead()  res.end()
});
 
// 路由级中间件
// 匹配带news路由以后继续向下匹配路由
router.get('/news',async (ctx,next)=>{
  console.log('这是一个新闻路由');
  await next();
});
router.get('/news',async (ctx)=>{
  ctx.body = '新闻列表页面';
});
 
router.get('/login',async (ctx)=>{
  ctx.body = '网站登录页面';
});
 
// 启动路由
app
  .use(router.routes())   /*启动路由*/
  .use(router.allowedMethods());  //作用:当请求出错时处理逻辑
/*
 * router.allowedMethods()作用: 这是官方文档的推荐用法,我们可以
 * 看到 router.allowedMethods()用在了路由匹配 router.routes()之后,所以在当所有
 * 路由中间件最后调用.此时根据 ctx.status 设置 response 响应头
 *
 */
 
// 监听3000端口
app.listen(3000,()=>{
  console.log('starting at port 3000');
});

6、获取请求数据

const Koa = require('koa')
const app = new Koa()
const Router = require('koa-router')
const router = new Router()
 
router.get('/data', async (ctx , next)=> {
  let url = ctx.url
 
  // 从ctx的request中拿到我们想要的数据
  let data = ctx.request.query
  let dataQueryString = ctx.request.querystring
 
  ctx.body = {
    url,
    data,
    dataQueryString
  }
})
 
app.use(router.routes())
 
app.listen(3333, ()=>{
  console.log('server is running at http://localhost:3333')
})

在浏览器里输入http://localhost:3333/data?user=wuyanzu&id=123456 ,可以看到运行结果:

 

 

可以看到区别,.query返回的结果是对象,而.querystring返回的是字符串,这个很好理解。(chrome插件显示成json格式)

如果遵从 RESTful 规范,比如请求要以 '/user/:id'的方式发出的话,我们可以用下面的例子来获取到想要的数据。

router.get('/data/:id', async (ctx, next) => {
 
  // 也从ctx中拿到我们想要的数据,不过使用的是params对象
  let data = ctx.params
 
  ctx.body = data
})

浏览器运行 http://localhost:3333/data/4396 看到结果:

 

 以上,我们通过上面的代码和描述,已经对koa及node有一个初步的印象和概念。

 

课后作业:

用koa框架实现一个web页面。

进阶:本地json存储,实现增删改查。

 

参考:

KOA官网

【从前端到全栈】- koa快速入门指南

标签:const,KOA,中间件,app,ctx,基础知识,koa,router,分享
来源: https://www.cnblogs.com/youqiancheng/p/15718529.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有