HTTPステータスコード428 Precondition Requiredとは?ロストアップデートを防ぐ方法

INEZA Felin-Michel

INEZA Felin-Michel

21 10月 2025

HTTPステータスコード428 Precondition Requiredとは?ロストアップデートを防ぐ方法

ウェブベースのエディターを使って同僚と重要なドキュメントを共同で作業しているとします。二人とも同時に同じドキュメントを開きました。あなたは30分かけて慎重に導入部分を書き直し、その間、同僚は結論部分に取り組んでいました。あなたが最初に「保存」をクリックし、あなたの変更は受け入れられました。その後、同僚が「保存」をクリックすると、彼らのバージョンがあなたの素晴らしい新しい導入部分を何の警告もなく完全に上書きしてしまいました。あなたの作業は「失われた更新の問題 (lost update problem)」の犠牲になったのです。

この苛立たしいシナリオこそ、428 Precondition Required HTTPステータスコードが防ぐために設計されたものです。これはHTTP仕様の中でも、より洗練された先見的なステータスコードの一つであり、複数のユーザーによって同時に変更される可能性のあるリソースの保護メカニズムとして機能します。

これはよく知られたステータスコードではありませんが、安全で信頼性の高い、同時実行可能なAPI通信において非常に重要な役割を果たします。

では、HTTP ステータスコード 428 Precondition Required は具体的に何を意味するのでしょうか?いつ発生し、どのように適切に処理すればよいのでしょうか?

これは、あなたがどの版を更新しているか確認するまで、本の貸し出しを許可しない慎重な図書館員のようなものだと考えてください。サーバーが「変更を加える前に、このリソースの最新バージョンで作業していることを証明してください」と言っているようなものです。

共同作業アプリケーション、同時更新を処理するAPI、またはデータの一貫性が不可欠なシステムを構築している場合、428 を理解することは不可欠です。

まさにそれが、この詳細な解説で掘り下げる内容です。これにより、428が何を意味するのかだけでなく、なぜ存在するのか、そしてどのようにAPIを改善できるのかを理解することができます。

💡
同時アクセスを安全に処理する必要があるAPIを構築またはテストしている場合、これらの複雑なシナリオをシミュレートするのに役立つツールが必要です。Apidogを無料でダウンロードしてください。これは、ETagやヘッダーを使用した条件付きリクエストを簡単にテストできるオールインワンのAPIプラットフォームであり、アプリケーションが428応答を正しく処理できることを保証します。
ボタン

それでは、HTTP 428 Precondition Required がどのように競合する更新の問題を解決するのかを見ていきましょう。

問題:恐るべき「失われた更新」

428 が存在する理由を理解するためには、それが解決する問題を認識する必要があります。マルチユーザーシステムでは、2人以上のユーザーがほぼ同時に同じリソースを更新しようとすると、いくつかの問題が発生する可能性があります。

  1. 失われた更新 (Lost Updates): 2番目の書き込みが、最初の書き込みの変更を取り込むことなく上書きしてしまうという典型的な問題です。
  2. 競合する変更 (Conflicting Changes): 2人のユーザーが同じリソースの異なる部分に異なる変更を加えることです。
  3. 古いデータの更新 (Stale Data Updates): ユーザーが古い情報に基づいて変更を加えることです。

従来のアプローチでは、条件付きヘッダーを含めることでクライアントが「正しいことをする」ことに依存することがよくありました。しかし、クライアントがそれを忘れてしまったらどうなるでしょうか?428 コードは、サーバーが適切な振る舞いを強制することを可能にします。

HTTP 428 Precondition Required は実際に何を意味するのか?

428 Precondition Required ステータスコードは、オリジンサーバーがリクエストに条件を付けることを要求していることを示します。これは、クライアントが最新のデータで作業していることを証明するために、条件付きヘッダー(If-MatchIf-Unmodified-Since など)を含めることをサーバーが義務付けている方法です。

応答には、どのような前提条件が必要かについての役立つ説明を含めるべきです。典型的な 428 応答は次のようになります。

HTTP/1.1 428 Precondition RequiredContent-Type: application/problem+json{  "type": "<https://example.com/probs/conditional-required>",  "title": "Precondition Required",  "detail": "This resource requires conditional requests. Please include an If-Match or If-None-Match header.",  "instance": "/articles/123"}

サーバーは本質的にこう言っているのです。「この特定のリソースについては、無条件の更新は受け付けません。どのバージョンを変更しようとしているのかを私に示してください。」

より簡単に言えば、サーバーはリクエストを処理する前に、クライアントが If-MatchIf-Unmodified-Since といった前提条件ヘッダーを含めることを期待しています。

