エンジニアの皆さん、こんにちは。ネットワークの深淵を愛するインフラアーキテクトです。
今日は「REST APIの4つの原則」の中でも、特に重要かつ、ネットワークエンジニアの視点から見ると「非常に理にかなっている」制約、「ステートレス性(Statelessness)」についてお話ししましょう。
「ステートレス」という言葉、API開発の現場では耳にタコができるほど聞きますよね。でも、なぜサーバーはあえて「記憶喪失」でいる必要があるのでしょうか? 郵便配達の仕組みに例えて、その真意を紐解いていきましょう。
—
1. 「ステート」ってそもそも何?
「ステート」とは「状態」のこと。例えば、あなたがWebサイトでログインして、買い物をしているとします。サーバー側が「この人はさっきログインした人だ」「今、カートにはリンゴが入っている」という情報をメモリ上に覚えておくこと、これが「ステートフル(状態を保持する)」な状態です。
これ、一見便利そうですよね? でも、ネットワークの世界、特に巨大なシステムではこれが「悪夢の始まり」になるんです。
郵便配達で例えてみよう
あなたが手紙を出すとき、毎回「私は山田太郎です。住所は〇〇町です」と名乗らなくても、ポストに投函すれば届きますよね。なぜなら、手紙そのものに「送り主」と「宛先」が全て書かれているからです。
もし郵便局が「配達中に誰から来たか、いちいち覚えておかなきゃいけない」としたらどうでしょう? 配達員が何万人もいたら、その記憶を共有するために巨大な会議を開く必要がありますよね。これは効率が悪すぎます。
RESTにおける「ステートレス」とは、まさにこの「手紙一枚ですべて完結する仕組み」のことなんです。
—
2. なぜステートレスだと「最強」なのか?
サーバーが何も覚えていないと、どんなメリットがあるのでしょうか?
- 拡張性が爆上がりする(スケールアウト): サーバーが「誰が誰か」を覚えていないので、急にアクセスが増えても、新しいサーバーをポンと横に追加するだけで対応できます。どのサーバーがリクエストを受けても同じ結果が返せるからです。
- トラブルに強い: あるサーバーが故障しても、クライアントは別のサーバーに投げ直せばいいだけ。「さっきの続き」なんて存在しないので、何も困りません。
インフラエンジニアの視点で見ると、この「どのリクエストも平等に扱える(独立している)」という状態は、負荷分散(ロードバランサー)と非常に相性が良いんです。
—
3. ステートレスなAPI設計をコードで見てみる
では、具体的にどう実装すればいいのか、PythonのWebフレームワークである Flask を例に見てみましょう。
ダメな例:サーバーが状態を記憶しちゃう
# サーバー側で勝手にカウントを保持する例
count = 0
@app.route('/increment')
def increment():
global count
count += 1
return f"現在のカウントは {count} です"
これだと、サーバーが2台あった場合、AサーバーとBサーバーで数字がバラバラになってしまいますよね。
良い例:ステートレスに設計する
クライアント側で状態を管理し、リクエストには「今の値はこれだよ」という情報を含めます。
# クライアントから値を受け取り、それを元に計算して返す
@app.route('/increment', methods=['POST'])
def increment():
# リクエストボディから現在の数値を受け取る
data = request.get_json()
current_value = data.get('value', 0)
# 計算結果を返す(サーバーは何も覚えていない!)
new_value = current_value + 1
return {"new_value": new_value}
このように、current_value をリクエストのたびに送ってもらうことで、サーバーは「自分が何をしていたか」を一切覚える必要がなくなりました。
—
4. 現場でのTips:どうやって「本人確認」するの?
「じゃあ、ログイン状態はどう管理するの?」という疑問が湧きますよね。ここで登場するのが Authorization ヘッダーや JWT (JSON Web Token) です。
ログイン時にサーバーから「通行手形(トークン)」を発行し、その後のリクエストで毎回その手形を提示してもらいます。
# リクエストヘッダーの例
GET /api/user/profile HTTP/1.1
Host: api.example.com
Authorization: Bearer <ここに暗号化された通行手形が入る>
サーバーは、この手形が正当なものかどうかをチェックするだけで、「この人は誰か」を瞬時に判断できます。データベースをいちいち参照してセッションを探す必要もありません。これぞステートレスの真髄です。
—
まとめ:ネットワークの恩恵を最大化しよう
REST APIにおけるステートレス性は、決して「不便」にするための制約ではありません。サーバーを身軽にし、ネットワーク全体の信頼性と拡張性を高めるための「賢い知恵」なのです。
1. 各リクエストは独立させる: サーバーに記憶させない。
2. 必要な情報はすべてリクエストに含める: ヘッダーやボディを活用する。
3. 状態管理はクライアントに任せる: サーバーは計算機に徹する。
この原則を守るだけで、あなたのAPIはグローバルなトラフィックにも耐えうる、美しく堅牢な設計に一歩近づきます。ぜひ、次の設計で意識してみてくださいね。
それでは、また次回の技術探訪でお会いしましょう!ネットワークの向こう側でお待ちしています。
コメント