土曜日, 5月 31, 2008
【EC開発体験記 -リソース志向-】 APIをやめデータ構造に着目する
あらかじめ断っておくが、ここで説明するリソース志向は、私自身の開発の経験から必然的にたどり着いた解であって、一般的に説明されているROAとは多くの部分で異なる。ここでは、正確なROAの説明をするつもりはないし、本当のROAとは?などと、不毛な議論もやりたくない。ROAもしくはリソース志向という言葉を便宜上使わせていただいているが、それは、自分の解に一番近いと思われるからである。したがって、私の説明をそのまま世間で使うと痛い思いをするかもしれないので気をつけていただきたい。
まず、リソース(以下Resource)の定義から説明したい。Resourceとは、分析クラスから導き出されるEntityを具現化したものである。噛み砕いていうと、モデリングにより定義された自己完結したデータの集合という感じだ。前記事で、分析クラスのBoundary、Control、EntityをStrutsのMVCモデルに落とせない話をしたが、リソース志向では、EntityがそのままResourceとなる。これは非常に分かりやすい。(Entity設計の責務は誰が負うべきかという課題はあるが、これはまたの機会に説明したい)また、Resourceは、それを指し示すID(URI)をもち、データ構造を公開できる。公開の手段は、XML、JSON、YAMLなんでもいい。これについては、インターオペラビリティの話として後ほど詳しく説明する。それから、ResourceのAPIはCRUDの4つだけとする。トランザクションを管理し、それぞれのAPIは1つのUOW(UnitOfWork)で実行されなければならない。注意していただきたいのは、このAPIはHTTPに限った話ではないということ。言語のAPIにもなりえる概念的なものということだ。また、RESTはステートレスといわれるが私はそうする必要はないと考えている。単純にステートレス=揮発性と考えると、リソースが揮発性になってしまうのはむしろ不都合になるからだ。リソースは不揮発性だが、トランザクション管理という意味では、不完全なものは破棄するという性質(揮発性)は持たなければならない。ステートレスの話はトランザクション管理に帰結すると思うので、私の定義では1UOWとなった。
<私が考えるリソース志向>
1)リソースは自己完結したデータの集合
2)リソースはデータ構造をもち公開できる
3)リソースに対してCRUDで操作する
4)リソースは特定できるアドレス(URI)をもつ
5)リソースに対して1UOWで操作する
ここで話が戻るが、公開するデータ構造は何でもいいという話をしたい。公開用のスキーマ言語は、必要最低限のデータ構造を表現できれば十分。それは、きちんとインターフェースを定義したい方はスキーマ言語を使うだろうが、それでもセマンティクスを十分に定義できないのは同じであり、いずれにしてもデータ長や意味などを説明した資料は必要になるからだ。
私はかつて、Webサービスの最も重要な性質の一つとして、インターオペラビリティを挙げていた。しかし多くの経験から学んで今ではかなり否定的になっている。数年前になるが、XMLコンソーシアムで、参加企業十数社がそれぞれの製品をもちよってWebサービスの接続実験を行ったことがある。その実験では、たしかに、言語やプラットフォームを越えて接続できるという利点は認められたが、各製品の制約が多すぎて、WSDLを変更しなければならないことがしばしばあった。製品に合わせてWSDLを変更するなんて本末転倒である。実際に接続するには相当な苦労があったわけで、ダイナミックバインディングなんてのは夢の世界。絵に描いた餅であった。そもそも、スキーマ言語でセマンティクスを完全に定義できないことの重要性に早く気づくべきだった。
インターオペラビリティの問題は本当に難しい。WSDL(XMLSchema)はCORBAにはできなかった言語の壁を越えることができたがセマンティクスの問題は解決できなかった。AtomPubは、この問題を解決できる可能性があるとは思ったが、普及していない現状を見る限りでは難しいように思える。(AtomPubにはすごく興味があって、ReflexではRFC前であるにもかかわらず実装を行った。たしか、2005年頃までのdraft-ietf-atompub-protocol-04.txtの実装を行ったが、自分の感性に合わなくなったことと、インターオペラビリティに疑問を感じたのでやめてしまった。)結局のところ、AtomPubにも同様の困難が待ち受けていると思われる。
そこで得た結論は、否定の3と7
3.各サブシステムで共通のエンティティを使用(最小単位は1品1葉1レコード)
7.サブシステム間を密に結合させない(サービスだけで繋ぐ)
これは要するに、システム共通のentityを定義して、それをやりとりすることだけに注力しようということだ。SOAPやAtomPubなどのAPIを介さないし、そのような共通APIに該当するものを敢えて開発しない。しかし、最低限は必要になるので、先に挙げたリソース志向を踏まえて定義する。具体的には次のような非常にシンプルなAPIを定義することになる。
<API例(entityはリソースの1インスタンス)>
entity = create(entity);
entity = retrieve(entity);
entity = update(entity);
entity = delete(entity);
サブシステム内であれば上記APIをそのまま使う。サブシステム外ではHTTPのPOST/GET/PUT/DELETEがそれぞれ対応する。例えば、GETを実行するとシリアライズされたentityが返ってくる。繰り返しになるが、entityの表現はJSONでもXMLでも何でもいい。実際のプロジェクトではReflexによりJSONとXMLの両方を使っている。(Reflexはentityの写像を取るフレームワーク。entityをJSONとXMLにシリアライズできる。)
自己完結したデータの集合が意味するところは、一つは自分から他のリソースへの依存がないということ、もう一つは、外からの影響を受けないこと。例えば、他リソースのインターフェースが変更になっても、スケルトンを取り込みなおす必要がない。
サービス志向では、インターオペラビリティの問題があって、セマンティクスに関係した部分が不安要素として残っていた。自己完結したデータの集合、すなわち、リソースを中心に設計していくことで、より安定した大規模なシステムを並行開発できるようになる。
登録:
コメントの投稿 (Atom)
2 件のコメント:
最近、WebSphere開発のCTOでIBMフェローのJerry Cuomoがおおっぴらに、Restful SOAという言葉を使い始めました。Project Zeroの活動が、まさにRESTでアクセスするリソースのComposition(マッシュアップと言ったほうが良いかも)をJDKだけの上で動くRuntimeで組み立てます。RSS、ATOMフィードで取れるものを組み上げて、Webクライアントに出すわけです。Zeroは基本はREST、JSON、RSS、ATOMなどの技術の上でGroovy又はPHPでアプリを作ります。 一度、遊んでみてはいかがでしょう? 清水
http://www.projectzero.org/
toshisさん、Project Zero情報ありがとうございます。発想が似ているのでびっくりしました。JavaでもRESTを中心にWebアプリを見直そうという流れは本物のようですね。あちこちでRESTの大合唱が起きていて、当分は続きそうな感じです。あと、ROAとはいわずにRestful SOAがいいですね。
コメントを投稿