🍉

バックエンドとしてのバリデーションを考える

に公開

はじめに

バリデーションと聞くと、真っ先に思い浮かぶのは「フロントでの入力チェック」という人もいるのではないでしょうか?
入力フォームで必須チェックや形式チェックをして、ユーザーにわかりやすいエラーメッセージを出す。これはユーザー体験を高めるうえで欠かせない役割です。

ただし、システムを守るという意味ではバックエンドのバリデーションが必要不可欠になります。
直接APIを叩かれるケースや、不正なリクエストなどがあった場合に、バックエンド側での制御がないと簡単にシステムトラブルにつながってしまいます。

今回は、バックエンドにおけるバリデーションの必要性や種類を整理しつつ、実際の開発でどう考えていくべきかをまとめてみました。

バックエンドでのバリデーションが必要な理由

フロントとバックの違い

フロントのチェックは、ユーザビリティの向上や無駄なデータ送信の制御を目的としています。
一方で、バックエンドは「セキュリティ」
フロントをすり抜ける or APIだけ叩かれる場合に悪意あるリクエストを防ぎシステム上トラブルにならないように防ぐために存在します。

セキュリティ上の観点

特にAPI開発では、直接APIを叩かれることを前提にしなければなりません。
「このAPIだけ直接呼ばれても業務的に問題ないか?」という問いに答えられる設計が必要です。

バリデーションの種類

1. 値のチェック

最も基本的なバリデーションになります。

  • 必須項目の存在
  • 型の一致(文字列・数値・日付など)
  • 値の範囲(0以上、100以下など)
  • フォーマット(メールアドレス形式など)

2. 権限・ロールによる制約

「どの権限をもつユーザーが操作できるのか?」という制御です。

  • 一般ユーザーは閲覧のみ、管理者は作成・更新可能
  • 特定のロールだけが実行できるAPI
  • 操作対象データが自分の所有物かどうかのチェック

3. 業務ロジック上の制約

ここからがバックエンドバリデーションの肝とも言えます。
システム固有の仕様を守るためのチェックです。

  • 存在チェック:更新対象のデータが存在するか
  • 状態チェック:すでにキャンセルされた注文を再度キャンセルできないようにする
  • 在庫チェック:在庫数を超える注文を防ぐ
  • 二重送信防止:同じリクエストで注文が2回通らないようにする
  • 整合性チェック:注文実行時にカートの中身が空でないか確認する

業務ロジック上の制約って聞くと、何から始めたらいいんだろう?と悩みますが、シンプルに3つの工程(前提条件・事後条件・禁止事項)に分けると整理しやすいです。

3-1.前提条件

「この処理を始める前に、必ず成り立っていてほしいこと」です。
例えば、注文確定であれば、

  • カートに商品が1件以上入っている
  • 合計金額が0円ではない
  • 注文商品の在庫が確保できている

このようなことが事前確認として必要です。

3-2.事後条件

「処理が終わったあとに、こうなっていなければおかしい」ということです。
注文終了後であれば、

  • 注文ステータスが完了になっていること
  • カートが空になっていること
  • 在庫が減っていること
  • ポイント付与処理が行われていること

などがチェックポイントになります。

3-3.禁止遷移

「この状態からは進ませてはいけない」というルールです。
例えば、

  • キャンセル済みの注文をもう一度確定処理できてしまう
  • 注文に失敗したのに、注文完了メールが届いてしまう
    このような状態になってしまったらシステムとしての整合性が崩れてしまいます。
    このようなやってはいけない動きを止めることが大事です。

4.外部サービスを利用するとき

バックエンドのバリデーションで特に気をつけたいのが、外部サービスを利用する処理です。
決済や配送、認証など、外部APIを順番に呼び出して処理を進めることはよくあります。

こうしたケースで陥りがちなのが、「1つ目のAPIでバリデーションしているから大丈夫だろう」と安心してしまうことです。例えば、最初のリクエストでカートの状態をチェックしていたとしても、2つ目や3つ目のAPIが直接呼ばれてしまうと、想定外の状態で処理が進んでしまうリスクがあります。

実際、フロントの不具合や外部からの不正リクエストによって「2つ目だけが単独で呼ばれる」といった事象は起こりえます。もしそのAPI側でもチェックを入れていなければ、整合性が崩れてサービス全体に影響が出る可能性があります。

  • 各APIごとに最低限のバリデーションを入れておく
  • 前提条件(カートが空でない、対象データが存在するなど)を毎回確認する
  • 「最初のAPIを通っていること」を前提にしない

こうした意識を持つことで、不具合や不正アクセスに強い仕組みを作ることができます。

まとめ

フロントのバリデーションは「ユーザーのため」、バックエンドのバリデーションは「システムを守るため」。この2つは似ているようで役割が大きく異なります。

バリデーション処理をただこなす作業にするのではなく、システム全体の安全装置としてどう設計するのかを考えることが大切です。

ぜひ、自分のプロジェクトでも「この処理を始める前に何を確認すべき?」「終わったあとどうなっているべき?」「絶対にやらせちゃいけない動きは?」と問いかけながら、バリデーションを設計してみてください。

株式会社アクトビ

Discussion