バックエンドサーバ — 「何を返すか」を考える頭脳

概要 — まず全体をつかむ

初級ではバックを「頭脳」と捉えました。中級では、APIの形・スケール・データアクセスの勘所を見ます。

詳細 — 1段階ずつ追う

これは何をする係?

バックエンドは、フロントからの要求を受けて業務ロジックを実行し、データ層を操作して結果を返すサーバです。設計の要点は次の3つ。

  • API の形 — REST(リソース単位)や GraphQL(必要な形で取得)など、決まった規約で会話する
  • ステートレス — サーバ自身に会話の状態を持たせない。状態はトークン・DB・キャッシュへ逃がす
  • 認証・認可 — 認証(誰か)はトークンやセッションで、認可(何ができるか)はロールや権限で

登場人物メモ:

  • ※1 REST/GraphQL — 代表的なAPIの形。前者はURL単位、後者は問い合わせ言語
  • ※2 トランザクション — 「全部成功か、全部なかったことにするか」をまとめて扱う単位
この部分をもっと深く(上級

1台の中では成功か失敗の二択ですが、サービスが分かれると「一部だけ落ちる・遅れる・返事が来ない」 が日常になります。ここが分散システムの本質的な難しさです。

  • ステートレス化 — 状態はDB/キャッシュ/トークンへ逃がし、どの台でも処理可能に
  • 境界の設計 — サービス分割の粒度、同期呼び出しの連鎖を減らす
やさしく言うと(初級

厨房のシェフにたとえられます。ホール(フロント)から注文(※1 API)を受け、材料(DBのデータ)を出し入れして、料理(返すデータ)を作る。判断・計算・データの指示が仕事です。

サーバ機器
サーバ — 要求に応えるコンピュータ

大事なのは、動く前に2つを確かめること:

  • 認証(※2) — そもそも「誰か」を確かめる(ログインしているか)
  • 認可(※3) — その人が「その操作をしてよいか」を決める(権限)

登場人物メモ:

  • ※1 API — フロントとバックの会話の窓口。決まった形でお願いして、決まった形で返す約束
  • ※2 認証 — 本人確認(あなたは誰?)
  • ※3 認可 — 権限の確認(あなたはこれをしてよい?)

仕事の流れ

  1. 入口経由で API リクエストが届く
  2. トークン等で認証、ロール等で認可を確認
  3. 業務ロジックを実行(必要なら複数の操作をトランザクションでまとめる)
  4. DB/キャッシュ/ストレージにアクセス(読みはキャッシュ優先で軽くする)
  5. 結果を規約どおりの形(JSONなど)で返す
アニメーション『バックエンドの層(受付・業務・データ入出力)』を開く
バックエンドの層 — 役割で分ける受付 → 業務ロジック → データ入出力 → 保管庫コントローラController受付・入力を受け取り、形を整えて渡す・結果を決まった形(JSON)で返すサービスService業務ロジック・判断・計算・手順をまとめる・必要ならトランザクションで束ねるリポジトリRepositoryデータ入出力・DBとのやり取りを引き受ける・SQLの詳細を上の層から隠すDBデータの保管庫要求(下へ降りる)応答(上へ戻る)各層は自分の役割だけを持つ。だから直しやすく、入れ替えやすい
この部分をもっと深く(上級
  1. タイムアウト — 無限待ちを避ける(呼ぶ側が必ず設定)
  2. リトライ+指数バックオフ+ジッタ — 再送はだんだん間隔を空け、揃えない
  3. 冪等キー — 二重実行を無害化
  4. サーキットブレーカ — 失敗が続く相手を一時遮断し、フォールバック
  5. 分散トレーシング — 1リクエストが複数サービスを跨ぐ様子を追う
やさしく言うと(初級
  1. フロントから API でお願いを受ける
  2. 認証を確認(ログインしているか)
  3. 認可を確認(その操作をしてよいか)
  4. 中身のロジックを実行(計算・判断)
  5. 必要なデータを DB・キャッシュ・ストレージに出し入れする
  6. 結果を決まった形にまとめてフロントへ返す
アニメーション『バックエンド=何を返すか考える頭脳』を開く
バックエンドサーバ=「何を返すか」を考える頭脳リクエスト受信フロントからのお願いを受ける処理認可チェック(してよい操作か)ビジネスロジック(判断)計算・組み立てレスポンス組み立てて返す必要なデータを取得するDB構造データキャッシュ高速な一時メモ他サービス外部API画面(フロント)ではなく、データと判断を扱う裏方

スケールとデータアクセス

  • 水平スケール — ステートレスにしておけば、混雑時はサーバを増やして分散できる
  • キャッシュ戦略 — 読み取りの多い結果はキャッシュに載せ、DB負荷を下げる
  • N+1問題 — 一覧+各行ごとのクエリで本数が爆発する。JOINやまとめ取得で回避
  • コネクションプール — DB接続は毎回張り直さず、あらかじめ用意した接続を使い回す。ただし水平スケール時は「サーバ台数×1台あたりのプール数」がDBの接続上限を圧迫する点に注意
  • 非同期ジョブ — 重い処理はキューに積み、レスポンスと切り離す
この部分をもっと深く(上級
  • 結果整合性 — 分散では強整合を諦め、少し遅れて揃う設計が多い
  • Saga — 複数サービスにまたがる業務を、補償トランザクションで整える(2相コミットを避ける)
  • イベント駆動/CQRS — 変更をイベントで伝え、読み取りと書き込みのモデルを分ける
  • アウトボックスパターン — DB更新とイベント発行を、取りこぼしなく一致させる
  • バックプレッシャ — 過負荷時に受け入れを絞り、雪崩を防ぐ
やさしく言うと(初級

すぐ返せない重い処理(メール送信・大量集計など)は、その場でやると待たされます。そういうものは「後でやるリスト(キュー)」に積んで、返事だけ先に返す——これが非同期処理です。

⚠️ うまくいかないとき

  • タイムアウト — 処理が長すぎる。リトライするなら冪等性(何度実行しても同じ結果)に注意
  • デッドロック — 複数の処理が互いのロックを待って止まる
  • 整合性の乱れ — キャッシュとDBの内容がズレる(無効化の設計が甘い)
この部分をもっと深く(上級
  • カスケード障害 — 1つの遅延が連鎖して全体を巻き込む
  • リトライストーム — 一斉リトライが相手をさらに潰す
  • スプリットブレイン — 分断で「両方が主」になり整合が壊れる
  • 可観測性不足 — ログ・メトリクス・トレースが無いと、分散の障害は追えない
やさしく言うと(初級
  • 403(権限なし) — 認証はOKだが認可で止められた
  • 500(内部エラー) — バックの処理そのものが失敗した
  • 遅い — DBへの問い合わせが重い/多すぎる(後述のキャッシュで軽くする)

理解度チェック

そのまま解けます(成績は保存されません)。無料アカウントを作ると、学習の記録と進捗の山登りが始まります。

1. 一覧を出すたびに、各行のために追加のクエリを1本ずつ投げてしまう非効率な状態を何と呼ぶ?

2. バックエンドを「ステートレス」に保つ主な狙いは?

3. 「全部成功か、全部なかったことにするか」をまとめて扱う単位を何と呼ぶ?

4. N+1問題を避ける手立てとして正しいのは?

5. 重い処理(大量集計など)を「キューに積み、レスポンスと切り離す」やり方を何という?

6. 複数の処理が互いの持つロックを待ち合って、どちらも進めなくなる状態を何という?

7. 「何度実行しても結果が同じ」性質を何と呼ぶ?(リトライを安全にするために重要)

8. RESTやGraphQLのように、決まった規約でフロントとバックが会話する窓口を、英字3文字で何と呼ぶ?