その前提条件が含まれていない場合、サーバーはリクエストを拒否し、428 Precondition Required エラーで応答します。

公式RFC定義

428ステータスコードは、ウェブ通信と信頼性を向上させるためにいくつかの追加HTTPステータスコードを導入したRFC 6585で定義されています。

その内容は次のとおりです。

「428 (Precondition Required) ステータスコードは、オリジンサーバーがリクエストに条件を付けることを要求していることを示します。その目的は、『失われた更新』の問題を防ぐことです。この問題は、クライアントがリソースの状態をGETし、それを変更してサーバーにPUTする間に、第三者がそのリソースを変更してしまった場合に発生します。」

これは多くの専門用語ですが、本質は単純です。複数のクライアントが同時に同じリソースを変更する際のデータの整合性上書きの回避に関するものです。

平易な言葉で説明する

このシナリオを想像してみてください。

Googleドキュメントでチームメイトとドキュメントを編集しているとします。ドキュメントを開き、いくつかの編集を加えて保存をクリックしますが、その間にチームメイトも変更を加えて、あなたよりも先に自分のバージョンを保存してしまいました。

このとき、バージョン管理がなければ、あなたの変更が彼らの変更を上書きしてしまいます。これこそ、428 Precondition Required ステータスコードがAPIで防ぐのに役立つことです。

これはクライアントにこう伝えます。

「このリソースを変更する前に、あなたが最新バージョンで作業していることを私に証明してください。」

なぜ428が導入されたのか?

RESTful APIや一般的なHTTP操作において、クライアントはリソースを読み取り、ローカルでいくつかの変更を加え、その後更新リクエストを送信することがあります。しかし、その間にリソースが変更されていた場合、無条件に更新を適用すると、より新しい変更を上書きしてしまう危険性があります。

クライアントに前提条件の指定を要求することで、サーバーは以下を保証します。

これは、同時操作や複数のユーザーをサポートするAPIにとって極めて重要です。

仕組み:条件付きリクエストの流れ

共同編集シナリオで 428 が失われた更新を防ぐのにどのように役立つか、完全な例を見ていきましょう。

ステップ1:ユーザーAがリソースを取得する

ユーザーAは現在のドキュメントを取得します。

GET /documents/123 HTTP/1.1

サーバーはドキュメントで応答し、この特定のリソースバージョンのユニークな識別子であるETagヘッダーを含めます。

HTTP/1.1 200 OKContent-Type: application/jsonETag: "abc123"{  "id": 123,  "title": "Project Proposal",  "content": "Original content...",  "version": "abc123"}

ステップ2:ユーザーBが同じリソースを取得する

ほぼ同じ頃、ユーザーBもドキュメントをリクエストし、同じETagを取得します。

ステップ3:ユーザーAが条件なしで更新を試みる

ユーザーAはドキュメントを更新しようとしますが、条件付きヘッダーを含めるのを忘れてしまいます。

PUT /documents/123 HTTP/1.1Content-Type: application/json{  "id": 123,  "title": "Project Proposal",  "content": "User A's updated content...",  "version": "abc123"}

ステップ4:サーバーの428応答

このエンドポイントは前提条件を要求するように設定されているため、サーバーは次のように応答します。

HTTP/1.1 428 Precondition RequiredContent-Type: application/json{  "error": "precondition_required",  "message": "This resource requires conditional updates. Please include an If-Match header with the current ETag."}

ステップ5:ユーザーAが正しいヘッダーで再試行する

ユーザーAのアプリケーションは 428 応答を受け取り、適切な条件付きヘッダーで自動的に再試行します。

PUT /documents/123 HTTP/1.1Content-Type: application/jsonIf-Match: "abc123"{  "id": 123,  "title": "Project Proposal",  "content": "User A's updated content...",  "version": "abc123"}

サーバーはこの条件付きリクエストを正常に処理し、新しいETagとともに 200 OK を返します。

ステップ6:ユーザーBが更新を試みる

ユーザーBが古いETagで更新しようとすると、サーバーは 412 Precondition Failed でそれを拒否できるようになり、失われた更新を防ぎます。

428と412 Precondition Failed:違いを理解する

これは、条件付きリクエストの世界における重要な区別です。

例え:

なぜ428 Precondition Requiredが存在するのか

一見すると、面倒に思えるかもしれません。なぜクライアントに自由に更新させないのでしょうか?

さて、428ステータスが存在するのには正当な理由があります。それは、分散システムにおけるデータ損失を防ぎ一貫性を確保するためです。

その目的をさらに詳しく見ていきましょう。

