服务端路由 Server Routes

Nitro 支持文件系统路由,可自动将文件映射到 h3 路由。

Event handlers

事件处理程序 是一个函数,它将被绑定到路由,并在路由器为传入请求匹配该路由时执行。

Filesystem routing

Nitro 支持基于文件的 API 路由(文件会自动映射到 h3 路由。定义路由非常简单,只需在 api/routes/ 目录中创建一个文件即可。

每个文件只能定义一个处理程序,并且可以将 HTTP 方法 附加到文件名以定义特定的请求方法。

md
api/
  test.ts      <-- /api/test
routes/
  hello.get.ts     <-- GET /hello
  hello.post.ts    <-- POST /hello
nitro.config.ts

如果你正在使用 Nuxt,请移动 server/api/server/routes/

一些提供商(例如 Vercel)使用顶级 api/ 目录作为功能,因此放置在 /api 中的路由将不起作用。 您必须使用 routes/api/

Simple routes

首先,在 routes/api/ 目录中创建一个文件。文件名将是路由路径。

然后,导出一个包装在 defineEventHandler 中的函数,该函数将在路由匹配时执行。

/api/test.ts
ts
export default defineEventHandler(() => {
  return { hello: 'API' }
})

Route with params

Single param

要定义带参数的路由,请使用 [<param>] 语法,其中 <param> 是参数的名称。该参数将在 event.context.params 对象中可用,或使用 unjs/h3 中的 getRouterParam 实用程序。

/routes/hello/[name].ts
ts
export default defineEventHandler((event) => {
  const name = getRouterParam(event, 'name')

  return `Hello ${name}!`
})

调用该路由并传入参数 /hello/nitro,你将得到:

Response
txt
Hello nitro!

Multiple params

您可以使用 [<param1>]/[<param2>] 语法在路由中定义多个参数,其中每个参数都是一个文件夹。您不能在单个文件夹文件名中定义多个参数。

/routes/hello/[name]/[age].ts
ts
export default defineEventHandler((event) => {
  const name = getRouterParam(event, 'name')
  const age = getRouterParam(event, 'age')

  return `Hello ${name}! You are ${age} years old.`
})

Catch all params

您可以使用 [...<param>] 语法捕获 URL 的所有剩余部分。这将包括参数中的 /

/routes/hello/[...name].ts
ts
export default defineEventHandler((event) => {
  const name = getRouterParam(event, 'name')

  return `Hello ${name}!`
})

使用参数 /hello/nitro/is/hot 调用路由,您将获得:

Response
txt
Hello nitro/is/hot!

Specific request method

您可以将 HTTP 方法附加到文件名,以强制路由仅与特定的 HTTP 请求方法匹配,例如 hello.get.ts 将仅与 GET 请求匹配。您可以使用任何您想要的 HTTP 方法。

js
GET
js
// routes/users/[id].get.ts
export default defineEventHandler(async (event) => {
  const id = getRouterParam(event, 'id')
  // 对 id 进行一些操作
  return `User profile!`
})

Catch all route

您可以创建一个特殊路由,该路由将匹配所有其他路由均未匹配的路由。这对于创建默认路由非常有用。

要创建捕获所有路由,请在routes/api/目录或任何子目录中创建一个名为[...].ts的文件。

/routes/[...].ts
ts
export default defineEventHandler((event) => {
  const url = getRequestURL(event)

  return `Hello ${url}!`
})

Environment specific handlers

该功能目前仅在 nightly 频道中可用。

您可以通过在文件名中添加.dev.prod.prerender后缀来指定仅包含在特定构建中的路由,例如:routes/test.get.dev.tsroutes/test.get.prod.ts

您可以通过handlers[]配置以编程方式注册路由来指定多个环境或指定预设名称作为环境。

Middleware

Nitro 路由中间件可以融入请求生命周期。

中间件可以在处理请求之前修改请求,而不是之后。

中间件在middleware/目录中自动注册。

md
routes/
  hello.ts
middleware/
  auth.ts
  logger.ts
  ...
nitro.config.ts

Simple middleware

中间件的定义与路由处理程序完全相同,唯一的不同之处在于它们不应返回任何内容。 从中间件返回的行为类似于从请求返回 - 该值将作为响应返回,并且不会运行进一步的代码。

middleware/auth.ts
ts
export default defineEventHandler((event) => {
  // 扩展或修改上下文
  event.context.user = { name: 'Nitro' }
})

middleware/ 目录中的中间件会自动为所有路由注册。如果要为特定路由注册中间件,请参阅对象语法事件处理程序

从中间件返回任何内容都会关闭请求,应避免!从中间件返回的任何值都将是响应,并且不会执行进一步的代码,但是不建议这样做!

Route Meta

您可以在构建时使用事件处理程序文件中的“defineRouteMeta”微程序定义路由处理程序元数据。

!NOTE 该功能目前仅在 nightly 频道中可用。

/api/test.ts
ts
defineRouteMeta({
  openAPI: {
    tags: ['test'],
    description: 'Test route description',
    parameters: [{ in: 'query', name: 'test', required: true }],
  },
})

export default defineEventHandler(() => 'OK')
相关阅读:https://swagger.io/specification/v3/此功能目前可用于指定 OpenAPI 元数据。请参阅 swagger 规范以了解可用的 OpenAPI 选项。

Execution order

中间件按照目录列表的顺序执行。

md
middleware/
  auth.ts <-- First
  logger.ts <-- Second
  ... <-- Third

在中间件前面加上数字来控制它们的执行顺序。

md
middleware/
  1.logger.ts <-- First
  2.auth.ts <-- Second
  3.... <-- Third

请记住,文件名是按字符串排序的,因此例如如果您有 3 个文件1.filename.ts2.filename.ts10.filename.ts,则10.filename.ts将位于1.filename.ts之后。 为避免这种情况,如果同一目录中有超过 10 个中间件,请在1-9前加上0,例如01

Request filtering

中间件在每个请求上执行。

应用自定义逻辑将其范围限定在特定条件下。

例如,您可以使用 URL 将中间件应用于特定路由:

middleware/auth.ts
ts
export default defineEventHandler((event) => {
  // 仅针对 /auh 路由执行
  if (getRequestURL(event).pathname.startsWith('/auth')) {
    event.context.user = { name: 'Nitro' }
  }
})

路由规则 Route Rules

Nitro 允许您在配置的每个路由的顶层添加逻辑。它可用于重定向、代理、缓存和向路由添加标头。

它是从路由模式(遵循 unjs/radix3)到路由选项的映射。

当设置 cache 选项时,匹配模式的处理程序将自动用 defineCachedEventHandler 包装。请参阅 guide cache 了解有关此功能的更多信息。

cache: { swr: true, maxAge: number } 缩写为 swr: true|number

您可以使用routeRules选项在nitro.config.ts中设置路由规则。

ts
nitro.config.ts
ts
export default defineNitroConfig({
  routeRules: {
    '/blog/**': { swr: true },
    '/blog/**': { swr: 600 },
    '/blog/**': { static: true },
    '/blog/**': { cache: { /* cache options */ } },
    '/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/**' },
  }
})