俺の報告

RoomClipを運営するエンジニアの日報(多分)です。

日報 #88 - ステートレスだとコノヤロウ!

今日の気付きは、このままずっとステートレスなWeb応答でいんすかね?という疑問です。

ステートレスというとうるさいですが、
要は「文脈ねぇぞ」ってことです。
今ステートレスでググってみたら http://yohei-y.blogspot.jp/2007/10/blog-post.html こんな分かりやすいサイトありました。

クライアント・サーバモデルでは、「相手の状態なんざ知らんわ、リクエストに対してレスポンスするだけだわ!」って振り切ることで、いついかなる時もどのサーバが応答受付をしても大丈夫なように設計されているそうです。
それをステートレスというと。
上記のサイトにあるハンバーガー屋の店員と客のやりとりが本当に分かりやすいです。
ぐっと単純に言えば、
【ステートレスじゃない】
客「ハンバーガーくれ」 店員「サイドメニューは?」客「コーヒで」⇒コーヒーとハンバーガー渡す。
【ステートレス】
客「ハンバーガーくれ」店員「サイドメニューは?」客「ハンバーガーとコーヒーくれ」⇒コーヒーとハンバーガ渡す。

ステートレスだとサイドメニューは?と訪ねた店員じゃなくても、コーヒーとハンバーガーが注文の全てだと分りますので、スケーラブルだというわけです。
はい。
まぁこんだけですね。

なんですが、
ぶっちゃけほっとんどのWebサービスは、ステートフルッフルのやりとりばっかりなわけです。
じゃぁどうするかっていうと、相手の状態(注文)をどっか外部に保存しておいて、
毎度毎度それを読み込んでいるわけです。
言ってみりゃこんな感じです。

【ステートレスでステートフルッフルのやりとり】
客「よう」
店員A「おう、お前整理券5番な。」
客「おk。整理券5番なんだけど、ハンバーガーくれよ。」
店員B「整理券5番な、ハンバーガーな、メモったわ。んで、他には?」
客「おう。整理券5番なんだけど、コーヒーも欲しいわ。」
店員C「誰だお前?整理券5番?ちょっと探すわ、あったわ、コーヒも欲しいのな、メモっとくわ。で他は?」
(客、諸事情で1回店でちゃう)
客「整理券5番なんだけど、注文全部くれよ。」
店員D「おう、お前誰だよ。整理券5番?1時間前にそのメモ破棄しちゃったわ。これ、新しい整理券な、12番な。それもって、おととい来やがれ。」
客「あぁ!?ファ◯ク!やり直しかよorz」

まぁこんな感じですね。
店員の「記憶」に頼っていたものを「外部化」すればステートフルっぽいやりとりも出来るわけです。
で、これ自体は凄い正しいと思うのだけど、 じゃぁステートフルなやりとりと本質的に何が違うの?って感じです。
状態を外部において、それを全プロセスに共有しているっていう点が違うというので終わりっていうなら、
「ステートレスorステートフル」という対立の本質は、状態記憶の内部化vs外部化っていう話なんですかね?
ステートレスというものは本質的には状態を前提にしないけど、
いま流行っているWebアプリのほとんどが状態を読み込んだ上での処理を前提をする、たまたまそうなっているだけだ、
という主張も考えられるけど、現実的にWebアプリのやりとりの99%以上が状態確認を前提にしているのであれば、
それはもうステートレスじゃないって思うのですよ。
だって、状態を前提にしないやりとりならほぼ意味を成さないレスポンスしかしないわけだし。
もう暗黙的にhttpのリクエスト・レスポンスにはセッションとクッキー的なものが必須なわけだよね。
じゃぁなんかステートレスなやりとりに拘る必要性はないんじゃないかと思うのよ。

なにがいいてぇのかというと、
セッションとクッキー前提の世界観でいくならもうステートフルなんだから、
もっとイケてる「ステート」の保存と共有方法ねぇのかなって話です。
すっごいわがままな話に落とし込めば、
アプリでログインしたのにブラウザじゃログインしてない、なんてナンセンスでしょうよ!
って話なわけですよ。
まぁディープリンクとかが代替的にそういう役割を演じたりするのかもしれませんが、
さっさとステートもクラウド化してリクエストヘッダにstate的なモノひっつけてやりとりしようぜって話なわけですよ。
セキュリティが心配すぎて鼻血でるわけですよ。
なんとかなんねぇかなぁ…

あぁ現場からは以上ですよ。