Validation
Hono fournit uniquement un validateur très léger. Il peut toutefois devenir puissant lorsqu'il est combiné à un validateur tiers. De plus, la fonctionnalité RPC permet de partager les spécifications de l'API avec vos clients grâce aux types.
Validateur manuel
Voyons d'abord comment valider les valeurs reçues sans utiliser de validateur tiers.
Importez validator depuis hono/validator.
import { validator } from 'hono/validator'Pour valider les données d'un formulaire, indiquez form comme premier argument et un callback comme deuxième argument. Dans ce callback, validez les valeurs et renvoyez les valeurs validées à la fin. Le validator peut être utilisé comme middleware.
app.post(
'/posts',
validator('form', (value, c) => {
const body = value['body']
if (!body || typeof body !== 'string') {
return c.text('Invalid!', 400)
}
return {
body: body,
}
}),
//...Dans le gestionnaire, vous pouvez récupérer la valeur validée avec c.req.valid('form').
, (c) => {
const { body } = c.req.valid('form')
// ... do something
return c.json(
{
message: 'Created!',
},
201
)
}Les cibles de validation comprennent json, query, header, param et cookie, en plus de form.
Attention
Lorsque vous validez json ou form, la requête doit contenir un en-tête content-type correspondant (par exemple Content-Type: application/json pour json). Sinon, le corps de la requête ne sera pas analysé et le callback recevra un objet vide ({}) comme valeur.
Il est important de définir l'en-tête content-type lors des tests avec app.request().
Avec une application comme celle-ci.
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)
}
)Vos tests peuvent s'écrire ainsi.
// ❌ 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' }Attention
Lorsque vous validez header, vous devez utiliser un nom en minuscules comme clé.
Pour valider l'en-tête Idempotency-Key, vous devez utiliser idempotency-key comme clé.
// ❌ 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')
// ...
}
)Plusieurs validateurs
Vous pouvez également combiner plusieurs validateurs pour valider différentes parties de la requête :
app.post(
'/posts/:id',
validator('param', ...),
validator('query', ...),
validator('json', ...),
(c) => {
//...
}
)Avec Zod
Vous pouvez utiliser Zod, l'un des validateurs tiers. Nous recommandons l'utilisation d'un validateur tiers.
Installez-le depuis le registre npm.
npm i zodyarn add zodpnpm add zodbun add zodImportez z depuis zod.
import * as z from 'zod'Écrivez votre schéma.
const schema = z.object({
body: z.string(),
})Vous pouvez utiliser le schéma dans le callback pour effectuer la validation et renvoyer la valeur validée.
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
)
}
)Middleware de validation Zod
Le middleware de validation Zod simplifie encore les choses.
npm i @hono/zod-validatoryarn add @hono/zod-validatorpnpm add @hono/zod-validatorbun add @hono/zod-validatorImportez ensuite zValidator.
import { zValidator } from '@hono/zod-validator'Puis écrivez comme suit.
const route = app.post(
'/posts',
zValidator(
'form',
z.object({
body: z.string(),
})
),
(c) => {
const validated = c.req.valid('form')
// ... use your validated data
}
)Middleware de validation Standard Schema
Standard Schema est une spécification qui fournit une interface commune aux bibliothèques de validation TypeScript. Créée par les mainteneurs de Zod, Valibot et ArkType, elle permet aux outils de l'écosystème de fonctionner avec n'importe quelle bibliothèque de validation sans adaptateurs spécifiques.
Le middleware de validation Standard Schema permet d'utiliser avec Hono n'importe quelle bibliothèque compatible Standard Schema. Vous pouvez ainsi choisir votre validateur préféré tout en conservant une sécurité de typage cohérente.
npm i @hono/standard-validatoryarn add @hono/standard-validatorpnpm add @hono/standard-validatorbun add @hono/standard-validatorImportez sValidator depuis le paquet :
import { sValidator } from '@hono/standard-validator'Avec Zod
Vous pouvez utiliser Zod avec le validateur Standard Schema :
npm i zodyarn add zodpnpm add zodbun add zodimport * 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}`,
})
})Avec Valibot
Valibot est une alternative légère à Zod avec une conception modulaire :
npm i valibotyarn add valibotpnpm add valibotbun add valibotimport * 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}`,
})
})Avec ArkType
ArkType propose une syntaxe native TypeScript pour la validation à l'exécution :
npm i arktypeyarn add arktypepnpm add arktypebun add arktypeimport { 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}`,
})
})