Skip to content

验证

🌐 Validation

Hono只提供一个非常简洁的Validator。 然而,当与第三方Validator结合使用时,它可以非常强大。 此外,RPC功能允许你通过类型与客户端共享API规范。

🌐 Hono provides only a very thin Validator. However, it can be powerful when combined with a third-party Validator. In addition, the RPC feature allows you to share API specifications with your clients through types.

手动验证器

🌐 Manual validator

首先,引入一种无需使用第三方验证器即可验证传入值的方法。

🌐 First, introduce a way to validate incoming values without using the third-party Validator.

hono/validator 导入 validator

🌐 Import validator from hono/validator.

ts
import { validator } from 'hono/validator'

要验证表单数据,将 form 指定为第一个参数,回调函数作为第二个参数。在回调中,验证值并在最后返回验证后的值。validator 可以用作中间件。

🌐 To validate form data, specify form as the first argument and a callback as the second argument. In the callback, validates the value and return the validated values at the end. The validator can be used as middleware.

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') 获取已验证的值。

🌐 Within the handler, you can get the validated value with c.req.valid('form').

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

验证目标包括 jsonqueryheaderparamcookie,此外还包括 form

🌐 Validation targets include json, query, header, param and cookie in addition to form.

WARNING

当你验证 jsonform 时,请求 必须 包含匹配的 content-type 头(例如,Content-Type: application/json 用于 json)。否则,请求体将不会被解析,并且你将在回调中收到空对象 ({}) 作为值。

在使用 app.request() 进行测试时,设置 content-type 头是很重要的。

🌐 It is important to set the content-type header when testing using app.request().

给定一个这样的应用。

🌐 Given an application like this.

ts
const app = new Hono()
app.post(
  '/testing',
  validator('json', (value, c) => {
    // pass-through validator
    return value
  }),
  (c) => {
    const body = c.req.valid('json')
    return c.json(body)
  }
)

你的测试可以这样写。

🌐 Your tests can be written like this.

ts
// ❌ this will not work
const res = await app.request('/testing', {
  method: 'POST',
  body: JSON.stringify({ key: 'value' }),
})
const data = await res.json()
console.log(data) // {}

// ✅ this will work
const res = await app.request('/testing', {
  method: 'POST',
  body: JSON.stringify({ key: 'value' }),
  headers: new Headers({ 'Content-Type': 'application/json' }),
})
const data = await res.json()
console.log(data) // { key: 'value' }

WARNING

当你验证 header 时,你需要使用 小写 名称作为键。

如果你想验证 Idempotency-Key 头,你需要使用 idempotency-key 作为密钥。

🌐 If you want to validate the Idempotency-Key header, you need to use idempotency-key as the 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 new 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 new HTTPException(400, {
        message: 'Idempotency-Key is required',
      })
    }
    return { idempotencyKey }
  }),
  (c) => {
    const { idempotencyKey } = c.req.valid('header')
    // ...
  }
)

多个验证器

🌐 Multiple validators

你还可以包含多个验证器来验证请求的不同部分:

🌐 You can also include multiple validators to validate different parts of request:

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

使用 Zod

🌐 With Zod

你可以使用 Zod,这是一个第三方验证器。我们建议使用第三方验证器。

🌐 You can use Zod, one of third-party validators. We recommend using a third-party validator.

从 Npm 注册表安装。

🌐 Install from the Npm registry.

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

zod 导入 z

🌐 Import z from zod.

ts
import * as z from 'zod'

编写你的模式。

🌐 Write your schema.

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

你可以在回调函数中使用模式进行验证并返回验证后的值。

🌐 You can use the schema in the callback function for validation and return the validated value.

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 Validator Middleware

你可以使用 Zod Validator Middleware 来让它变得更简单。

🌐 You can use the Zod Validator Middleware to make it even easier.

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

🌐 And import zValidator.

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

并按如下方式编写。

🌐 And write as follows.

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

Standard Schema Validator Middleware

标准模式 是一个规范,提供了一个用于 TypeScript 验证库的通用接口。它由 Zod、Valibot 和 ArkType 的维护者创建,以便生态系统工具可以与任何验证库协作,而无需自定义适配器。

标准架构验证中间件 让你可以在 Hono 中使用任何兼容标准架构的验证库,使你能够选择自己偏好的验证器,同时保持一致的类型安全性。

🌐 The Standard Schema Validator Middleware lets you use any Standard Schema-compatible validation library with Hono, giving you the flexibility to choose your preferred validator while maintaining consistent type safety.

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

从包中导入 sValidator

🌐 Import sValidator from the package:

ts
import { sValidator } from '@hono/standard-validator'

使用 Zod

🌐 With Zod

你可以将 Zod 与标准 Schema 验证器一起使用:

🌐 You can use Zod with the Standard Schema validator:

sh
npm i zod
sh
yarn add zod
sh
pnpm add zod
sh
bun add zod
ts
import * as z from 'zod'
import { sValidator } from '@hono/standard-validator'

const schema = z.object({
  name: z.string(),
  age: z.number(),
})

app.post('/author', sValidator('json', schema), (c) => {
  const data = c.req.valid('json')
  return c.json({
    success: true,
    message: `${data.name} is ${data.age}`,
  })
})

使用 Valibot

🌐 With Valibot

Valibot 是 Zod 的轻量级替代方案,具有模块化设计:

sh
npm i valibot
sh
yarn add valibot
sh
pnpm add valibot
sh
bun add valibot
ts
import * as v from 'valibot'
import { sValidator } from '@hono/standard-validator'

const schema = v.object({
  name: v.string(),
  age: v.number(),
})

app.post('/author', sValidator('json', schema), (c) => {
  const data = c.req.valid('json')
  return c.json({
    success: true,
    message: `${data.name} is ${data.age}`,
  })
})

使用 ArkType

🌐 With ArkType

ArkType 提供用于运行时验证的 TypeScript 原生语法:

sh
npm i arktype
sh
yarn add arktype
sh
pnpm add arktype
sh
bun add arktype
ts
import { type } from 'arktype'
import { sValidator } from '@hono/standard-validator'

const schema = type({
  name: 'string',
  age: 'number',
})

app.post('/author', sValidator('json', schema), (c) => {
  const data = c.req.valid('json')
  return c.json({
    success: true,
    message: `${data.name} is ${data.age}`,
  })
})

Hono 中文网 - 粤ICP备13048890号