当前位置: 首页 > 编程日记 > 正文

理解koa-router 路由一般使用

阅读目录

  • 一:理解koa-router一般的路由
  • 二:理解koa-router命名路由
  • 三:理解koa-router多个中间件使用
  • 四:理解koa-router嵌套路由
  • 五:分割路由文件
回到顶部

一:理解koa-router一般的路由

koa-router是koa的路由库,什么是路由库呢?比如当我们访问 http://localhost:3001/ 的时候,浏览器就会显示index页面的内容(一般默认是index)。如果当用户访问 http://localhost:3001/home 的时候,浏览器就会显示home页面的内容。

假如要实现上述功能,如果我们不使用 koa-router 或者其他路由中间件的话,我们一般需要在app.js如下代码编写:

const Koa = require('koa');
const app = new Koa();const route = (ctx, next) => {console.log(ctx.path);switch (ctx.path) {case '/':ctx.body = '<h1>欢迎光临index page 页面</h1>';break;case '/home':ctx.body = '<h1>欢迎光临home页面</h1>';break;default:// 404页面return;}
}app.use(route);app.listen(3001, () => {console.log('3001 server start....');
});

然后我们在node命令行中 执行 node app.js 的时候就启动服务器。

当我们访问 http://localhost:3001/ 的时候,页面显示index page 信息,如下图所示:

当我们访问 http://localhost:3001/home 的时候,就显示 欢迎光临home页面的信息。如下图所示:

这种方式不是很好,当我们项目变得很大的时候,我们需要编写很多 switch-case 这样的语句,代码变得更加耦合,并且当我需要对某个路由要加一个中间件过滤下的时候,这种方式并不好处理。并且当项目非常大的时候,我们不想把所有的路由编写的一个app.js 页面的时候,我们需要写到routes文件夹下多个js里面去,也就是说对路由进行分层级的时候,这样做的目的就是想让以后项目路由管理更加方便。那么目前的app.js中的switch-case 这种方式不支持了,因此我们这个时候就需要koa-router这样的中间件来做这件事情了哦。

因此我们现在需要安装 koa-router 模块了。命令如下:

npm install --save koa-router

通过 npm install supervisor --save-dev 安装supervisor模块, 用于node热启动.

package.json 代码如下:

{"name": "routers","version": "1.0.0","description": "","main": "index.js","scripts": {"start": "supervisor app.js"},"author": "","license": "ISC","devDependencies": {"koa": "^2.7.0","koa-router": "^7.4.0","supervisor": "^0.12.0"}
}

然后我们把app.js 代码改成如下了:

const Koa = require('koa');
const app = new Koa();const router = require('koa-router')();// 添加路由
router.get('/', ctx => {ctx.body = '<h1>欢迎光临index page 页面</h1>';
});router.get('/home', ctx => {ctx.body = '<h1>欢迎光临home页面</h1>';
});router.get('/404', ctx => {ctx.body = '<h1>404...</h1>'
});// 加载路由中间件
app.use(router.routes());app.listen(3001, () => {  console.log('server is running at http://localhost:3001');
});

同样在node命令行中 运行命令 node app.js, 然后在浏览器下访问 http://localhost:3001/ 或 http://localhost:3001/home 或 http://localhost:3001/404 的时候就会加载到对应路由的页面了。

如上是koa-router 中get方法请求,koa-router也支持处理其他的请求方法,如下:

router.post('/users', ctx => {// ....
})
.put('/user/:id', ctx => {// ....
})
.del('/user/:id', ctx => {// ....
})
.all('/user/:id', ctx => {// ....
});

如上demo实列中,我们可以看到有一个all方法,该方法通常用于匹配一组路由或者全部路由可以做一些统一的设置操作。

const Koa = require('koa');
const app = new Koa();const router = require('koa-router')();// 添加路由
router.get('/', (ctx, next) => {ctx.body = '<h1>欢迎光临index page 页面</h1>';next();
});router.get('/home', ctx => {ctx.body = '<h1>欢迎光临home页面</h1>';
});router.get('/404', ctx => {ctx.body = '<h1>404...</h1>'
});// all 方法
router.all('/', (ctx, next) => {console.log('match "all" method');next();
});
// 加载路由中间件
app.use(router.routes());app.listen(3001, () => {  console.log('server is running at http://localhost:3001');
});

如上代码,当我们运行 http://localhost:3001/ 刷新的时候,可以看到 在node命令行中也会打印 all方法的信息,但是要打印该信息的时候,有一个前提就是上一个中间件必须 next() 执行下,才会执行到下一个中间件上来,否则的话,all方法内部的代码也不会执行的。

回到顶部

二:理解koa-router命名路由

如下代码来简单的理解koa-router命名路由了。当我们在浏览器访问 http://localhost:3001/users/2 的时候,会打印 ctx.params = {'id': 2};并且会显示 'hello world';

const Koa = require('koa');
const app = new Koa();const router = require('koa-router')();// 添加命名路由
router.get('user', '/users/:id', (ctx, next) => {// 当我们在浏览器访问 http://localhost:3001/users/2 的时候,会打印 ctx.params = {'id': 2}console.log(ctx.params); // { id: '2' }ctx.body = 'hello world';
});// 加载路由中间件
app.use(router.routes());app.listen(3001, () => {  console.log('server is running at http://localhost:3001');
});
回到顶部

三:理解koa-router多个中间件使用

koa-router支持路由多个中间件的处理,通过这个特性,我们能够为一个路由添加中间件进行做一些操作的事情。比如如下代码:

const Koa = require('koa');
const app = new Koa();const router = require('koa-router')();// 添加命名路由
router.get('user', '/users/:id', (ctx, next) => {ctx.body = 'hello world';// 比如一个异步的操作,执行一些处理setTimeout(() => {ctx.user = {'id': 11};next(); // 把执行权转交给下一个中间件}, 100);
}, (ctx, next) => {// 在该中间件可以对数据进行一些操作等事情,console.log(ctx.user); // 会打印 {'id': 11}
});// 加载路由中间件
app.use(router.routes());app.listen(3001, () => {  console.log('server is running at http://localhost:3001');
});

当我们在浏览器运行 http://localhost:3001/users/1 的时候,会显示 'hello world'文案,并且在node命令行中会打印 {'id': 11}。

回到顶部

四:理解koa-router嵌套路由

我们可以在我们项目中定义很多路由,然后把这些路由组装起来。最后我们访问这些路由的时候,都可以支持。什么意思呢?
我们来简单的做个demo。如下代码:

const Koa = require('koa');
const app = new Koa();// 初始化 router1
const router1 = require('koa-router')();// 初始化 router2
const router2 = require('koa-router')();// 使用router1做一些事情
router1.get('/', (ctx, next) => {ctx.body = 'router1';next();
});
router1.get('/:id', (ctx, next) => {console.log(22222222);console.log(ctx.params);next();
});// 使用router2嵌套router1
router2.use('/user/:id/xxx', router1.routes(), router1.allowedMethods());// 加载路由中间件
app.use(router2.routes());app.listen(3001, () => {  console.log('server is running at http://localhost:3001');
});

当我们访问 http://localhost:3001/user/1/xxx 这个的时候,就可以匹配到 第一个 router1.get('/', (ctx, next) => {}) 这个路由到,当我们访问 http://localhost:3001/user/1/xxx/x 的时候,就可以匹配到 router1.get('/:id', (ctx, next) => {}) 这个路由到了,其中/:id 就是命名路由了。不管是 /x 还是 /(任意的路径都是支持的)。也就是说 router1路由嵌套到router2路由里面了,只要访问 router2中的路由路径'http://localhost:3001/' + '/user/:id/xxx' 这样的路径的时候,就可以自动把router1的路径匹配到。也就是可以理解 router2是路由路径的前缀。

回到顶部

五:分割路由文件

比如现在项目的目录结构如下:

|----- 项目
| |-- node_modules     # 依赖的包文件
| |-- routes           # 所有的路由文件
| | |-- index.js       # 路由入口文件
| | |-- router1.js     # router1.js 路由文件
| | |-- router2.js     # router2.js 路由文件
| |-- app.js           # 项目启动的文件
| |-- package.json

如上目录结构,app.js 文件是启动代码文件,代码如下:

const Koa = require('koa');
const app = new Koa();const router = require('./routes/index');// 加载路由中间件
app.use(router.routes(), router.allowedMethods());app.listen(3001, () => {  console.log('server is running at http://localhost:3001');
});

routes 文件夹包含所有的路由文件,routes/index.js 是路由的入口路由文件,在app.js 会引入该文件,代码如上,该文件的作用是读取所有的路由的文件,并且对每个路由进行注册。
routes/index.js 代码如下:

const router = require('koa-router')();
const fs = require('fs');
const path = require('path');
const files = fs.readdirSync(__dirname);
/*/^[^\.].*\.js/ 该正则匹配以.js末尾的文件,包括比如: a.js,/xx/yy/x.js 类似的多个目录文件,只要以 .js 末尾的即可。/^[^\.].*\.js$/.test('a.js'); // true/^[^\.].*\.js$/.test('/xx/yy/a.js'); // true
*/
files.filter(file => ~file.search(/^[^\.].*\.js$/)).forEach(file => {// 获取文件名 比如 xx.js 这样的,截取 file.substr(0, file.length - 3); 因为 .js 长度为3const fileName = file.substr(0, file.length - 3);/* 获取每个路由的全局路径,比如文件夹 routes下的 router1.js.router1.js 代码如下:const router = require('koa-router')();router.get('/', (ctx, next) => {ctx.body = 'hello world';});router.get('/home', (ctx, next) => {ctx.body = '欢迎光临home页面';});module.exports = router;然后对每个路由进行注册*/const fileEntity = require(path.join(__dirname, file));if (fileName !== 'index') {router.use(`/${fileName}`, fileEntity.routes(), fileEntity.allowedMethods());
  }
});module.exports = router;

