跳到內容

驗證

Hono 僅提供一個非常薄的驗證器。但是,當與第三方驗證器結合使用時,它會非常強大。此外,RPC 功能允許您通過類型與您的客戶端共享 API 規範。

手動驗證器

首先,介紹一種在不使用第三方驗證器的情況下驗證傳入值的方法。

hono/validator 引入 validator

ts
import { validator } from 'hono/validator'

要驗證表單資料,請將 form 指定為第一個參數,並將回調指定為第二個參數。在回調中,驗證該值並在最後返回經過驗證的值。validator 可以用作中介軟體。

ts
app.post(
  '/posts',
  validator('form', (value, c) => {
    const body = value['body']
    if (!body || typeof body !== 'string') {
      return c.text('Invalid!', 400)
    }
    return {
      body: body,
    }
  }),
  //...

在處理常式中,您可以使用 c.req.valid('form') 獲取經過驗證的值。

ts
, (c) => {
  const { body } = c.req.valid('form')
  // ... do something
  return c.json(
    {
      message: 'Created!',
    },
    201
  )
}

除了 form 之外,驗證目標還包括 jsonqueryheaderparamcookie

警告

當您驗證 header 時,您需要使用 **小寫** 名稱作為鍵。

如果您想驗證 Idempotency-Key 標頭,您需要使用 idempotency-key 作為鍵。

ts
// ❌ this will not work
app.post(
  '/api',
  validator('header', (value, c) => {
    // idempotencyKey is always undefined
    // so this middleware always return 400 as not expected
    const idempotencyKey = value['Idempotency-Key']

    if (idempotencyKey == undefined || idempotencyKey === '') {
      throw HTTPException(400, {
        message: 'Idempotency-Key is required',
      })
    }
    return { idempotencyKey }
  }),
  (c) => {
    const { idempotencyKey } = c.req.valid('header')
    // ...
  }
)

// ✅ this will work
app.post(
  '/api',
  validator('header', (value, c) => {
    // can retrieve the value of the header as expected
    const idempotencyKey = value['idempotency-key']

    if (idempotencyKey == undefined || idempotencyKey === '') {
      throw HTTPException(400, {
        message: 'Idempotency-Key is required',
      })
    }
    return { idempotencyKey }
  }),
  (c) => {
    const { idempotencyKey } = c.req.valid('header')
    // ...
  }
)

多個驗證器

您還可以包含多個驗證器來驗證請求的不同部分

ts
app.post(
  '/posts/:id',
  validator('param', ...),
  validator('query', ...),
  validator('json', ...),
  (c) => {
    //...
  }

使用 Zod

您可以使用 Zod,一種第三方驗證器。我們建議使用第三方驗證器。

從 Npm 註冊表中安裝。

sh
npm i zod
sh
yarn add zod
sh
pnpm add zod
sh
bun add zod

zod 引入 z

ts
import { z } from 'zod'

編寫您的模式。

ts
const schema = z.object({
  body: z.string(),
})

您可以在回調函式中使用該模式進行驗證並返回經過驗證的值。

ts
const route = app.post(
  '/posts',
  validator('form', (value, c) => {
    const parsed = schema.safeParse(value)
    if (!parsed.success) {
      return c.text('Invalid!', 401)
    }
    return parsed.data
  }),
  (c) => {
    const { body } = c.req.valid('form')
    // ... do something
    return c.json(
      {
        message: 'Created!',
      },
      201
    )
  }
)

Zod 驗證器中介軟體

您可以使用 Zod 驗證器中介軟體 使其更加容易。

sh
npm i @hono/zod-validator
sh
yarn add @hono/zod-validator
sh
pnpm add @hono/zod-validator
sh
bun add @hono/zod-validator

並引入 zValidator

ts
import { zValidator } from '@hono/zod-validator'

然後如下編寫。

ts
const route = app.post(
  '/posts',
  zValidator(
    'form',
    z.object({
      body: z.string(),
    })
  ),
  (c) => {
    const validated = c.req.valid('form')
    // ... use your validated data
  }
)

根據 MIT 許可發布。