見出し画像

どこまでフロント? どこから API? 〜 Next.js × Hono の責務分担を整理した記録 〜

型契約 ・ 境界の先決め ・ 層の考え方 — 3 つの基準で線引きする

「どこまでフロントで、どこから API か」

Next.js で UI を書き、Hono で API を書く。
そんな構成にしたとき、この問いに答えられず迷ったことはありませんか?

僕も、個人開発でフロントと API を両方触りながら、型の食い違いで深夜デバッグを繰り返しました。
壁打ちのなかで「フロントと API の責務分担を、どんな基準で線引きしているか?」と自分に問い直し、ようやく整理できた記録を共有します。


「どこで何をするか」 が揺れていた

みなさんは、Next.js と Hono を併用していますか?

あるいは、Next.js の App Router と Server Actions だけで完結させつつ、「ちょっとした API を Hono で切り出したい」と考えている方もいるかもしれません。

僕は個人開発で、フロントに Next.js、API に Hono という構成を取っています。
案件では Next.js の大規模アプリを、友人ポートフォリオサイトでは Hono を触る機会もありました。

ところが、「どこまでフロントで、どこから API か」が、ずっと曖昧だったのです。

Server Actions を書くとき、「バリデーションはどこで?」「認可は?」と Action ごとに揺れる。
Hono のミドルウェアを積むとき、「どこまで共通化すべきか」で迷う。
フロントと API のあいだで型が食い違って、ランタイムで発覚する。

あるとき、たった一つの小さな API を作るためだけに Next.js のプロジェクトを立ち上げていました。
create-next-app を打ち、ようやく /api/hello にアクセスできたとき、心に浮かんだのは達成感ではなく、ある種のもどかしさでした。

「僕はただ、小さなバラック小屋を建てたいだけなのに、まるで巨大な城を築いているような気分だ…」

その感覚と、「どこで何をするか」の曖昧さが重なって、線引きの基準が欲しいと強く感じるようになりました。

型の食い違いで深夜デバッグを繰り返した

僕が個人開発でフロントと API を両方触っているとき、何度か「言った言わない」に近いことが起きました。

💭 API のレスポンスに createdAt を追加した。フロントは created_at を期待していた。

💭 フロントで「この型で受け取る」と決めていたのに、API 側でフィールド名を変えてしまった。

💭 仕様は口頭やチャットで共有していたが、型として残っていなかった。

そのたびに、フロントでランタイムエラーや表示崩れが起き、原因を追う時間が奪われました。
深夜、画面とログを睨みながら「なんで動かないんだ」と頭を抱えた経験もあります。

「言った言わない」を防ぐには、型を契約として明文化するしかない。

そう気づいてから、Client / Server 両側から型を揃える設計に切り替えました。
型契約の話は、以前「言った言わないを防ぐ。フロントと API の型契約」で詳しく書いています。

でも、型を揃えても、「どこで何をするか」の線引きは、まだ曖昧なままでした。

壁打ちで問い直した 「責務分担の基準」

週末の執筆フローで、素材を「問い」に変換する習慣があります。

あるとき、こんな断片がテーブルに並びました。

「Hono の middleware、どこまで共通化すべきか迷った」

これを疑問文に変換すると、こうなります。

「フロントと API の責務分担を、どんな基準で線引きしているか?」

この問いが、僕の頭のなかでずっと引っかかっていました。

型契約は「何を渡し、何を受け取るか」の話。

でも、
「どこでバリデーションするか」
「どこで認可するか」
「フロントと API の境界をどこに置くか」

その基準が、言語化できていなかったのです。

Server Actions の記事で「境界を先に決める」と書いたとき、同じ感覚がありました。
「どこでやるか」が決まっていないと、追加のたびに揺れる。

実装を書き始める前に、責務分担の基準を決めておく。

その方針で、僕が試行錯誤の末に辿り着いた 3 つの基準を整理します。

責務分担を整理する 3 つの基準

僕が「どこまでフロントで、どこから API か」を線引きするときに使っているのは、次の 3 つです。