routes/router1.js 是其中一个路由文件,代码如下:

const router = require('koa-router')();router.get('/', (ctx, next) => {ctx.body = 'hello world';
});router.get('/home', (ctx, next) => {ctx.body = '欢迎光临home页面';
});module.exports = router;

routes/router2.js 是另外一个路由文件,代码如下:

const router = require('koa-router')();router.get('/', (ctx, next) => {ctx.body = '已经进入router2页面了';
});router.get('/detail', (ctx, next) => {ctx.body = '已经进入详情页面了';
});module.exports = router;

当我们访问 http://localhost:3001/router1 的时候,会打印 "hello world", 如下图所示:

当我们访问 http://localhost:3001/router1/home 的时候,会打印 "欢迎光临home页面", 如下图所示:

当我们访问 http://localhost:3001/router2 的时候,会打印出 "已经进入router2页面了", 如下图所示:

当我们访问 http://localhost:3001/router2/detail 的时候,会打印出 "已经进入详情页面了", 如下图所示:

github源码查看

转载于:https://www.cnblogs.com/tugenhua0707/p/10686634.html

相关文章:

Go 分布式学习利器(20)-- Go并发编程之多路选择和超时控制,channel的关闭和广播

Select 多路选择 基本使用语法如下&#xff1a; select { case ret : <-retCh1: //阻塞事件&#xff0c;等待channel1的消息t.Logf("result %s \n",ret) case ret : <-retCh2:t.Logf("result %s \n", rest) default :t.Error("return empty&q…

