コンテンツにスキップ

003. サーバー主導UI(Server-driven UI)

原理:「正解」を持つのは誰か?

クライアント主導の限界と混沌

現代の一般的なWeb開発(特にSPA: Single Page Application)では、ブラウザ(クライアント)がアプリケーションのロジックや状態の多くを管理します。これは「クライアント主導UI」と呼ばれます。 サーバーから届くのは「生のデータ(JSON)」だけで、それをどう加工し、どのタイミングで画面のどの部分を表示するかは、ブラウザ内の複雑なJavaScript(JS)が決定します。

しかし、この方式には致命的な弱点があります。それは、「状態(State)の同期」という地獄です。 「今、ユーザーはログインしているか?」「ショッピングカートの合計金額はいくらか?」といったデータが、ブラウザ上のメモリとサーバー上のデータベースの両方に存在し、それらを寸分違わず一致させ続けるために、開発者は多大な労力を割かなければなりません。ちょっとした不具合で「画面上は購入済みになっているが、サーバーには注文が届いていない」といった深刻なバグが発生しやすくなります。

HTMXが提唱する「サーバーへの回帰」

HTMXの「サーバー主導UI」という原理は、この主導権(ロジックと状態)を、再び強力で安全なサーバー側に取り戻すことを意味します。 HTMXにおいて、ブラウザは意思決定をしません。ブラウザは単に「ユーザーがこれを押しました」とサーバーに伝え、サーバーから返ってきた「完成したHTMLパーツ」を表示するだけです。

「どのような見た目であるべきか」の正解は常にサーバーにあります。 サーバーがHTMLを生成する時点で、そのユーザーの権限、現在のステータス、最新の在庫状況などがすべて反映されています。ブラウザ側でデータを解析して、if文で表示を切り分ける必要はありません。サーバーから届いた「成功のメッセージ付きボタン」を、そのまま表示するだけでUIが成立します。

これにより、クライアントとサーバーの間でデータを同期させる必要がなくなり、コードの複雑さは劇的に軽減されます。


実践:ロジックをサーバーのテンプレートに預ける

1. 状態に応じた出し分け(サーバー側)

例えば、「お気に入り登録ボタン」を考えてみましょう。 サーバー側(Python/Djangoなどのテンプレート)で以下のようにロジックを書きます。

<!-- server-side template (item_partial.html) -->
<div id="favorite-section">
    {% if item.is_favorited %}
        <!-- すでにお気に入りなら「解除」ボタンを出す -->
        <button hx-post="/unfavorite/{{ item.id }}" hx-target="#favorite-section">
            ★ お気に入り解除
        </button>
    {% else %}
        <!-- まだなら「登録」ボタンを出す -->
        <button hx-post="/favorite/{{ item.id }}" hx-target="#favorite-section">
            ☆ お気に入り登録
        </button>
    {% endif %}
</div>

2. ブラウザ側の実装(極限のシンプルさ)

ブラウザ側には、上記のHTMLの一部を呼び出すコードを置くだけです。JSによる「状態の書き換え」は一切不要です。

<!-- index.html -->
<div id="favorite-section" hx-get="/item-status/1" hx-trigger="load">
    読み込み中...
</div>

3. ステップ・バイ・ステップ解説

  1. リクエスト: ユーザーがボタンを押すと、HTMXがリクエストをサーバーに送ります。
  2. サーバーの判断: サーバーはデータベースを更新し、最新の状態を反映した「新しいボタンを含むHTMLパーツ」を生成します。
  3. レスポンス: サーバーから ★ お気に入り解除 というボタンのHTMLが返ってきます。
  4. 画面更新: HTMXがそのパーツを hx-target に指定された場所に差し込みます。

このプロセスにおいて、ブラウザ側のJSは「現在お気に入り中かどうか」という情報を1ミリも持っていません。すべてはサーバーが判断し、結果(HTML)を送っているからです。


比較:JSON API vs HTMLパーツ

従来のJSON(データ重視)方式

  1. ブラウザ:/api/favorite を叩く。
  2. サーバー:{ "success": true, "new_status": "active" } を返す。
  3. ブラウザ:JSでレスポンスを解析し、「activeならボタンのアイコンを星に変えて、テキストを書き換えて…」と指示を書く。 問題点: 画面をどう変えるかのルール(UIロジック)をJSで書かなければならず、サーバー側のロジックと重複しがちです。

HTMX(サーバー主導)方式

  1. ブラウザ:/favorite を叩く。
  2. サーバー:<button>★ 解除</button> を返す。
  3. ブラウザ:そのまま表示する。 利点: ブラウザにUIのルールを教える必要がありません。サーバー側でテンプレートを一箇所直すだけで、すべての画面が正しく更新されます。

まとめ:初心者のための「サーバーを信じる」設計

サーバー主導UIへのシフトは、Web開発における最大の「肩の荷」を下ろす行為です。

  • 状態はサーバーに一つだけ: ブラウザ側のメモリ(ReduxやVuexなど)に悩む必要はありません。
  • UIはサーバーで作る: HTMLを組み立てる力(テンプレートエンジンなど)があれば、高度なアプリが作れます。
  • デバッグが明確: 「画面がおかしい」時は、サーバーが返しているHTMLを見れば一発で原因がわかります。

サーバーという「司令塔」を信頼し、ブラウザを「忠実なモニター」に変える。これこそが、HTMXが提唱するシンプルかつ強力な開発スタイルです。次の記事では、この土台となるWebの本来の仕組み「ハイパーメディア」という概念(004. ハイパーメディアの復権)を深掘りし、さらに理解を深めていきましょう。