Lazy Diary @ Hatena Blog

PowerShell / Java / miscellaneous things about software development, Tips & Gochas. CC BY-SA 4.0/Apache License 2.0

HTTPメソッドのセマンティクスとビジネスロジックのインピーダンスミスマッチ

Webアプリケーションを実装する際に、各処理の実装のトリガとなるHTTPメソッドは何であるべきか?という話は議論の的になりやすいようだ。たとえばStackOverflowによる以下の議論など。

stackoverflow.com

ここでは、特にエンタープライズアプリケーションの開発で議論のポイントとなりそうな点を備忘録列挙しておく。

  • HTMLのformタグはGETPOSTしかサポートしていない。なので、formタグでapplication/x-www-form-urlencodedを送信する前提のアプリケーションの場合、どうしたってPOSTを使ったうえでパラメタに処理のセマンティクスを含める必要がある*1
  • POSTリクエストはブラウザバック時にリクエスト再送可否を聞くダイアログが表示されるが、GETリクエストではそんなものはない。PRGパターンを実装する際に議論になる点。
  • アプリケーションサーバの前段にHTTPサーバやロードバランサを設ける構成の場合、GETリクエストのクエリストリングがそれらのアクセスログに出力されることになる。クエリストリングが個人情報等を含む場合、業務担当者と運用担当者の情報開示範囲の差を考慮してアクセスログsed等でフィルタする*2ことになるが、ビジネスロジック中の個人情報と思われるパラメタをすべて列挙してフィルタすることは難しい。
  • エンタープライズアプリケーションで実行される処理はHTTPの世界に閉じない。たとえば「帳票を印刷する」という処理はそもそも処理結果がHTTPの世界どころか別の機械(プリンタ)から別のメディア(紙)で出てくる。HTTPのセマンティクスはHTTPのプロトコル上で発生する事象しか定義しない。
  • アプリケーションの開発上、ある処理が「特定のレコードを取得する処理」であるかを客観的・機械的に示すことが難しい。たとえばDBやファイルから読み込みだけ行う処理を「取得処理」と定義すると、レコードの取得時に悲観排他や監査証跡記録を行うアプリケーションではレコードの取得処理が「取得処理」にならないことになってしまう。
  • HTTPのプロトコル上に処理が閉じるがRESTful APIのセマンティクスでは表現しづらい処理というものもあり、たとえば「複数レコードを選択して削除する処理をアトミックに行う」などが挙げられる。
  • 上記に挙げたようにビジネスロジックの内容からそのセマンティクスを読み取るのが難しい、あるいは人による解釈の違いが発生しやすい場合、多機能なアプリケーションでは機能ごとにセマンティクスが異なるというケースが発生しやすくなり、それはアプリケーション自体の開発者にとっても、アプリケーションの提供するAPIを利用する人にとっても落とし穴になりうる。
  • これは個人的な意見なのだが、HTTPは(アプリケーション層のプロトコルではあるが)あくまで通信プロトコルなのだから、ビジネスロジックのセマンティクスは通信レイヤについては不可知であるべきでは? 技術的な向き不向き(たとえばリアルタイム音声通信ならUDPが適するとか)は議論の俎上に載せてもよいが、処理の意味が下層のレイヤに縛られるのはレイヤ分離の観点から見てどうなんだ?というのはちょっと疑問に思っている。