はじめに
HTTPはステートレスなプロトコルです。
それ自体はよく知られた前提ですが、
- セッションを使うべきか
- Cookieで足りるのか
- 画面の状態はどこに持たせるべきか
といった設計判断になると、
「何となくの慣習」で決めてしまう場面も多いのではないでしょうか。
この記事では、.NET Core(ASP.NET Core)を例にしながら、
状態をどう保持するかではなく、
その状態は誰の都合なのか?
という視点で整理してみます。
HTTPはステートレス、でもアプリはステートフル
HTTPはリクエストごとに完結し、 前後関係を持ちません。
しかし、Webアプリケーションでは
- 申請 → 確認 → 完了
- 一覧 → フィルタ → 詳細
のように、
文脈(状態)を前提にした画面遷移が当たり前に存在します。
そのギャップを埋めるために、
さまざまな「状態の置き場」が使われます。
状態管理の代表的な選択肢
Cookie
- クライアント(ブラウザ)に保存
- リクエストごとに自動送信
- 小さなデータ向き
Response.Cookies.Append("UserId", userId);
向いているもの
- ユーザ識別
- ログイン状態のトークン
向いていないもの
- 画面途中の入力内容
- 一時的な業務データ
Session
- サーバ側で状態を保持
- CookieなどでセッションIDを関連付け
HttpContext.Session.SetString("ApplyData", json);
向いているもの
- 申請 → 確認 のような画面フロー
- 一時的だが業務上意味のある状態
注意点
- セッションクリアのタイミング
- 画面戻り・リロードとの整合性
「画面遷移とSessionの整合性」を合わせることも必要です。
クエリ・Hidden Field
- 状態を明示的に受け渡す
<input type="hidden" name="status" value="confirm" />
向いているもの
- 小さく、明示的な状態
- URLや画面構造に含めたい情報
ブラウザ側(JavaScript)
sessionStorage / localStorage
JavaScript変数
sessionStorage.setItem("filter", "active");
向いているもの
- 表示切り替え
- フィルタ条件
- ユーザ操作の都合
サーバは知らなくていい状態です。
判断軸は「誰の都合か」
ここまで見てきた選択肢は、 技術的な優劣ではなく、
その状態は誰の都合なのか
で整理できます。
| 状態の性質 | 置き場所 |
|---|---|
| 業務の進行に必須 | サーバ(Sessionなど) |
| ユーザ体験のため | ブラウザ(JS) |
| 識別・認証 | Cookie |
今なら当たり前に思えるこの整理も、
とりあえずSessionに入れる
という判断をしがちでした。
しかし、
アプリ全体の都合か、ユーザ個人の都合か
を意識すると、
自然と設計は整理されます。
URLで見る状態管理の使い分け
状態の置き場所は、URLを見ると直感的に理解できます。
サーバ都合の状態(Session)
例:申請 → 確認 → 完了
GET /apply
POST /apply
GET /apply/confirm
POST /apply/complete
URLには申請内容が含まれていません。
途中状態はサーバ側で保持します。
// POST /apply
HttpContext.Session.SetString("ApplyData", json);
// GET /apply/confirm
var data = HttpContext.Session.GetString("ApplyData");
これは、業務フローを保証するための アプリ全体の都合の状態です。
明示的に共有する状態(Query)
例:一覧・検索
GET /users?status=active&page=2
URLを見るだけで表示内容が再現できます。
public IActionResult Index(string status, int page = 1)
{
...
}
- ブックマークできる
- 共有できる
ユーザとサーバ双方にとって都合のよい状態です。
ブラウザ都合の状態(JavaScript)
例:表示切り替え・フィルタUI
GET /users
URLは変わりません。
sessionStorage.setItem("viewMode", "card");
- 表示形式
- UIの開閉状態
サーバは知らなくてよい、 ユーザ体験のための状態です。
補足:SPA風の構成について
Razorで画面の雛形を作り、
データ取得や表示更新をJavaScript(Ajax)で行う構成は、
いわゆる「SPA風」の作りです。
この構成では、
- 画面遷移をサーバに依存しない
- 表示状態をブラウザ側で管理できる
ため、 画面都合の状態をSessionに持たせる必要は減ります。
ただし、 SPAであっても 状態の責務が消えるわけではありません。
表示や操作の都合はブラウザへ、
業務の進行状態はサーバへ。
判断軸は変わらないと考えています。
おわりに
状態管理の設計で迷ったとき、
どこに置けるか
ではなく、
誰の都合の状態か
と問い直すと、 選択肢は自然に絞られます。
HTTPがステートレスであることは変わりませんが、
設計の視点を持つことで、
無理のない状態管理ができるようになります。