Tender Surrender

先日のキャッシュに関する記事でPHP版Shindigではcontent-rewrite機能が使えないと書いたのですが、1.0.xの段階で、既に実装されているようです。

content-rewrite機能はOpenSocial0.9で提案された機能ではありますが、0.8や0.7でも実行できそうです。

使い方はこんな感じ。

<Optional feature="content-rewrite">
  <Param name="expires">86400</Param>
  <Param name="include-url"></Param>
  <Param name="exclude-url">excluded</Param>
  <Param name="exclude-url">moreexcluded</Param>
  <Param name="minify-css">true</Param>
  <Param name="minify-js">true</Param>
  <Param name="minify-html">true</Param>
</Optional>
  • expires: キャッシュの有効期限を秒で指定。デフォルトは86400秒(24時間)。
  • include-url: キャッシュしたい外部コンテンツのURLを指定。”*”アクタリスクが使える。”.gif”などとすると、前後にアスタリスクがあるものと想定される。繰り返し可。
  • exclude-url: キャッシュしたくない外部コンテンツのURLを指定。適用方法はinclude-urlと同じ。
  • minify-css: CSSファイルの内容を圧縮してキャッシュするかどうかを”true”または”false”で指定。デフォルトは”true”
  • minify-js: JSファイルの内容を圧縮してキャッシュするかどうかを”true”または”false”で指定。デフォルトは”true”
  • minify-html: HTMLファイルの内容を圧縮してキャッシュするかどうかを”true”または”false”で指定。デフォルトは”true”

exclude-urlがinclude-urlよりも優先される。”*”はすべてのURLを指定。詳細な動作はコンテナ依存。

これで、開発がもう少し楽になりますね

Read on...

来る2月12日、13日に目黒雅叙園にてDeveloper Summit 2009が開催されます。

中でも、12日17:40からOpenSocialパネルディスカッション 2009年、OpenSocial普及元年に「これから」を大予言にご注目。

最近「OpenSocial入門」を執筆された田中洋一郎さん、リクルートの川崎有亮さん、mixiから小山浩之さん、Googleの石原直樹さん、白石俊平さん、矢野りんさんに加え、僕もパネラーとして登壇することになりました。

今年はいよいよmixiやgoo、OpenPNEなど、日本でも複数のOpenSocial環境が利用できるようになるいわば元年です。OpenSocialが今後ウェブにとってどういう役割を果たして行くのか議論する予定です。ご興味のある方はぜひ、ご参加ください。

参加の申し込みはこちらから

Read on...

先日の記事でShindigが持つOpenSocialアーキテクチャの強力なキャッシュ機能について触れました。Shindigには大きく4種類のキャッシュが存在しています。

  • ガジェットXMLのキャッシュ
  • makeRequestでアクセスされる外部APIのキャッシュ
  • featureを固めたJavaScriptのキャッシュ
  • JavaScript、CSS、imgなどHTMLからリンクされたリソースのキャッシュ

ガジェットXMLのキャッシュ

OpenSocialガジェットを開発し始めて最初につまずくのがこのガジェットXMLのキャッシュでしょう。ガジェットXML上で変更を行っても、それが実際のガジェット表示上に反映されない場合は、まずガジェットXMLがキャッシュされていることを疑いましょう。

