路由与终结点
路由中间件是 Web 框架中用于将 HTTP 请求分发到对应处理逻辑(终结点)的核心组件。它负责解析请求路径、方法等信息,并根据预定义的路由规则,将请求映射到对应的处理函数或控制器。
快速启动
路由模块为我们提供了构建mini-api的能力,我们可用调用mapXXX开头的函数来构建终结点。
cangjie
import spire_web_http.*
import spire_web_hosting.*
import spire_web_routing.*
import spire_extensions_injection.*
main() {
let builder = WebHost.createBuilder()
builder.services.addRouting() // 注册路由所需要的服务
let host = builder.build()
// 注册终结点
host.mapGet("hello") { context =>
context.response.write("Hello Spire!")
}
// 表示支持任意谓词:get、post...
host.map("health") { context =>
context.response.write("healthy")
}
host.run()
return 0
}核心概念
- Route(路由):根据url匹配终结点的过程。
- Endpoint(终结点):服务端的动态资源。
- EndpointRouteBuilder(终结点构建器):我们可以通过扩展该来,来提供不同形式的终结点。(mvc中间件就是这样实现的)
- EndpointRoutingMiddleware(路由中间件):负责根据url匹配终结点,如果存在匹配的终结点,将保存到HttpContext上,其它中间件可以调用HttpContext.getEndpoint()来获取匹配的终结点。
- EndpointMiddleware(终结点中间件):负责执行终结点,如果HttpContext.getEndpoint()不为空,那么执行终结点。
接口授权
我们可以通过该案例,来获取路由中间件路由到的终结点。然后可以进行鉴权或其它操作,来决定后续操作。
cangjie
import spire_web_http.*
import spire_web_hosting.*
import spire_web_routing.*
import spire_extensions_injection.*
main() {
let builder = WebHost.createBuilder()
builder.services.addRouting()
let host = builder.build()
// 手动注册路由中间件
host.useRouting()
host.use { context, next =>
// 我们可以获取到路由中间件,设置到上下文上的终结点
if(let Some(endpoint) <- context.getEndpoint()) {
// 编写你的授权逻辑
if(context.request.path == "/hello") {
next() // 如果授权通过执行下一步操作
} else {
context.response.write("授权失败")
}
} else {
next()
}
}
host.mapGet("hello") { context =>
context.response.write("hello")
}
host.run()
return 0
}总结:
- 如果主动注册路由,那么
useEndpoints将不再注册路由中间件 useEndpoints会同时注册两个终结点,路由终结点和中间件终结点,并且还能用于构建终结点。- 之所以拆分为两个中间件,是为了实现在路由到终结点之后,和执行中节点中间件之前插入其它中间件(如授权)。此时我们可以手动注册路由中间件,来控制中间件的执行顺序。
tip:spire为我们提供了通用的授权中间件。
路由算法
ASP.NET Core使用DFA(Deterministic Finite Automaton,确定有限状态自动机)来实现高效的路由匹配,将传入的HTTP请求映射到相应的处理程序。spire移植了此算法。匹配性能接近O1,匹配过程不消耗CPU和堆栈。
支持的模式:
- 文本路径:
/home/index - 参数路径:
/home/index/{id} - 通配路径:
/home/{**path}