choukin

V1

2022/07/23阅读:23主题:默认主题

[Nuxt 3] (九)服务器路由

不论是房子、星星或是沙漠,都因为看不见的东西而显得美丽! ———— 《小王子》

服务器路由

Nuxt 自动扫描 ~/server/api,~/server/routes, ~/server/middleware目录下的文件,以注册 支持API 和 服务器处理程序的热更新。

每个文件都需要通过defineEventHandler()导出一个默认的函数

应用程序可以直接返回JSON 数据,一个 Promise 或者使用 event.res.end() 来发送响应

例子

创建一个server/api/hello.ts文件:

export default defineEventHandler((event) => {
  return {
    api: 'works'
  }
})

限制你可以使用await $fetch('/api/hello') 来常规调用这个API

服务端路由

~/server/api 中的文件会自动在路由添加路由前缀 /api 如果不想添加 /api 前缀,你可以把他们放到~/server/routes 文件夹中。

例子:

export default defineEventHandler(() => 'Hello World!')

上面的例子,可以通过路由 /hello 访问,http://localhost:300/hello

服务端中间件

Nuxt 会自动读取 ~/server/middleware 中的文件为你的项目生成中间件。

中间件程序会在请求其他服务器路由前对请求进行检查,扩展,头部信息,记录请求,扩展请求对象等。

中间件处理程序不应该返回任何数据(也不要关闭或响应请求),仅仅检查或者扩展请求上下文,或抛出异常。

例子:

export default defineEventHandler((event) => {
  console.log('New request: ' + event.req.url)
})
export default defineEventHandler((event) => {
  event.context.auth = { user: 123 }
})

服务器辅助方法

服务器路由由unjs/h3赋能,它提供了一套辅助方法。

::ReadMore{link="https://www.jsdocs.io/package/h3#package-index-functions" title="Available H3 Request Helpers"} ::

你可以在~/server/utils 中添加更多的辅助方法。

使用示例

匹配路由参数

服务器路由可以在文件名中通过中括号来使用动态参数比如/api/hello/[name].ts,然后通过 event.context.params来获取。

Example:

export default defineEventHandler(event => `Hello, ${event.context.params.name}!`)

你可以使用 await $feetch(‘/api/hello/nuxt’) 请求API ,然后得到 Hello,nuxt!

匹配 HTPP Method

请求文件名称可以使用后缀 .get .post .put .delete 来匹配请求的 HTTP Method.

export default defineEventHandler(() => 'Test get handler')
export default defineEventHandler(() => 'Test post handler')

上面的例子,通过下列方式匹配到 /test

  • GET method: 返回 Test get handler
  • POST method: 返回 Test post handler
  • 其他 method: 返回 404 error

捕获所有路由

捕获所有路由有助于回退路由处理,例如,创建一个名字是 ~/server/api/foo/[...].ts的文件,会注册一个捕获全部的路由,用来匹配没有匹配的路由,比如/api/foo/bar/baz

例子:

export default defineEventHandler(() => `Default foo handler`)
export default defineEventHandler(() => `Default api handler`)

使用body来处理请求

export default defineEventHandler(async (event) => {
    const body = await useBody(event)
    return { body }
})

现在你可以使用 fetch('/api/submit', { method: 'post', body: { test: 123 } }) 方式调用这个API.

我们在文件名submit.post.ts中匹配post方式才能获取请求体,如果在一个get请求中使用useBody,会抛出一个 HTTP 错误405 method Not Allowed

使用query来处理请求

简单的 query /api/query?param1=a&param2=b

export default defineEventHandler((event) => {
  const query = useQuery(event)
  return { a: query.param1, b: query.param2 }
})

获取运行时的配置


export default defineEventHandler((event) => {
  const config = useRuntimeConfig()
  return { key: config.KEY }
})

获取请求的cookie

export default defineEventHandler((event) => {
  const cookies = useCookies(event)
  return { cookies }
})

进阶使用示例

使用嵌套路由

import { createRouter } from 'h3'

const router = createRouter()

router.get('/'() => 'Hello World')

export default router

发送数据流 (实验阶段)

注意: 这是一个实验性的特性,只能在Nodejs环境中使用.

import fs from 'node:fs'
import { sendStream } from 'h3'

export default defineEventHandler((event) => {
  return sendStream(event, fs.createReadStream('/path/to/file'))
})

返回一个传统的处理程序或者中间件

export default (req, res) => {
  res.end('Legacy handler')
}

使用unjs/h3可以支持对传统的支持,但是它建议你尽可能避免使用传统的方式处理。

export default (req, res, next) => {
  console.log('Legacy middleware')
  next()
}

永远不要将next()回调与async 或者返回Promise的传统中间件一起使用。

分类:

前端

标签:

HTML

作者介绍

choukin
V1