玩转Koa之koa-router原理解析

【玩转Koa之koa-router原理解析】一、前言
Koa为了保持自身的简洁 , 并没有捆绑中间件 。但是在实际的开发中 , 我们需要和形形色色的中间件打交道 , 本文将要分析的是经常用到的路由中间件 -- koa-router 。
如果你对Koa的原理还不了解的话 , 可以先查看Koa原理解析 。
二、koa-router概述
koa-router的源码只有两个文件:router.js和layer.js , 分别对应Router对象和Layer对象 。
Layer对象是对单个路由的管理 , 其中包含的信息有路由路径(path)、路由请求方法(method)和路由执行函数(middleware) , 并且提供路由的验证以及params参数解析的方法 。
相比较Layer对象 , Router对象则是对所有注册路由的统一处理 , 并且它的API是面向开发者的 。
接下来从以下几个方面全面解析koa-router的实现原理:
Layer对象的实现
路由注册
路由匹配
路由执行流程
三、Layer
Layer对象主要是对单个路由的管理 , 是整个koa-router中最小的处理单元 , 后续模块的处理都离不开Layer中的方法 , 这正是首先介绍Layer的重要原因 。

玩转Koa之koa-router原理解析


Layer构造函数主要用来初始化路由路径、路由请求方法数组、路由处理函数数组、路由正则表达式以及params参数信息数组 , 其中主要采用path-to-regexp方法根据路径字符串生成正则表达式 , 通过该正则表达式 , 可以实现路由的匹配以及params参数的捕获:
玩转Koa之koa-router原理解析


根据paramNames中的参数信息以及captrues方法 , 可以获取到当前路由params参数的键值对:
玩转Koa之koa-router原理解析


需要注意上述代码中的safeDecodeURIComponent方法 , 为了避免服务器收到不可预知的请求 , 对于任何用户输入的作为URI部分的内容都需要采用encodeURIComponent进行转义 , 否则当用户输入的内容中含有'&'、'='、'?'等字符时 , 会出现预料之外的情况 。而当我们获取URL上的参数时 , 则需要通过decodeURIComponent进行解码 , 而decodeURIComponent只能解码由encodeURIComponent方法或者类似方法编码 , 如果编码方法不符合要求 , decodeURIComponent则会抛出URIError , 所以作者在这里对该方法进行了安全化的处理:
玩转Koa之koa-router原理解析


Layer还提供了对于单个param前置处理的方法:
玩转Koa之koa-router原理解析


上述代码中通过some方法寻找单个param处理函数的原因在于以下两点:
保持param处理函数位于其他路由处理函数的前面;
路由中存在多个param参数 , 需要保持param处理函数的前后顺序 。
玩转Koa之koa-router原理解析


Layer中的setPrefix方法用于设置路由路径的前缀 , 这在嵌套路由的实现中尤其重要 。
最后 , Layer还提供了根据路由生成url的方法 , 主要采用path-to-regexp的compile和parse对路由路径中的param进行替换 , 而在拼接query的环节 , 正如前面所说需要对键值对进行繁琐的encodeURIComponent操作 , 作者采用了urijs提供的简洁api进行处理 。
四、路由注册
1、Router构造函数
首先看了解一下Router构造函数:
玩转Koa之koa-router原理解析


在构造函数中初始化的params和stack属性最为重要 , 前者用来保存param前置处理函数 , 后者用来保存实例化的Layer对象 。并且这两个属性与接下来要讲的路由注册息息相关 。

推荐阅读