[REST][misc] それでもやっぱりPUTにしたい理由。
http://d.hatena.ne.jp/IwamotoTakashi/20090326/p1
Tim Brayのエントリーはスルーしようと思ったんですが、彼のRackのエントリや、Sam Rubyのぼやき、などをみていて、おもしろそうだなー、といったところで、id:IwamotoTakashiさんのエントリにまとまっていたので、言及してみる。
[追記] なんかよく考えたら、大分論点がずれている。。エントリは残しておきますが、あまり関係ないかも。ただ、システムにおけるWebの役割を考えるともう少し考えたいですね。。
おおむね、POSTでいいじゃん、というRoyの言及には同意なのですが、一点、システム管理屋としての立場から見て口を出したくなります。つまりWebの世界から少し離れた立場での意見です。とりあえず、Webさえできればそれでいい、的な場合はこの議論はスルーできると思っています。というか、PUTかPOSTかの議論ではなくて、stateをexplicitにするかどうかの議論ですね(書いてみて思った)。RESTfulをどう実装するか、の前に、このような議論もあったのかもしれませんが、参考までに。
とりあえず、自分であれば、何が何でも以下のようなPUTにしてくれ、と主張したかと。
>>PUT /vm/3333 >>{"state": "rebooting"} << 202 Accepted
もしくは、
>>PUT /vm/3333/state >>"rebooting" << 202 Accepted もとの議論に習えば、POSTでState管理用のトランザクションリソースを作れ、という話もあって、 >|| >>POST /vm/3333 >>change_state_to="rebooting" << 201 Created
などもあるのかと思います。が一貫して、PUTのほうが、Webを事実集合のデータベースとして扱え、「Webをフロントエンドにしたポリシーベースの疎結合なシステムが組みやすい」という恩恵に預かれるかと思っています。POSTでコマンドを発行したつもりになるのは勘弁してください、ってことで。
PUTによる更新を採用すると /vm/3333 の状態を更新させるWebのプロセスと、それをトリガーに「/vm/{id} リソースにおいて、state == rebooting ならばリブートコマンドを実行する」というポリシーエンジンを独立して、疎結合に作ることができるはずです。データとプログラムを分ける、よろしく、プロセスとリソースは分けた方が、後々便利になると思っています*1。
ちょっと考えた程度では、次のようなポリシーを定義できるかと思います。
State | VM-type-attrs | Action |
rebooting | web | shutdown and boot |
rebooting | db | wait-commit, syncdata, shutdown and boot |
rebooting | monitored-system | stop-monitor-with-scheduled-shutdown, shutdown, boot, start-monitor |
DBは普通のshutdownがwait-commit, syncdataを含んでいる、というつっこみはおいといて、逆に monitored-system の場合は明示的に計画停止でっせー、って宣言しておかないと、管理画面が真っ赤になって泣きそうになって、しまいにゃオオカミ少年モニターができあがってしまいますので注意。
この手のポリシー、rebootのトリガーをPOSTでやってしまって、オブジェクト指向の必殺技の継承等で実装を追加していくぐらいなら、Prologライクに事実を書き連ねていく方が、(少なくともシステム管理を生業としている立場にたつと)非常に管理が楽になる、と思うんです。
RWSを読んだとき、SOAP/REST の対立には全く興味がなく、「真にポリシーベースのシステムの時代が来たなぁ」というのが感想でした*2。まぁ、オートマトンに戻るんじゃないか、という話はおいといて。
"便利になると思っています"には、確固たる確証はまだないのですが、こう考える背景について、以下、超雑感です。個人の意見として。。
POSTの失敗はWebServiceに見て取っています。
本来、Service Oriented Archtecture は、様々なビジネスプロセス、システムプロセスをサービスとして定義し、それをSOAPという標準化されたプロトコルでやりとりしようよ!、という事だったはずです。SOAP自体はHTTPに限らず、ですが、どうもHTTP POSTが使われていたようです(いわゆるPOSTのオーバーロード)。このことを思い出してみると、自分にとっては、2003年ぐらい。新しくでてきた.NETでWebServiceを使って実装しようや、という話になったとき「できるわけないじゃん」と思いました*3。なぜなら「サービス指向」=「プロセス指向」だったからです、プロセスをWebというハイパーメディア空間で実装するには無理が有りすぎです。
だいたい、業務アプリや企業の活動なんて「今XXという状態になっています、どうしますか?」とお伺いを立ててしかるべき人の判断に基づいて行われるのであり、ITシステムごときが「YYすることを柔軟に」できるはずがないのです。プロセスを柔軟に結びつけるなんて、(判断権限のある)偉い人の頭が柔軟なことが大前提なんだから、そこからしておかしい、と思っています。
大抵、Excel なりなんなりをメールに添付して「今こんな感じですけど、どうしますかね?」という話で、まさにSOA, Spreadsheet Oriented Architecture で活動しているわけです。そこに必要なのは、サービスの判断基準となるデータ(Fact)があることが大前提で、それに対して「FactがXならばYを行う」という企業の判断基準のポリシーを適用させた結果、システムとして成り立つものだと思うのです。
Webをデータベースとして、つまり、システム(系)におけるFactの集合として取り扱えるようにできれば、データの入り口を「業務として正規化(DBの意味での正規化ではなく)」でき、データにポリシーを関連づける、という作業がサービスの定義、であり、ポリシーによって実行されるプロセス、という形でImplementationをアプリケーションのアーキテクチャーから独立させて、少なくとも(Implementationに制約がなければ)デザイン上は柔軟なシステムになると、思うんです。
ただし、以上は、理想論であって、現実的には、Prolog ってあまり使われていないよね、アプリケーションでは、という落胆もあります。いや、システム管理の分野だと、この手の議論は大分進んでいるんですけど*4。 もちろん、BPM とかその手の分野でも進んでいるような気がするのですが、BPMと聞くだけで辟易してしまう正確なので(Big WebServiceのせいだと思っている)、その辺は知りません。
で、ぶっちゃけて思うのは、この手の理想を掲げたのはDOAであって、、、とか。しかし、自分が就職した@2004には、既にDOAはないがしろにされていたので、よくわかりません。