ガジェットXML上でJavaScriptコードを修正しつつサンドボックス環境で動作確認しながら開発したい場合は、URLのquery部分にnocache=1を加えることで、キャッシュが無効化されます。これで開発がだいぶ楽になるはずです。(コンテナによってはURLの末尾が途中からhash(#以降)になっている場合があるので、気をつけてください。)

なお、iGoogleのサンドボックスではMy Gadgetsでキャッシュを無効にできたり、hi5ではサンドボックスなら特に何もしなくてもキャッシュが無効だったりといった特徴もあります。

makeRequestでアクセスされる外部APIのキャッシュ

makeRequestを使って外部のリソースにGETでアクセスした場合、これもキャッシュされます。例えばRSSを取得するような場合、更新頻度の低いものであれば相手方サーバーの負荷を少しでも軽減することができます。

これを回避したい場合は、makeRequestのopt_paramsにgadgets.io.ProxyUrlRequestParamters.REFRESH_INTERVALというパラメータを追加し、0に設定してください。これで、キャッシュされなくなります。

featureを固めたJavaScriptのキャッシュ

OpenSocialでは、ガジェットXMLに[email protected]を加えることで、様々な機能が利用できるという仕様があります。このfeatureは、ガジェット内に表示されるHTMLにJavaScriptを追加することで機能を実現していますが、Shindigではここでも軽量化/効率化を図っています。featureのJavaScriptは、レンダリング時に難読化した上で全てをひとつに繋げて、キャッシュされます。

一般ユーザー/ガジェットディベロッパーがこれを意識する必要はほぼありませんが、頭の片隅にいれておきましょう。

JavaScript、CSS、imgなどHTMLからリンクされたリソースのキャッシュ

コンテナによっては(orkut, iGoogle, hi5等、今のところJava版のShindigを使っているサービス)、ガジェットXML内で指定された外部のJavaScript、CSS、imgが、レンダリング時にキャッシュされます。レンダリングされたガジェットのHTMLを見ると、キャッシュされた外部リソースのURLのpath部分の最後にconcatが付いていることから、キャッシュされていることが分かると思います。

この機能はContent Rewriteと呼ばれるのですが、OpenSocialバージョン0.9からは正式な機能として取り込まれますが、現段階ではShindig Java版独自の機能です。0.9では、ガジェットXMLの設定でどのファイルタイプをリライトするのか、JavaScriptなら圧縮するか、キャッシュする場合の有効期限はどれくらいか、などを指定できるようになります。

さて、このキャッシュは実運用時に各ファイルの置かれているサーバーの負荷を軽くすることが目的ですが、開発時にはコードの修正が即座に反映されず、効率を下げてしまうこともあるでしょう。これを回避するには、下記をXMLに追加します。

<optional feature="content-rewrite>
  <param name="include-tabs" />
</optional>

コンテナによってはサポートしない場合がありますので注意してください。

ところで、PHP版 Shindigの場合はこの機能がありません。つまり、もしガジェットが例えば、あなたのサーバーに用意したファイルを指しているとしたら、ガジェットのレンダリングの度にリクエストが発生するため、開発には便利な反面、本番環境で大量にアクセスが来た場合サーバーに負荷がかかってしまいます。これを回避するため、キャッシュ機能をうまく利用する、というテクニックもあります。

http://opensocial-container/gadgets/proxy?url=http://devlog.agektmr.com/image.gifのように、ドメインに”/gadgets/proxy?url=”を付けて、意図的にShindigのプロキシを入れてしまいましょう。(concatと異なり、難読化や圧縮はされません。)

追記(2009/2/3)

上記に関して、コメント欄でmainyaさんから、getProxyUrlを使ったやり方を教えていただきました。

var params = {'REFRESH_INTERVAL' : 3600*24*7};
var url = 'http://example.com/img/logo.jpg';
try{
  url = gadgets.io.getProxyUrl(url, params);
}catch(e){}

このやり方でURLを取得すれば、コンテナに依存しない方法でキャッシュを意図的に効かせた参照を行うことができるようになります。(MySpaceでは使えないのでtry/catchした方がよいそうです)

 

Read on...

1月23日に株式会社DeNAオフィスにて、SocialWeb勉強会 vol.1を開催しました。参加者は50名で、キャンセル待ちも出るほどの盛況ぶり。ソーシャルウェブの注目度の高まりを感じる勉強会となりました。

僕からのプレゼンテーションは、主催としてコミュニティの今後の方向性を示すと共に、現在の海外サービスで示されている方向性および、実際にメインプレイヤーたちがどういう形でソーシャルウェブ化に取り組んでいるかという状況を紹介しました。多くの内容は既にこのブログで紹介してきたものでしたが、いいまとめになったのではないかと思います。

スライドはSlideShareにアップしましたので、掲載しておきます。フォントが変わってしまって少々見づらい部分もあるかもしれませんが、ダウンロードもできますのでぜひご覧ください。

[slideshare id=948379&doc=socialweb-vol1-1232769487727464-3&w=425]

他にもよういちろうさんにOpenSocial導入のためのプレゼンテーション、id:ZIGOROuさんによる2009年のOpenIDの動向を紹介するプレゼンをしていただきました。詳しい内容は追ってこちらのページにアップされることと思います。ぜひチェックしてみてください。

最後に、会場を提供してくださったDeNAと、お手伝いしてくださったDeNA社員の皆様にお礼申し上げたいです。ありがとうございました。

追記:神部さんの飛び入り参加によるPaypal + OpenPNEのプレゼンについて書くのを忘れていました。僕のプレゼンの中でも触れた課金によるマネタイズにも絡む、実に興味深いお話でした。

再追記:PowerPointをPDFに変換してからSlideShareに再アップしたら、きれいに表示されるようになりました。

Read on...

OpenSocialと関わるには

  • コンテナになる
  • ガジェットを開発する
  • RESTを使ったクライアントサービスを作る

といった選択肢が考えられますが、そのいずれを選択するにしても、アーキテクチャについて知っておくことはとても重要です。特にガジェットを開発するに当たっては、アーキテクチャを知っていることでより開発しやすい場面が多々あります。

そこで今回は、OpenSocialに対応するコンテナのほとんどで利用されているオープンソースのリファレンス実装、Shindigのアーキテクチャについて解説したいと思います。

ガジェットとSNSの関係

iGoogle(既にShindigが利用されている)ではどうやって第三者の作ったガジェットを表示しているかご存知でしたか?実は、別ドメイン(iGoogleならgmodules.com)上にレンダリングしたガジェットを、iframe内に表示しているのです。

理由は、同ドメイン上に第三者の書いたJavaScriptを置くことは、セキュリティ上危険だからです。詳しくは以前Cajaについて解説した記事がありますので、そちらをご覧ください。

OpenSocial Gadget Rendering

APIはどこにあるか

OpenSocialにはPeople, Group, Activity, Persistentの4つのソーシャルなAPIが用意されていますが、それぞれRESTfulによるJSON, XML, AtomPub形式と、RPCによるJSON形式が用意されています。ShindigのJavaScript APIでは、この中でもRPCによるJSON形式が使用されています。

先ほど2つのドメインについて説明しましたが、JavaScriptのAPIということはAjaxなので、当然同じドメインということで、エンドポイントはShindigのドメイン上に存在します。

OpenSocial Server Architecture

ガジェット表示の流れ

基本的な構造が分かったところで、実際にガジェットを表示するまでの流れを見てみましょう。

どのガジェットを表示するのか

ガジェットを表示するためには、まずガジェットを表示したいというユーザーの意思が必要です。これはiGoogleであれば、ガジェットディレクトリから好きなガジェットを選び、自分のページを表示する、というサービス側での作業によって行われます。表示したいガジェットが分かったところで、サービス側もガジェットを表示するためのiframeを表示する必要があるため、ガジェットに関する情報を収集します。これはShindigのmetadata APIを使って行われます。

metadataの取得

metadata APIのリクエストを取得したShindigは、キャッシュを参照します。キャッシュにガジェットの情報が残っていない場合は、サービスからのリクエストに基づいてガジェットXMLを取得し、解析します。

iframeのレンダリング

ガジェットに関する情報を取得したサービスは、ガジェットを表示するためiframeをレンダリングします。これにより、iframe内にガジェットを表示するためのリクエストがブラウザからShindigに投げられます。

基本的にガジェットXMLに記述されたContentsの内容はそのまま表示されますが:

  • 指定されたガジェットのfeature(tabやminimessageなど、ガジェットが持つ機能セット)のJavaScriptがHTMLに追記される。
  • 設定によってはJavaScript、CSS、画像などのあらゆる外部コンテンツがShindig上にキャッシュして呼び出される。

という点は覚えておいて損はないでしょう。

これでガジェットの表示は完了です。Firebugなどを使ってAPIを試してみれば、Shindigにリクエストが飛んでいることが分かると思います。

外部サーバーを使うAPI

外部サーバーを使う際、JavaScript APIとしてgadgets.io.makeRequestが使用されます。コンテンツタイプとしてFEEDを選択すると、RSSやRDF、Atomを共通のフォーマットで返してくれたり、JSONを選択すると、データが返ってきた時点ですぐにJSONオブジェクトとして扱えるようになっています。

また、セキュリティ面でもいくつかの選択肢が用意されています。

  • 通常のリクエスト
  • Signed Request
  • OAuth

通常のリクエストは、特に認証等のかかっていないAPIに対して行われるものです。Signed Requestとは、OAuth Consumer Requestを指しており、これを利用することで、外部サーバーはガジェットからのリクエストのみを扱うことができるようになります。OAuthはOAuth Coreを指しており、外部サーバーはガジェットからのリクエストであることだけでなく、誰からのリクエストなのかをセキュアなクレデンシャルで認証した上で扱うことができるようになります。

OAuthについてはこの辺りこの辺りを参考にしてください。

ここで注意しなければならないのが、すべてShindigのproxyを介して行われるということです。先ほど書いた通り、ここでもGETリクエストには強力なキャッシュ機能が利用されるため、若干注意が必要な場合があります。キャッシュについては次回以降まとめて記事にしたいと思います。

Read on...