‼️

【備忘録】Next.jsとHono.jsのmonorepo構成でパラメータ送受信エラーに遭遇

に公開

はじめに

フロントエンド(Next.js)とバックエンド(Hono.js)の monorepo構成 でアプリケーションを開発しています。
しかしNext.jsでHonoクライアントを使用しAPIを呼び出す実装をしている最中にAPIパラメータの受け渡しが正確に行われないエラーが起きてしまいました。
上記の件で少し躓いたので自身の備忘も兼ねて紹介します。

問題の概要

今回のエラーに遭遇したのはシンプルなSNSのユーザ検索機能を開発している時でした。

  • フロントエンド: Next.js + Honoクライアント
  • バックエンド: Hono.js(APIエンドポイント)

しかし、異なるユーザでログインしていてもデータの結果が同じものを返していました。
デバッグログを確認すると、以下のように表示されました。

[フロントエンド] 検索ユーザーID: user123
[バックエンド] 受信したユーザーID: undefined

つまりフロントエンドから送信したはずのパラメータが、バックエンドで受け取れていない状態でした。

原因

原因は、Honoクライアントにおけるパラメータの取り扱い方の誤認です。

以下は誤った実装です。

フロントエンド側(誤り)

const res = await client.api.users.$get({
  param: { userId: "user123" } // ❌ paramを使用
});

バックエンド側

app.get("/users", async (c) => {
  const userId = c.req.query("userId"); // queryとして取得しようとしている
  console.log("受信したユーザーID:", userId); // → undefined
});
  • paramはパスパラメータ(例:/users/:id)向けであるにも関わらず、
  • バックエンドではqueryで受け取ろうとしていたため、値が渡りませんでした。

解決策

Honoクライアントでは、パラメータの種類に応じて適切なキーを使う必要があります。

パラメータ種別 用途 指定方法
パスパラメータ /users/:id param
クエリパラメータ /users?userId=xxx query

以下が修正後の正しい実装です。

フロントエンド側(修正後)

const res = await client.api.users.$get({
  query: { userId: "user123" } // ✅ queryを使用
});

バックエンド側

app.get("/users", async (c) => {
  const userId = c.req.query("userId");
  console.log("受信したユーザーID:", userId); // → user123
});

この修正により、バックエンド側で正しくパラメータを受け取れるようになりました:

[フロントエンド] 検索ユーザーID: user123
[バックエンド] 受信したユーザーID: user123

学んだこと

Honoクライアントでパラメータを扱う際には、パラメータの種別に応じて適切な指定方法を使うことが重要

  • param: パスパラメータ(例:/users/:id
  • query: クエリパラメータ(例:/users?userId=123

また、上記のような誤った実装を行っていてもTypeScriptの型だけでは判別できない

まとめ

TypeScriptを使っていても、パラメータの使い方を誤るとバグを見逃してしまう可能性があります。

Honoクライアントは便利ですが、paramとqueryの違いをしっかり理解しておかないと、
今回のような問題が起こります。

シンプルな修正ではありますが、この経験を通じてパラメータの使い方について理解を深められました。

Discussion