高木のブログ

【Hono】v3.0.0 からバリデーションの書き方が変わった

2023/02/19

Hono v3.0.0 がリリースされた!めでたい!

バリデーションの書き方が変わった

以前の Validator Middleware は廃止されて、薄いバリデーターしか提供されなくなった
サードパーティのバリデーターと組み合わせて使うと良いらしい
公式では Zod が推奨されていて、Zod Validator Middleware が用意されている

ちょうど手元に簡単なバリデーションを書いているものがあったので書き換えてみた

Before

import { Hono } from 'hono'
import { validator } from 'hono/validator'

const app = new Hono()

app.get(
  '/',
  validator((v) => ({
    tags: v.query('tags').isRequired().message('tags is a required parameter.'),
    associate_id: v.query('associate_id').isRequired().message('associate_id is a required parameter.'),
    count: v.query('count').isOptional().isNumeric().message('count must be numeric.'),
  })),
  async (c) => {
    const { tags, associate_id, count } = c.req.valid()
    // ...
  }
)

export default app

After

$ yarn add zod @hono/zod-validator
import { Hono } from 'hono'
import { z } from 'zod'
import { zValidator } from '@hono/zod-validator'

const app = new Hono()

app.get(
  '/',
  zValidator(
    'query',
    z.object({
      tags: z.string({ required_error: 'tags is a required parameter.' }),
      associate_id: z.string({ required_error: 'associate_id is a required parameter.' }),
      count: z.number({ invalid_type_error: 'count must be numeric.' }).optional(),
    }),
    (result, c) => {
      if (!result.success) {
        return c.text(result.error.issues.map(i => i.message).join('\n'))
      }
    }
  ),
  async (c) => {
    const { tags, associate_id, count } = c.req.valid('query')
    // ...
  }
)

export default app

所感

  • Zod が使えるのが良い(以前も使おうと思えば使えたのかな?)
  • バリデーションエラー時のレスポンスを変えたくなくて、以下のコードを追加したため以前よりコードが長くなってしまったのが気になる
(result, c) => {
  if (!result.success) {
    return c.text(result.error.issues.map(i => i.message).join('\n'))
  }
}

他にシンプルな書き方がないか引き続き調査、もしくはレスポンスを変えてしまうかの検討をしたい


SNS でシェアする


ytkg

Written by ytkg, Twitter, GitHub