【基準 1】 型契約 — 「何を渡し、 何を受け取るか」 を共有する

フロントと API のあいだでは、型が契約になります。

人間同士の「言った言わない」には議事録がある。
フロントと API の「言った言わない」には型がある。
そう捉え直してから、僕の設計は変わりました。

リクエストの型、レスポンスの型、エラーの型。
これらを、どちらか一方だけが持つのではなく、両側で参照できる形で置く。

☑ 共有パッケージに型を置き、両側から import する
☑ Zod スキーマを「正」とし、そこから型を推論する
☑ OpenAPI から型を生成する

どの方式を選ぶかはプロジェクトの規模によります。
大切なのは、型定義が一箇所にあり、両側がそれを参照していることです。

型契約を破った瞬間、コンパイルエラーが出る。
「言った言わない」は、ランタイムではなくビルド時に検知できる。
これが責務分担の土台になります。

【基準 2】 境界の先決め — 「どこで何をするか」 を実装前に決める

境界とは、「どのレイヤーで、何を担当するか」の線引きです。

📌 バリデーション:
入力が「正しい形か」をどこでチェックするか

📌 認可:
「このユーザーがこの操作をしていいか」をどこでチェックするか

📌 エラー:
失敗したとき、呼び出し元にどう返すか

この 3 つを「うちのプロジェクトではこうする」と先に決めておくと、迷いが消えます。

Next.js の Server Actions なら、バリデーションは Action の入口で。
信頼の境界はサーバーに置く。
Hono の API なら、認証はミドルウェアで、ビジネスロジックはルートハンドラで。

実装を書き始める前に、境界を決めておく。
これだけで、一貫した設計になります。

【基準 3】 層の考え方 — 責務を分離し、 積み木のように重ねる

Hono のミドルウェアを「積み木」として捉え直した話は、以前「なんとなくミドルウェアを卒業する。Hono で学んだ層の考え方」で書きました。

最下層:
エラーハンドリング
👉️ どこで何が起きても受け止める

中間層:
ログ
👉️ すべてのリクエストを記録する

上層:
認証
👉️ 許可されたリクエストだけを通す

地表:
ルートハンドラ
👉️ ビジネスロジックだけ

この「層」の考え方は、Next.js の Server Actions にも通じます。
Server Actions の境界を先に決める」で、バリデーション・認可・エラーの「どこでやるか」を先に決める重要性を書きました。

フレームワークは違っても、設計の原則は同じ。

「責務を分離し、層を重ねる」

この考え方が身につくと、Next.js でも Hono でも、「なんとなく」から卒業できます。

【具体的な線引き】 Next.js と Hono の役割分担

ここからは、僕が実際に採用している「フロントと API の役割分担」を、もう少し具体的に共有します。

Next.js (フロント) が担うこと

UI の描画:
☑ コンポーネント、レイアウト、スタイリング

フォームと UX:
☑ 入力、バリデーションの先行チェック
 (Zod でサーバーと同じスキーマを使用)

Server Actions:
☑ フォーム送信、mutation
バリデーションは Action の入口で必ず行う
☑ 信頼の境界はサーバー

認可チェック:
☑ ログイン済みかどうか、権限があるかどうか
☑ Action の先頭で確認する

Next.js は「ユーザーに近い側」の責務を担います。
表示、入力、送信、そしてサーバーへの「依頼」まで。

Hono (API) が担うこと

ビジネスロジック:
☑ DB アクセス、外部 API 呼び出し、計算

認証・認可:
☑ トークン検証、権限チェック
☑ ミドルウェアで層として分離

ログ・エラー:
☑ リクエストの記録、例外の受け止め
☑ これもミドルウェアで層として分離

レスポンスの型保証:
☑ 共有型定義に沿ってレスポンスを返す
☑ Zod でランタイムバリデーションも行う

Hono は「ビジネスロジックとインフラに近い側」の責務を担います。
フロントから「こういうデータが欲しい」と依頼を受け、型契約に沿って返す。

境界を決めるときのチェックリスト