Java项目:网盘系统设计和实现(java+ssm+jpa)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 很多同学都有自己的网盘&#xff0c;方便存储一些java学习教程。该毕业设计实现了一个简易的网盘&#xff0c;包含文件上传和文件分享等功能。 后端技术采用了spring&#xff0c;spring mvc&#xff0c;JPA&…

快速学习的方法论

大多数人认为学习的快慢取决于学习者的天赋&#xff0c;实际上研究表明学习方法起着至关重要的作用。更深层次的知识加工&#xff0c;与时而反复的温故知新&#xff0c;在某些情况下会加倍你的学习效率。最近学习了如何快速学习的方法论&#xff0c;分享给大家。 是否能加速理解…

C#拉姆达(=)表达式

前言&#xff1a; 之前小猪曾经分享过自己对C#委托的一点理解 其实在使用委托的过程中我们会大量的使用拉姆达(>)表达式 介绍&#xff1a; "Lambda表达式"是一个匿名函数&#xff0c;是一种高效的类似于函数式编程的表达式&#xff0c;Lambda简化了开发中需要编写…

Python爬虫入门教程 57-100 python爬虫高级技术之验证码篇3-滑动验证码识别技术

滑动验证码介绍 本篇博客涉及到的验证码为滑动验证码&#xff0c;不同于极验证&#xff0c;本验证码难度略低&#xff0c;需要的将滑块拖动到矩形区域右侧即可完成。 这类验证码不常见了&#xff0c;官方介绍地址为&#xff1a;https://promotion.aliyun.com/ntms/act/captchaI…

FlameScope 更高级全面的火焰图

FlameScope 更高级全面的火焰图 文章目录FlameScope 更高级全面的火焰图安装步骤安装问题fix使用方式网飞(Netflix)开发的火焰图工具能够更好得呈现出一段时间内的服务器on/off cpu 的热力图。安装步骤 $ git clone https://github.com/Netflix/flamescope $ cd flamescope $ …

sql 基础--mysql 5 (6)

