Appearance
验证
¥Validation
Hono 只提供了一个非常薄的验证器。但是,当与第三方验证器结合使用时,它会非常强大。此外,RPC 功能允许你通过类型与客户端共享 API 规范。
¥Hono provides only a very thin Validator. But, 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
)
}除了 form 之外,验证目标还包括 json、query、header、param 和 cookie。
¥Validation targets include json, query, header, param and cookie in addition to form.
警告
验证 json 或 form 时,请求必须包含匹配的 content-type 标头(例如,json 必须包含 Content-Type: application/json)。否则,请求正文将不会被解析,你将在回调中收到一个空对象 ({}) 作为值。
¥When you validate json or form, the request must contain a matching content-type header (e.g. Content-Type: application/json for json). Otherwise, the request body will not be parsed and you will receive an empty object ({}) as value in the callback.
使用 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' }警告
验证 header 时,你需要使用小写名称作为键。
¥When you validate header, you need to use lowercase name as the key.
如果要验证 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 zodsh
yarn add zodsh
pnpm add zodsh
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 验证器中间件 使其更加容易。
¥You can use the Zod Validator Middleware to make it even easier.
sh
npm i @hono/zod-validatorsh
yarn add @hono/zod-validatorsh
pnpm add @hono/zod-validatorsh
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
}
)