服务器路由
事件处理器
事件处理器 是一个功能,它将绑定到一个路由,并在路由被路由器匹配到一个输入请求时执行。
文件系统路由
Nitro 支持基于文件的 API 路由(文件自动映射到 h3 路由)。定义一个路由只需要在 api/
或 routes/
目录中创建一个文件。
每个文件只能定义一个处理程序,你可以 将 HTTP 方法附加 到文件名,以定义一个特定的请求方法。
api/
test.ts <-- /api/test
routes/
hello.get.ts <-- GET /hello
hello.post.ts <-- POST /hello
nitro.config.ts
你可以通过创建子目录来嵌套路由。
routes/
communities/
index.get.ts
index.post.ts
[id]/
index.get.ts
index.post.ts
hello.get.ts
hello.post.ts
api/
目录作为特性,因此放置在 /api
中的路由将无法工作。
你必须使用 routes/api/
。简单路由
首先,在 routes/
或 api/
目录中创建一个文件。文件名将成为路由路径。
然后,导出一个用 defineEventHandler
包装的函数,当路由匹配时将被执行。
export default defineEventHandler(() => {
return { hello: 'API' }
})
带参数的路由
单个参数
要定义具有参数的路由,请使用 [<param>]
语法,其中 <param>
是参数的名称。该参数将可在 event.context.params
对象中使用,或使用来自 unjs/h3 的 getRouterParam
工具。
export default defineEventHandler(event => {
const name = getRouterParam(event, 'name')
return `Hello ${name}!`
})
调用带参数的路由 /hello/nitro
,你将得到:
Hello nitro!
多个参数
你可以使用 [<param1>]/[<param2>]
语法在一个路由中定义多个参数,其中每个参数是一个文件夹。你 不能 在单个文件名或文件夹中定义多个参数。
export default defineEventHandler(event => {
const name = getRouterParam(event, 'name')
const age = getRouterParam(event, 'age')
return `Hello ${name}! You are ${age} years old.`
})
捕获所有参数
你可以使用 [...<param>]
语法捕获 URL 的所有剩余部分。这将包括参数中的 /
。
export default defineEventHandler(event => {
const name = getRouterParam(event, 'name')
return `Hello ${name}!`
})
调用带参数的路由 /hello/nitro/is/hot
,你将得到:
Hello nitro/is/hot!
特定请求方法
你可以将 HTTP 方法附加到文件名,以强制路由仅匹配特定的 HTTP 请求方法,例如 hello.get.ts
只会匹配 GET
请求。你可以使用任何你想要的 HTTP 方法。
// routes/users/[id].get.ts
export default defineEventHandler(async (event) => {
const id = getRouterParam(event, 'id')
// 做一些与 id 相关的操作
return `User profile!`
})
捕获所有路由
你可以创建一个特殊的路由,匹配所有未被任何其他路由匹配的路由。这对于创建默认路由很有用。
要创建捕获所有路由,在 routes/
或 api/
目录中或任何子目录中创建一个名为 [...].ts
的文件。
export default defineEventHandler(event => {
const url = getRequestURL(event)
return `Hello ${url}!`
})
环境特定处理程序
你可以通过在文件名后添加 .dev
、.prod
或 .prerender
后缀,指定仅在特定构建中包含的路由,例如:routes/test.get.dev.ts
或 routes/test.get.prod.ts
。
handlers[]
配置的编程注册路径,指定多个环境或使用预设名称作为环境。中间件
Nitro 路由中间件可以钩入请求生命周期。
中间件在 middleware/
目录内自动注册。
routes/
hello.ts
middleware/
auth.ts
logger.ts
...
nitro.config.ts
简单中间件
中间件的定义与路由处理程序完全相同,唯一的例外是在于它们不应返回任何内容。 从中间件返回的内容会像从请求返回一样 - 返回的值将作为响应返回,后续代码将不再运行。
export default defineEventHandler((event) => {
// 扩展或修改事件
event.context.user = { name: 'Nitro' }
})
在 middleware/
目录中的中间件会自动注册到所有路由。如果你想为特定路由注册中间件,请参见 对象语法事件处理程序。
路由元信息
你可以在构建时通过 defineRouteMeta
微功能在事件处理程序文件中定义路由处理程序元信息。
defineRouteMeta({
openAPI: {
tags: ["test"],
description: "Test route description",
parameters: [{ in: "query", name: "test", required: true }],
},
});
export default defineEventHandler(() => "OK");
执行顺序
中间件按目录列表顺序执行。
middleware/
auth.ts <-- 第一个
logger.ts <-- 第二个
... <-- 第三个
使用数字作为前缀来控制它们的执行顺序。
middleware/
1.logger.ts <-- 第一个
2.auth.ts <-- 第二个
3.... <-- 第三个
1.filename.ts
、2.filename.ts
和 10.filename.ts
,那么 10.filename.ts
将在 1.filename.ts
之后。如果你有超过 10 个中间件在同一目录中,可以将 1-9
前缀加上 0
,比如 01
。请求过滤
中间件在每个请求上执行。
应用自定义逻辑,以将它们范围缩小到特定条件。
例如,你可以使用 URL 为特定路由应用中间件:
export default defineEventHandler((event) => {
// 仅在 /auth 路由执行
if (getRequestURL(event).pathname.startsWith('/auth')) {
event.context.user = { name: 'Nitro' }
}
})
路由规则
Nitro 允许你在配置的顶层为每个路由添加逻辑。它可以用于重定向、代理、缓存和向路由添加头信息。
它是从路由模式(遵循 unjs/radix3)到路由选项的映射。
当设置 cache
选项时,匹配模式的处理程序将自动包裹在 defineCachedEventHandler
中。请参见 缓存指南 以了解有关此功能的更多信息。
swr: true|number
是 cache: { swr: true, maxAge: number }
的简写。你可以使用 routeRules
选项在 nitro.config.ts
中设置路由规则。
export default defineNitroConfig({
routeRules: {
'/blog/**': { swr: true },
'/blog/**': { swr: 600 },
'/blog/**': { static: true },
'/blog/**': { cache: { /* 缓存选项 */ } },
'/assets/**': { headers: { 'cache-control': 's-maxage=0' } },
'/api/v1/**': { cors: true, headers: { 'access-control-allow-methods': 'GET' } },
'/old-page': { redirect: '/new-page' },
'/old-page/**': { redirect: '/new-page/**' },
'/proxy/example': { proxy: 'https://example.com' },
'/proxy/**': { proxy: '/api/**' },
}
})