12.子查询 子查询进行过滤 mysql> select msg from pw_luck where name wang5-> ; ------ | msg | ------ | 1001 | | 1000 | | 1000 | | 100 | | 100 | ------ 5 rows in set (0.03 sec)mysql> select uid from pw_luck where msg in (select msg from pw_luck w…

Java项目:就业管理系统设计和实现(java+springboot+ssm)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 就业管理系统: 该毕业设计采用了spring boot&#xff0c;spring&#xff0c;spring mvc&#xff0c;mybatis作为后端技术框架&#xff0c;这些组合稳定抗打&#xff0c;前端使用了layui&#xff0c;界面美观…

算法设计与分析之循环与递归

前言&#xff1a;循环与递归可以说是算法设计中最基本但却也是最重要的工具方法。循环和递归对于学习过高级程序设计语言的人来说都并不陌生&#xff0c;但还是有必要仔细的探究一下循环和递归之间的相似和区别。循环与递归最大的相似之处莫不是在于他们在算法设计中的工具作用…

面向对象与软件工程---团队作业1

1.队伍名称&#xff1a; 遥遥万里&#xff08;还有很长路要走的意思&#xff09; 2.队员信息&#xff1a; 陈雄&#xff08;组长&#xff09; 学号&#xff1a;1700509024 博客园链接&#xff1a;https://www.cnblogs.com/bearchan/ 廖鹏辉 学号&#xff1a;1700802007 博客园…

从paxos到raft zab,为何raft能够“独领风骚”

文章目录RAFT出现的缘由RAFT 的实现STATE MACHINELog Replicated State MachineLeader Election基本角色关键变量基本选举过程Log Replicated基本概念基本操作SafetyLog Replication: Consistency checkLeader Election: Leader Completeness总结RAFT 和 ZAB 的对比参考文献:阅…

Java项目:前台+后台精品水果商城系统设计和实现(java+Springboot+ssm+mysql+jsp+maven)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 一、项目简述 本系统主要实现的功能有&#xff1a; 前台用户的登录注册&#xff0c;水果商品的展示&#xff0c;水果的购物车&#xff0c; 购物车新增结算等等&#xff0c;银行卡的支付绑定&#xff0c;收货…

Android屏幕像素密度适配详解

讲到像素密度&#xff0c;我们先要搞明白什么是像素密度&#xff0c;像素密度的字面上的意思为手机屏幕上一定尺寸区域内像素的个数。在Android开发中&#xff0c; 我们一般会使用每英寸像素密度&#xff08;dpi&#xff09;这样一个单位来表示手机屏幕的像素密度&#xff0c;d…

如让自己想学不好shell编程都困难?

众所周知&#xff0c;shell是linux运维必备的技术&#xff0c;必须要掌握&#xff0c;但是shell语法复杂&#xff0c;灵活&#xff0c;网友掌握了语法也不知道如何应用到实际运维中&#xff0c;老男孩培训shell编程给所有linux运维人员带来了学好shell的法宝,老男孩培训2014最新…

sqlserver可将字符转成数字再进行sum,如果varchar类型中存放的都是数字

sqlserver语法&#xff1a; select sum(cast(score as int)) as score from 表名; 注意&#xff1a;int是整型&#xff0c;在实际操作中根据自己需要的类型转换。转载于:https://www.cnblogs.com/MisMe/p/10690748.html

LSM 优化系列(六)-- 【ATC‘20】MatrixKV : NVM 的PMEM 在 LSM-tree的write stall和写放大上的优化

文章目录LSM 问题背景MatrixKV 设计细节整体架构介绍Matrix Container介绍ReceiverRowTableCompactorSpace managementColumn Compaction介绍对于Column Compaction的总结读加速 Cross-row Hint SearchMatrixKv 写入完整流程MatrixKV 读取完整流程MatrixKV 性能总结这篇论文大家…

Java项目:前台+后台在线考试系统设计和实现(java+Springboot+ssm+mysql+jsp+maven)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 一、项目简述 本系统主要实现的功能有&#xff1a; 学生以及老师的注册登录&#xff0c;在线考试&#xff0c;错题查询&#xff0c;学生管理&#xff0c;问题管理&#xff0c;错题管理&#xff0c;错题查询…

修改nginx服务器类型

通常nginx服务器不隐藏服务器类型及版本信息 curl -I http://www.aaa.com 获取web服务器的类型和版本代码 HTTP/1.1 200 OK Server: nginx nginx/0.8.53 Date: Tue, 14 Dec 2010 08:10:06 GMT Content-Type: text/html Content-Length: 151 Last-Modified: Mon, 13 Dec 2…

JS 自带函数

JS数组方法汇总 array数组元素的添加和删除js数组元素的添加和删除一直比较迷惑&#xff0c;今天终于找到详细说明的资料了&#xff0c;先给个我测试的代码^-^var arr new Array();arr[0] "aaa";arr[1] "bbb";arr[2] "ccc";//alert(arr.leng…

Flink学习笔记:Operators之CoGroup及Join操作

本文为《Flink大数据项目实战》学习笔记&#xff0c;想通过视频系统学习Flink这个最火爆的大数据计算框架的同学&#xff0c;推荐学习课程&#xff1a; Flink大数据项目实战&#xff1a;http://t.cn/EJtKhaz 1. Window CoGroup与Join 1.1回顾RDBMS各种join 假设有两个表A和B 1.…

Rocksdb 的优秀代码(二)-- 工业级 打点系统 实现分享

文章目录前言数据结构选型打点代码设计耗时打点请求计数打点打点总结前言 一个完善的分布式系统一定是需要完善的打点统计&#xff0c;不论是对系统内核 还是 对系统使用者都是十分必要的。系统的客户需要直观得看到这个系统的性能相关的指标来决定是否使用以及如何最大化使用…

JVM中可生成的最大Thread数量

最近想测试下Openfire下的最大并发数&#xff0c;需要开大量线程来模拟客户端。对于一个JVM实例到底能开多少个线程一直心存疑惑&#xff0c;所以打算实际测试下&#xff0c;简单google了把&#xff0c;找到影响线程数量的因素有下面几个&#xff1a; -Xms intial java heap s…

Java项目:在线电影售票系统设计和实现(java+Springboot+ssm+mysql+jsp+maven)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 一、项目简述 前台&#xff1a; 1、正在上映的电影浏览查看。 2、影院信息浏览查看。 3、新闻咨询信息浏览查看。 4、地域信息查看切换。 5、用户注册登录。 6、电影排期查看。 7、在线选座生成…

matlab正态分布

normrnd(mu, sigma, m,n) 返回m x n的随机数&#xff0c;正态分布均值mu&#xff0c;标准差sigma。 mvnrnd(mu, sigma, m) 返回m个随机数&#xff08;点&#xff09;&#xff0c;是多元正太分布&#xff0c;mu是均值向量&#xff0c;sigma是协方差。 x normrnd(0,4,1,100000);…

MYSQL语句

-- 一、管理数据库-- 1.1 创建数据库CREATE DATABASE day15; SHOW DATABASES; CREATE TABLE student( id INT, NAME VARCHAR(20), age INT); -- 查看表SHOW TABLES; -- 二、管理数据-- 1.1插入数据&#xff08;insert into&#xff09;-- 需求&#xff1a; 往学生表插入数据INS…

Intel Optane PMEM 概览

文章目录前言基本架构编程模型PMDK接口架构接口概览pmdk 安装开发文档汇总PMEM性能官方性能实测性能前言 随着以PCM 为存储单元的3D XPoint 非易失存储介质 不断精进的工艺&#xff0c;以及 上层硬件协议栈的飞速发展&#xff0c;为非易失内存这样硬件的出现提供了技术工艺基础…

Java项目:新闻发布系统(java+Springboot+ssm+mysql+maven)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 一、项目简述 功能&#xff1a; 区分为管理员用户和普通用户&#xff0c;管理员用户能删除评论&#xff0c; 调整新闻显示/隐藏&#xff0c;修改新闻&#xff0c;删除普通用户&#xff0c;普通用户能 登陆浏…

Linux下搭建Lotus Domino集群

Linux下搭建Lotus Domino 集群本文内容是Linux平台下Lotus Domino服务器部署案例&#xff08;http://chenguang.blog.51cto.com/350944/1334595&#xff09;的另一个模块&#xff0c;所以大家首先要有以上基础之后然后继续实验。集群是 Lotus Domino Server 提供的最重要特性之…

Centos下卸载openjdk并安装自定义jdk

1、查看是否安装了openjdk java -version 2、查看需要卸载的openjdk信息&#xff0c;其中只需要删除红色框标记的地方 rpm -qa | grep java 3、删除openjdk rpm -e --nodeps 需要删除的java组件 4、创建文件夹java mkdir java 5、到官网下载linux版本的jdk&#xff08;如果不能…

pmdk -- libpmemlog 介绍

文章目录1. libpmemlog 应用背景2. libpmemlog 使用方式2.1 基本接口2.2 接口使用3. Libpmemlog 性能3.1 write sys call 性能3.2 libpmemlog 性能1. libpmemlog 应用背景 本文介绍的是英特尔 傲腾持久化内存 pmdk中 的一个持久化日志的库。 我们正常系统中会将日志 形成一个…