Web APIに柔軟に対応するために
MetaGatewayは、他のブログエディタではサポートしていないさまざまなサービスなどを、すべて同じように操作することができます。具体的には「対応サービスとサポートする機能」を参照してください。
さらにこれらのサービスだけでなく、Google Mapや各種アフィリエイト、その他さまざまなAPIを利用して、外部サイトとのマッシュアップを行っています。数だけでいえば、ある意味究極のマッシュアップサービスかもしれません。
MetaGatewayでは新しいサービス等が増えても、非常に簡単に機能追加が可能になるように注意して設計されています。APIや認証などさまざまなプラグインを配置すれば対応できるような形です。
たとえば、APIのプラグインであれば、Twitterならtwitter.py, mixiならmixi.pyというコードの中に、サービスに依存するコードがすべて集約されています。問題の切り分けがしやすく、メンテナンスコストが低い構成というのを常に意識しています。
実際はファイルを置いただけで機能を追加できるようにでもできますが、ファイルのリスティングなどのパフォーマンスをちょっとでも稼ぐために、プラグインモジュールの__init__.pyにリスト1のようなデータを定義しているので、そこは合わせて修正する必要はあります。
MetaGatewayのプラグイン実装
まずはMetaGatewayのコードを実際に出しながら、どういう構造になっているのかを話していこうと思います。まず具体的に、それらのプラグインがどのように実装されているのかを簡単に説明します。例として、マイクロブログに対応するためのプラグイン部分をとりあげます。マイクロブログの代表的なものに、Twitter、 はてなハイク、Jaiku、cotobako、Haru.fm、もごもご、piyo、Timelog、Wassr等があります。
まず、すべてのAPIプラグインはApiPlugin抽象クラス(リスト2)からの派生クラスになります。これらのメソッドをオーバーライドすることにより、挙動を制御することができます。インターフェースに関しては、XMLRPCのインターフェース(blogger、metaweblog、 movabletype、 typepad)とatompubを抽象化したあとに、各種APIを参考にすべてを表現するために足りないものを追加したものになります。
リスト2のコードは、だいたい先に挙げたインターフェースと1対1にマップされているのですが、いくつかわかりにくいものもあるので説明しておきます。
isAuthedは、getUserChannels時に認証できない場合、実際に記事を取得してみて認証を行うためにあります(ただ、実際には書き込んでみないと合っているかどうが一切かわからないサイトも多く、「開発者泣かせ」も結構あります)。
isCreatePostは、本当にデータが書き込まれたかをチェックするためにあります(Twitterなどでは、連続で同じステータスを書き込むと成功であるにもかかわらず、1つにまとめられてしまい書き込まれないため)。
rebuildSiteは、MovableTypeのようにmt.publishPostしないと再構築されないサイトが数多くあるので、そのためにあります。formatTitle, formatBodyはMicroformatsなどが必要なサイトの場合、そこを変換するためにあります。さらに、Google App Engineのfetchでは、postのContent-Typeが常にapplication/x-www-form-urlencodedのになってしまうので、multipart/form-dataできるようにメソッドを追加しています。
プラグイン作成の実際
実際のTwitterプラグインはリスト3のようになります。これに関しても、Twitter互換のAPIをもつサイトが多いので、書き換えられるようにしているわけです。そのため、Twitterから派生しているmogomogoは、リスト4のように簡単に記述することができます。また「はてなハイク」なども同様にTwitter互換のAPIですので、非常に簡単に実装することができるわけです。
日付だけを見てもマイクロブログごとに好きなフォーマットを使っているので、残念ながら一貫性がほとんどありません。
表1 Twitter系マイクロブログの日付フォーマット
twitter | '%a %b %d %H:%M:%S +0000 %Y' |
mogomogo | '%a %b %d %H:%M:%S +0900 %Y' |
nowa | '%Y-%m-%d %H:%M:%S' |
timelog | '%Y/%m/%d %H:%M:%S' |
はてなハイク | '%Y-%m-%dT%H:%M:%SZ' |
これらも含めて各マイクロブログごとに微妙な差異があるため、各専用クライアントはそれらを吸収する必要があり、それぞれ対応しなければなりません。なぜ再発明したがるのかがいまひとつ理解できませんが、真似るところは真似る、特化する所は特化する。メリハリが大事なのではないかなと思います。
ちなみに、私が開発しているしゃべるでは完全Twitter互換なAPIを提供しています。そのためHOSTSにtwitter.comと社内サーバのマッピングを記述すれば、どのような専用クライアントを使っても動作します。HOSTSの書き換えを行いたくない場合は、P3のような優れたクライアントを使えば動作します。
ユーザの「入り口」を広げたい
最近のWebアプリケーションは、Webインターフェースだけに特化したものでなくなってきています。スマートフォン、モバイル、ブラウザのExtension、専用クライアントなど、どれもシームレスに連携できるのが当たり前になりつつあります。DropBoxなどのようにExplorerの拡張になっているものもあります。ユーザの入り口を限りなく広めていく必要があるのです。MetaGatewayでもそれらの入り口を広げるためにAPIを実装しています。そのため、どのブログクライアントでも同様に操作することが可能になるのです。
よく言われるのですが、なぜにAtomPubでなくて、MetaWeblogなのか? 理由は明白です。MetaWeblogの方が仕様が明確だからです。機能も豊富ですし、ほとんどのブログクライアントで実装されています。もちろんGoogleのAPIのようなAtomPubの拡張はいいと思いますし、AtomPubの方が技術的にはエッジが利いているかもしれません。ただ、私にとっては最も重要なことではありません。技術云々よりも、まずたくさんの人に喜んでもらうにはどうするのが一番いいのか? それが大切だと考えています。