新しい機能を追加するとき、僕は次の 3 つを確認しています。

1️⃣ 型は共有定義から参照しているか?
👉️ フロントと API で別々に型を書いていないか

2️⃣ バリデーション・認可・エラーの「どこでやるか」は決まっているか?
👉️ 前回と揺れていないか

3️⃣ 層の順番に意味があるか?
👉️ 「なぜこの順番か」を説明できるか

この 3 つを守るだけでも、責務分担の迷いはかなり減ります。

境界が曖昧だったときの失敗例

僕が境界を曖昧にしていた頃は、こんなことが起きていました。

📍 Server Action によって、バリデーションをクライアントでやるものとサーバーだけでやるものが混在していた

📍 認可チェックの有無が Action ごとにバラバラで、「前回はどう書いたっけ」と毎回悩んだ

📍 Hono のルートハンドラに、ログ出力と認証チェックとビジネスロジックが同居していた

「動いているから、まあいいか」

そう思っていた 3 ヶ月後の僕は、自分のコードを読み返すのが怖くなっていました。

境界を先に決めてから、実装を書き始める。
その習慣をつけてから、コードの一貫性が驚くほど上がりました。

責務分担は、 一度決めて終わりではない

責務分担の基準は、プロジェクトの成長とともに見直していくものです。

最初は「型契約」と「境界の先決め」だけでも十分。
規模が大きくなったら、「層の考え方」をミドルウェア設計に適用する。

Next.js と Hono の組み合わせに正解はありません。
大切なのは、「どこで何をするか」を自分なりの基準で言語化し、一貫して守ること です。

「フロントと API の責務分担を、どんな基準で線引きしているか?」

この問いを、週末の壁打ちで自分に投げかけてみてください。
答えを言語化するだけで、設計がずっと楽になります。

ひとりごと

型の食い違いで深夜デバッグをした経験は、今でも忘れません。

「言った言わない」を防ぐ型契約と、「どこで何をするか」を先に決める境界設計。
この 2 つを言語化してから、責務分担の迷いはかなり減りました。

フロントと API の線引きに悩んでいる方へ。
まずは「型契約」と「境界の先決め」の 2 つだけ、自分なりのルールにしてみませんか。

2026© おおとろ

あわせて読みたい

▼ 型契約の具体的な設計を知りたいときに

型を契約として明文化し、共有型ファイル・Zod スキーマ・OpenAPI の 3 パターンを解説。
責務分担の土台となる型設計の実践例です。

▼ Hono の層の考え方を知りたいときに

ミドルウェアを「積み木」として設計する考え方。
エラー → ログ → 認証の順番の「なぜ」を言語化する方法を共有しています。

▼ Server Actions の境界設計を知りたいときに

「どこでやるか」を実装前に決める重要性。
Next.js 側の境界設計の具体例です。

▼ 技術選定の変遷を知りたいときに

Next.js と Hono をどう組み合わせるか、技術選定の背景を解説しています。

▼ Hono との出会いを知りたいときに

小さな API に Next.js が重いと感じたとき、Hono と出会うまでの物語です。

次の一歩を一緒に決める 「作戦会議室」 へ

責務分担の線引きや、型契約・境界設計の具体的な実装。
こうした技術的な設計の悩みは、メンバーシップ「フリーランス開発者の作戦会議室」で毎週共有しています。

Next.js と Hono の組み合わせ例、共有型パッケージの構成、ミドルウェアの積み方など、この記事では書ききれなかった細かい工夫を、作戦会議室では「具体物」としてお届けしています。

責務分担の基準を、一緒に磨いていきませんか?

参加する

ここから先は

0字

メンバーシップ ¥ 500 /月

■メンバーシップ 15 年目フリーランス開発者のひとり戦略を支える作戦会議室です。\ 案件に追われる…

ベーシックプラン

¥500 / 月

最後まで読んでいただき、ありがとうございます。もしこの記事が「役に立った」「心に響いた」と感じたら、珈琲一杯分サポートいただけると嬉しいです。あなたの温かい応援を力に、また次の創作活動に励みます。