Skip to main content

路由方法

keq 提供了灵活的路由机制,让中间件只对特定请求生效。通过 .apply() 链式 API,你可以精确控制中间件的作用范围。

.apply(...middlewares)

将一个或多个中间件应用到指定路由,返回链式配置对象,通过 .exclude().forRoutes() 定义匹配规则。

import { request } from "keq"

request
  .apply(authMiddleware, loggingMiddleware)
  .forRoutes({ host: "api.example.com" })

参数

  • middlewares - 一个或多个中间件函数

.forRoutes(...routes)

指定中间件生效的路由。多个路由之间为 OR 关系(任一匹配即生效)。

import { request } from "keq"

request
  .apply(rateLimitMiddleware)
  .forRoutes(
    { host: "api.example.com", method: "post" },
    { host: "api.example.com", method: "put" },
  )

参数

  • routes - 一个或多个 KeqRoutePattern 对象或 KeqRoute 谓词函数

KeqRoutePattern 字段

字段类型说明
hoststring匹配域名
methodstring匹配 HTTP 方法
pathnamestringglob(minimatch)模式匹配路径

单个 KeqRoutePattern 内多个字段之间为 AND 关系(所有字段都满足才匹配)。

// host AND method AND pathname 都需要匹配
request
  .apply(middleware)
  .forRoutes({ host: "api.example.com", method: "get", pathname: "/users/**" })

.forAllRoutes()

将中间件应用到所有路由。语义等价于无条件匹配,配合 .exclude() 可实现"全局生效但排除特定路由"。

import { request } from "keq"

// 全局应用
request
  .apply(loggingMiddleware)
  .forAllRoutes()

// 全局应用但排除健康检查
request
  .apply(loggingMiddleware)
  .exclude({ pathname: "/health" }, { pathname: "/ready" })
  .forAllRoutes()

.exclude(...routes)

排除特定路由。多个排除条件之间为 OR 关系(任一匹配则跳过)。

import { request } from "keq"

request
  .apply(authMiddleware)
  .exclude({ pathname: "/health" }, { pathname: "/ready" })
  .forRoutes({ host: "api.example.com" })

参数

  • routes - 一个或多个 KeqRoutePattern 对象或 KeqRoute 谓词函数

自定义 KeqRoute 谓词

除了 KeqRoutePattern 对象,还可以传入自定义谓词函数:

import { request } from "keq"
import type { KeqRoute } from "keq"

const hasDebugParam: KeqRoute = (ctx) => {
  return ctx.request.url.searchParams.has("debug")
}

request
  .apply(debugMiddleware)
  .forRoutes(hasDebugParam)

链式调用

.forRoutes().forAllRoutes() 返回 request 实例本身,支持连续链式注册多组路由中间件:

import { request } from "keq"

request
  .apply(authMiddleware)
    .forRoutes({ host: "api.example.com" })
  .apply(cacheMiddleware)
    .forRoutes({ host: "cdn.example.com" })
  .apply(loggingMiddleware)
    .exclude({ pathname: "/health" })
    .forAllRoutes()

综合示例

import { request } from "keq"

// 为 API 请求添加认证,但排除健康检查
request
  .apply(authMiddleware)
  .exclude({ pathname: "/health" }, { pathname: "/ready" })
  .forRoutes({ host: "api.example.com" })

// 为写操作添加请求日志
request
  .apply(logMiddleware)
  .forRoutes(
    { host: "api.example.com", method: "post" },
    { host: "api.example.com", method: "put" },
    { host: "api.example.com", method: "delete" },
  )

// 全局添加限流,排除内部路径
request
  .apply(rateLimitMiddleware)
  .exclude({ pathname: "/internal/**" })
  .forAllRoutes()

执行顺序

路由中间件按照注册的顺序执行。当请求匹配多个路由时,所有匹配的中间件都会按顺序执行:

request
  .apply(middleware1).forRoutes({ host: "api.example.com" })
  .apply(middleware2).forRoutes({ pathname: "/users/**" })
  .apply(middleware3).forRoutes({ method: "get" })

// 对于 GET https://api.example.com/users/123
// 执行顺序:middleware1 -> middleware2 -> middleware3 -> 内置中间件