1. 失われた更新の防止

「失われた更新」の問題は、複数のクライアントが同じリソースを取得し、それぞれ独立して更新する際に発生します。前提条件がなければ、あるクライアントの更新が、別のクライアントの更新を黙って上書きしてしまう可能性があります。

428は、すべての変更がリソースが取得されてから変更されたかどうかをチェックすることを保証し、静かなデータ損失を防ぎます。

2. データの整合性の確保

If-Match のような前提条件を要求することで、サーバーは更新がリソースの正しいバージョンにのみ適用されることを保証します。これは、データに安全ロックをかけるようなものです。

3. 安全な同時実行性の促進

共同編集、API統合、RESTfulサービスなど、多くのユーザーが共有リソースと対話するシステムにおいて、428は同時実行性管理をより予測可能で安全なものにします。

4. ベストプラクティスの奨励

条件付きリクエストを強制することで、サーバーは開発者に対し、ETag条件付きGETバージョンチェックなどのRESTful設計のベストプラクティスに従うよう促します。

428 Precondition Required をいつ使用するか

以下のシナリオで 428 の使用を検討すべきです。

1. 共同編集アプリケーション

複数のユーザーが同時に同じドキュメントを編集する可能性のあるGoogleドキュメントのようなアプリケーション。

2. 競合頻度の高いリソース

複数のソースから頻繁に更新されるあらゆるリソース。例えば:

3. 機密データの更新

誤って上書きされると、財務記録や医療データのように深刻な結果を招く可能性のあるリソース。

4. 安全のためのAPI設計

良好なクライアントの振る舞いを強制し、一般的な同時実行性の問題を防止したい場合。

428 Precondition Required の実世界シナリオ

1. 同時API編集

複数のクライアントが同時に同じレコードを変更する際、428は更新が互いに上書きされないようにします。

2. バージョン管理されたAPI

時間の経過とともに進化するAPIは、クライアントが互換性のあるバージョンを使用していることを保証するために前提条件を強制できます。

3. 楽観的ロックシステム

楽観的同時実行制御のためにETagを使用するデータベースやREST APIは、競合を検出するために前提条件に依存しています。

4. ファイルまたはオブジェクトストレージAPI

S3のようなクラウドストレージシステムは条件付きリクエストを多用しており、428はそのようなルールを強制するのに自然に適合します。

Apidogを使ったAPIテスト

Apidog プロモーション素材

同時実行制御を扱う際、Apidogはあなたの秘密兵器となります。条件付きリクエストフローのテストには、慎重な設定と複数のステップが必要です。Apidogはこのような種類のテストに完全に適しています。

Apidogを使えば、以下のことができます。

ボタン

実装のベストプラクティス

サーバー開発者向け:

クライアント開発者向け:

より大きな視点:堅牢なAPIの構築

428 Precondition Required ステータスコードは、より堅牢で自己文書化されたAPIへの移行を表しています。クライアントに条件付きリクエストの使用を要求することで、あなたは次のことを行っています。

  1. データ損失の防止: 同時実行性のバグの全カテゴリーを排除する
  2. APIの安全性の向上: クライアントが誤ってデータを破損させるのをより困難にする
  3. ベストプラクティスの強制: クライアントを適切な使用パターンに導く
  4. より良い診断の提供: クライアントが間違いを犯したときに明確なフィードバックを与える

結論:リアクティブからプロアクティブなエラー処理へ

HTTP 428 Precondition Required ステータスコードは、同時実行制御をオプションのベストプラクティスから強制可能な要件へと変革します。これにより、エラー処理がリアクティブ(「あなたの更新は他の誰かのものと競合しました」)からプロアクティブ(「あなたの更新を検討する前に、あなたが現在のデータで作業していることを証明する必要があります」)へと移行します。

これは追加のステップのように思えるかもしれませんが、このアプローチは最終的に、より信頼性の高いアプリケーションと、静かなデータ破損によって作業が失われることのない、より満足度の高いユーザーにつながります。

現代のウェブアプリケーションを構築する開発者にとって、428 を理解し実装することは、API設計における洗練の証です。これは、APIが何をするかだけでなく、複数のユーザーがいる実世界の条件下でどのように動作するかを考えていることを示します。

そして、これらの洗練された同時実行制御を実装およびテストする準備ができたら、Apidogのような強力なツールが、条件付きリクエストロジックが完璧に機能し、ユーザーのデータと精神的な安定を保護することを保証するために必要なテスト環境を提供します。

ボタン

ApidogでAPIデザイン中心のアプローチを取る

APIの開発と利用をよりシンプルなことにする方法を発見できる