🔥

【Hono】フィルターを使って検索機能を作る

に公開

軽量webフレームワークのHonoを使用してクエリを作成しフィルター機能を使ってレスポンスのjsonを検索機能を実装します。

実装

エンドポイントはsearch?q=abcとします。データはJsonのnameを検索し、一致するものを返します。
まずHonoのconsextであるc:Contextを使って末尾の?q=textの文字を取り出します。
toLowerCase関数を使ってクエリの値をkeyword変数に格納します。

const q = (c.req.query('q') ?? '').trim()
const keyword = q.toLowerCase()

ここまでできたら最後にfilterを使用して、検索を行います。nameは検索するkeyに変更できます。たとえばageやidなど任意のものに変更できます。

 const result = data.filter((p) =>
        p.name.toLowerCase().includes(keyword)
    )
return c.json(result)

ハンドラー全体

import { Context } from 'hono'

export const searchHandler = async (c: Context) => {
    const q = (c.req.query('q') ?? '').trim()
    if (!q) return c.json([])

    const keyword = q.toLowerCase()

    const result = data.filter((p) =>
        p.name.toLowerCase().includes(keyword)
    )
    return c.json(result)
}

エラーやヒットしなかったときに対応する

さっきの実装で一応リストとして返すことはできるのですがこれだと実際の開発では不十分だと言われることがあります。そこでエラーハンドリングやヒットしなかった時の対応を考えて行きます。
ここでは要件として
ヒットした時は

{
    status:200
    message:"x件がヒットしました"
    item:{
        [
        // item
        ]
    }
}

エラー時は

{
    status:500
    message:"エラーが発生しました"
}

ヒットしなかった時は

{
    status:200
    message:"ヒットしませんでした"
    item:[]
}

これを返したいと思います。
まぁなんとなく察してる人もいるかと思いますが、条件分岐を使って実装しました。

///他のコード
if (result.length === 0) {
    return c.json({
        status: 200,
        message: "ヒットしませんでした",
        item: []
    })
}

resultの長さを取ってきて0件ならreturnをヒットしなかったという
resultが0件以上なら以下のようにします

return c.json({
    status: 200,
    message: `${result.length}件がヒット`,
    item: result
})

これでヒットしたかしていないかのハンドリングができました。
あとはstatus500の時(エラー時)の対応ですがこれはtry,catchで実現します。

try{
/// さっきのコードたち
} catch (error) {
    return c.json({
        status: 500,
        message: "エラーが発生しました"
    })
}

これで安全に返すことができます

全体

export const searchHandler = async (c: Context) => {
    try {
        const q = (c.req.query('q') ?? '').trim()
        if (!q) {
            return c.json({
                status: 200,
                message: "検索キーワードが空です。全件を表示します。",
                item: data
            })
        }

        const keyword = q.toLowerCase()

        const result = data.filter((p) =>
            p.name.toLowerCase().includes(keyword)
        )

        if (result.length === 0) {
            return c.json({
                status: 200,
                message: "ヒットしませんでした",
                item: []
            })
        }

        return c.json({
            status: 200,
            message: `${result.length}件がヒット`,
            item: result
        })
    } catch (error) {
        return c.json({
            status: 500,
            message: "エラーが発生しました"
        })
    }
}

まとめ

今回は、軽量なWebフレームワーク「Hono」を使って、シンプルな検索機能の実装方法を解説しました。

  • クエリパラメータから検索文字列を取得
  • ilter() を使ってデータを検索
  • ヒット件数によって返すレスポンスを柔軟に分岐
  • try-catch による エラーハンドリング で堅牢性を向上

さらに検索対象のキーを name 以外にも id や age に拡張すれば、より柔軟なフィルター機能も構築できます。小規模なAPI開発やモックサーバーの構築にも便利なので、ぜひ試してみてください

ぽちぽちのつどい

Discussion