双方が変更を「コミット」する時期であることを示す確認 URL を使用して、軽量バージョンのトランザクションを実現しようとしている 1 組の REST アプリケーションがあります。手順は次のとおりです。これらはすぐには実行されません。手順の間にエンド ユーザーの承認を得るために一時停止する場合があります。
- アプリケーション A が変更を承認してステージングし、アプリケーション B に変更の準備が整ったことを通知します。
- アプリケーション B は変更をステージングし、準備ができていることをアプリケーション A に通知し、コミット時にアプリケーション A が「ヒット」する確認 URL を提供します。
- アプリケーション A は受信確認 URL に「ヒット」し、受信すると、アプリケーション B は変更をコミットして 200 を返します。アプリケーション A が 200 を取得した場合、変更をコミットします。それ以外の場合は、全員がロールバックします。
問題は、承認 URL に関して行うべき正しい操作は何かということです。2 つの「合理的な」選択肢があり、それぞれに欠点があります。
GET リクエストを使用する - 欠陥は、データが変更されていることであり、GET で許可されるべきではありません。
PUT リクエストを使用する - これは、データが変更され、
一度だけ発生することが想定されているため、より理にかなっています。ただし、PUT 要求には
Content-Length ヘッダーが必要であり、送信するデータがないため、多くの HTTP
クライアント ライブラリは "Content-Length: 0" の設定を拒否します。そのため、「壊れた」PUT が生成され、コンテンツ アイテムのない PUT を送信すると、(当然のことながら) 多くの場合、411 が返されます。解決策は、1 文字の本文を送信することです。これにより、PUT が有効になりますが、少し気分が悪くなります。
これは、1 文字の本体を持つ GET または PUT を使用してプロトコルを設計する必要があるかどうかを尋ねる狭義の質問です。
明確にするために、すべての HTTP クライアントが Content-Length: 0 ヘッダーの送信を拒否するわけではありませんが、Java HttpURLConnection は、PUT で実際にデータを送信する場合にのみヘッダーを送信します。また、すべての HTTP サーバーが Content-Length ヘッダーのない PUT を取得したときに 411 をスローするわけではありませんが、Rails (およびその他) はルールを正しく適用します。このプロトコルは、すべての言語、HTTP サーバー、および HTTP クライアントで機能する必要があるため、「X ですべて書き直す」という答えは役に立ちません。
これは REST の哲学に関する質問であり、「どの言語が優れているか」という質問ではありません。