dena technology seminar #3 - opensocial and javascript
TRANSCRIPT
OpenSocial
and
JavaScript
DeNA
横江直輔 (@zentooo)
Profile
• YokoeNaosuke
• 2010年度入社 / エンジニア
• Hatena: http://d.hatena.ne.jp/zentoo/
• Twitter: http://twitter.com/zentooo
Agenda
1. Y!モバゲー JS API
2. Test of JS API
3. OpenSocialの今後
1. Y!モバゲー JS API
1. Y!モバゲー JS API
1. Y!モバゲー JS API
• OpenSocial 0.8
1. Y!モバゲー JS API
• OpenSocial 0.8
• Core APIはほぼ提供(opensocial.*, …)
1. Y!モバゲー JS API
• OpenSocial 0.8
• Core APIはほぼ提供(opensocial.*, …)
• 独自API(mbga.*)
OpenSocial API
OpenSocial API(1)
• People API
• Activities API
• AppData API
OpenSocial API(1)
• People API
• Activities API
• AppData API
これらはJSON-RPC経由でDBに話しかけるAPI
JSON-RPC
JSON-RPC
• HTTPベースのRPC
JSON-RPC
• HTTPベースのRPC
• メッセージフォーマットにJSONを使用
JSON-RPC
• HTTPベースのRPC
• メッセージフォーマットにJSONを使用
Client Server
{“method”: “people.get”, “params”:
{“userId”: “@owner”, “groupId”: “@all”, “fields”: …. }
}
{“id”: “person”, “result”:
{“nickname”: “sengoku38”, “profileUrl”: “http://…” … }
}
OpenSocial App and JSON-
RPC
OpenSocial Container
OpenSocial App JSON-RPC
Mbga DB
XmlHttpRequest
OpenSocial API(2)
• opensocial.requestSendMessage()
• opensocial.requestShareApp()
• opensocial.requestPayment()
OpenSocial API(2)
• opensocial.requestSendMessage()
• opensocial.requestShareApp()
• opensocial.requestPayment()
これらはポップアップを表示するAPI
Popup
OpenSocial Container
OpenSocial App
友達を招待
Popup
OpenSocial Container
OpenSocial App
友達を招待
Popup
OpenSocial Container
OpenSocial App
招待して大丈夫か?
大丈夫だ、問題ない
OpenSocial API(3)
• gadgets.Tab
• gadgets.MiniMessage
• gadgets.window
• gadgets.flash
OpenSocial API(3)
• gadgets.Tab ->いらない子
• gadgets.MiniMessage
• gadgets.window
• gadgets.flash
OpenSocial API(3)
• gadgets.Tab ->いらない子
• gadgets.MiniMessage ->いらない子
• gadgets.window
• gadgets.flash
OpenSocial API(3)
• gadgets.Tab ->いらない子
• gadgets.MiniMessage ->いらない子
• gadgets.window ->中間管理職
• gadgets.flash
OpenSocial API(3)
• gadgets.Tab ->いらない子
• gadgets.MiniMessage ->いらない子
• gadgets.window ->中間管理職
• gadgets.flash ->無双
OpenSocial API(3)
• gadgets.Tab ->いらない子
• gadgets.MiniMessage ->いらない子
• gadgets.window ->中間管理職
• gadgets.flash ->無双
これらは主にgadgetの表示に関するAPI
Gadgetってそもそも
どういう風に
表示してんの?
OpenSocial App and Shindig
OpenSocial Container
Shindig
OpenSocial App and Shindig
OpenSocial Container
Shindig
OpenSocial App and Shindig
OpenSocial Container
Shindig
Request Rendering
OpenSocial App and Shindig
OpenSocial Container
Shindig
Request Rendering
SAP Server
OpenSocial App and Shindig
OpenSocial Container
Shindig
Request Rendering
SAP Server
GadgetXML
OpenSocial App and Shindig
OpenSocial Container
OpenSocial App
Shindig
Request Rendering
Render
SAP Server
OpenSocial App and Shindig
OpenSocial Container
OpenSocial App
Shindig
Request Rendering
Render
SAP Server
OpenSocial API(4)
• gadgets.json
• gadgets.utils
• gadgets.io
OpenSocial API(4)
• gadgets.json ->window.JSON
• gadgets.utils
• gadgets.io
OpenSocial API(4)
• gadgets.json ->window.JSON
• gadgets.utils ->名前の通り
• gadgets.io
OpenSocial API(4)
• gadgets.json ->window.JSON
• gadgets.utils ->名前の通り
• gadgets.io ->無双
OpenSocial API(4)
• gadgets.json ->window.JSON
• gadgets.utils ->名前の通り
• gadgets.io ->無双
これらはユーテリティ的なAPI
gadgets.io.makeRequest
• 要はCross-Domain XHR
• Shindigがリクエストをproxy
• XML, JSON, RSSをデコード
• Signed-Requestも可能
gadgets.io.makeRequest
OpenSocial Container
OpenSocial App
Shindig
XHR
gadgets.io.makeRequest
OpenSocial Container
OpenSocial App
ShindigExternal
Site
XHR
mbga API
mbga API
• BlackList API
• NGWord API
• Avatar API
• TextData API
• Diary API
mbga API
• BlackList API ->いわゆるblock
• NGWord API
• Avatar API
• TextData API
• Diary API
mbga API
• BlackList API ->いわゆるblock
• NGWord API ->いわゆるフィルタリング
• Avatar API
• TextData API
• Diary API
mbga API
• BlackList API ->いわゆるblock
• NGWord API ->いわゆるフィルタリング
• Avatar API ->いわゆるアバター
• TextData API
• Diary API
mbga API
• BlackList API ->いわゆるblock
• NGWord API ->いわゆるフィルタリング
• Avatar API ->いわゆるアバター
• TextData API ->いわゆる…?
• Diary API
mbga API
• BlackList API ->いわゆるblock
• NGWord API ->いわゆるフィルタリング
• Avatar API ->いわゆるアバター
• TextData API ->いわゆる…?
• Diary API ->いわゆる日記投稿機能
APIまとめ
• OpenSocial 0.8にだいたい準拠
• mbga.*以下に独自API
2. Test of JS API
2. Test of JS API
• ちょっと環境がややこしい• gadgets.rpc
• Iframe
• Security Token
• QUnitを使用
• Test::QUnitで自動実行
OpenSocial Container & App
OpenSocial Container
OpenSocial App
[hash].app.mbga-platform.jp
yahoo-mbga.jp
OpenSocial Container & App
OpenSocial Container
OpenSocial App
[hash].app.mbga-platform.jp
yahoo-mbga.jp
.js .js .js .js
.js .js .js
gadgets.rpc
OpenSocial Container
OpenSocial App
[hash].app.mbga-platform.jp
yahoo-mbga.jp
gadgets.rpc
OpenSocial Container
OpenSocial App
[hash].app.mbga-platform.jp
yahoo-mbga.jp
gadgets.rpc.register
gadgets.rpc
OpenSocial Container
OpenSocial App
[hash].app.mbga-platform.jp
yahoo-mbga.jp
gadgets.rpc.register
gadgets.rpc.register
gadgets.rpc
OpenSocial Container
OpenSocial App
[hash].app.mbga-platform.jp
yahoo-mbga.jp
gadgets.rpc.register
gadgets.rpc.call
gadgets.rpc.register
Inside of gadgets.rpc
• window.postMessage -> modern browsers
• frameElement -> Firefox 2.x
• Native IE XDC -> IE6, 7
• RMR -> Safari 2.x, Chrome 1
• IFPC -> all others
window.postMessage
• HTML 5
• Standard way ( hackではない )
• Cross-Domain messaging between
windows
• Web Workersへのmessagingにも
window.postMessage
OpenSocial Container
OpenSocial App
[hash].app.mbga-platform.jp
yahoo-mbga.jp
window.postMessage
OpenSocial Container
OpenSocial App
[hash].app.mbga-platform.jp
yahoo-mbga.jp
window.parent.postMessage(msg)onmessage
child.postMessage(msg) onmessage
IFPC
• Inter-Frame Procedure Call
• 孫iframe + fragment IDで通信
• 一応どんなブラウザでも動く
IFPC
OpenSocial Container
OpenSocial App
[hash].app.mbga-platform.jp
yahoo-mbga.jp
function foo
IFPC
OpenSocial Container
OpenSocial App
[hash].app.mbga-platform.jp
yahoo-mbga.jp
(invisible iframe)
yahoo-mbga.jp
function foo
IFPC
OpenSocial Container
OpenSocial App
[hash].app.mbga-platform.jp
yahoo-mbga.jp
(invisible iframe)
yahoo-mbga.jp
ifr.src = http://…#<json>
function foo
IFPC
OpenSocial Container
OpenSocial App
[hash].app.mbga-platform.jp
yahoo-mbga.jp
(invisible iframe)
yahoo-mbga.jp
ifr.src = http://…#<json>
window.parent.parent.foo()
function foo
Share app with gadgets.rpc
[hash].app.mbga-platform.jp
yahoo-mbga.jp
Share app with gadgets.rpc
[hash].app.mbga-platform.jp
yahoo-mbga.jp
1.opensocial.requestShareApp
5.callback
Share app with gadgets.rpc
[hash].app.mbga-platform.jp
yahoo-mbga.jp
1.opensocial.requestShareApp
2.shareApp
5.callback
gadgets.rpc
Share app with gadgets.rpc
[hash].app.mbga-platform.jp
yahoo-mbga.jp
1.opensocial.requestShareApp
2.shareApp
5.callback
3.endpoint DBgadgets.rpc
Share app with gadgets.rpc
[hash].app.mbga-platform.jp
yahoo-mbga.jp
1.opensocial.requestShareApp
2.shareApp
5.callback
3.endpoint DBgadgets.rpc
Share app with gadgets.rpc
[hash].app.mbga-platform.jp
yahoo-mbga.jp
1.opensocial.requestShareApp
2.shareApp 4.callback
5.callback
3.endpoint DBgadgets.rpc
Share app with gadgets.rpc
[hash].app.mbga-platform.jp
yahoo-mbga.jp
1.opensocial.requestShareApp
2.shareApp 4.callback
5.callback
3.endpoint DBgadgets.rpc
Constraints for test
Constraints for test
• StaticなJSライブラリのtestでは済まない
Constraints for test
• StaticなJSライブラリのtestでは済まない
• 各windowでloadされるべき.jsの存在
Constraints for test
• StaticなJSライブラリのtestでは済まない
• 各windowでloadされるべき.jsの存在
• gadgets.rpcが初期化プロセスにも関係
Constraints for test
• StaticなJSライブラリのtestでは済まない
• 各windowでloadされるべき.jsの存在
• gadgets.rpcが初期化プロセスにも関係
• gadgets.rpcを利用するAPIのテストも…
Constraints for test
• StaticなJSライブラリのtestでは済まない
• 各windowでloadされるべき.jsの存在
• gadgets.rpcが初期化プロセスにも関係
• gadgets.rpcを利用するAPIのテストも…
• Security Tokenとか(ry
Testing tools for JS
• JSUnit
• QUnit
• JSTAPd
• JSTestDriver
• Jasmine
etc…
QUnit
• jQueryからスピンアウト
• Author: John Resig
• Maintainer: JornZaefferer
• QUnit.logやQUnit.doneなどをフック可能
Hijacking QUnit
Hijacking QUnit
• アプリとしてtestを書くのが一番ラク
Hijacking QUnit
• アプリとしてtestを書くのが一番ラク
• しかし手動テストは。。。
Hijacking QUnit
• アプリとしてtestを書くのが一番ラク
• しかし手動テストは。。。
• 「それMozReplでできるよ」
Hijacking QUnit
• アプリとしてtestを書くのが一番ラク
• しかし手動テストは。。。
• 「それMozReplでできるよ」
• MozRepl.pmでテストアプリを起動→QUnitオブジェクトをジャック→テストを実行→テスト結果をPerlに戻してTAP形式で集計
Test::QUnit
Test::QUnit
• proveによるremoteテスト
Test::QUnit
• proveによるremoteテスト
• QUnitJackerなので本番環境もテスト可
Test::QUnit
• proveによるremoteテスト
• QUnitJackerなので本番環境もテスト可
• 指定したwindowのonloadをフックし、処理を走らせる(例えばpopupのCloseボタンをクリックとか)ことも可能
Test::QUnit
• proveによるremoteテスト
• QUnitJackerなので本番環境もテスト可
• 指定したwindowのonloadをフックし、処理を走らせる(例えばpopupのCloseボタンをクリックとか)ことも可能
• http://github.com/zentooo/p5-test-qunit
ごっつええ感じ
• テストの全自動化 ( via prove )
• ポップアップのテストも可能に(副産物)
• JSON-RPCの仕様変更もキャッチ
テストまとめ
• gadgets.rpcはけっこうややこしい
• Firefoxでしかtestできない男の人って…
• 汎用性に限界
• JSTAPdとかJSTestDriverとかとか
• いっそNodeで書いちゃうのも
3. opensocialの今後
• 主にextras↓
• opensocial-payment
• Activity Streams
• Open Ajax Hub
• Wave API
opensocial-payment
opensocial-payment
• 既に実用段階
opensocial-payment
• 既に実用段階
• Y!mbgaでは少しいじったコードを利用
opensocial-payment
• 既に実用段階
• Y!mbgaでは少しいじったコードを利用
• ユーザの課金はcontainer domain
opensocial-payment
• 既に実用段階
• Y!mbgaでは少しいじったコードを利用
• ユーザの課金はcontainer domain
• 例によってgadgets.rpcで通信
Activity Streams
Activity Streams
• JSにはあまり関係ないけど
Activity Streams
• JSにはあまり関係ないけど
• SocialなActivityの標準化
Activity Streams
• JSにはあまり関係ないけど
• SocialなActivityの標準化
• DBは既に対応済
Activity Streams
• JSにはあまり関係ないけど
• SocialなActivityの標準化
• DBは既に対応済
• Shindig-2.0.0にはJavaによる実装あり
Open Ajax Hub
Open Ajax Hub
• Frame間通信、その弐
Open Ajax Hub
• Frame間通信、その弐
• http://www.openajax.org/member/wiki/Ope
nAjax_Hub_2.0_Specification
Open Ajax Hub
• Frame間通信、その弐
• http://www.openajax.org/member/wiki/Ope
nAjax_Hub_2.0_Specification
• Gadget間でのsecureなpub/subを想定
Open Ajax Hub
• Frame間通信、その弐
• http://www.openajax.org/member/wiki/Ope
nAjax_Hub_2.0_Specification
• Gadget間でのsecureなpub/subを想定
• 夢のアプリ間通信!?
Open Ajax Hub
OpenSocial Container
App A
sub: []
App C
sub: [A, D]
App B
sub: [A]
App D
sub: [C]
pub
pub pubpub
Wave API
Wave API
• G◯◯gleのアレのWave Gadget API
Wave API
• G◯◯gleのアレのWave Gadget API
• ShindigコミッタにはG◯◯gleの人が多い
Wave API
• G◯◯gleのアレのWave Gadget API
• ShindigコミッタにはG◯◯gleの人が多い
• Waveは滅びん!何度でも蘇るさ!
Wave API
• G◯◯gleのアレのWave Gadget API
• ShindigコミッタにはG◯◯gleの人が多い
• Waveは滅びん!何度でも蘇るさ!
ということで、復活させてみました
(多分)世界初のwave on Shindig
• Shindigのwave featureで実現する簡単なお絵かきチャット feat. node.js and
Socket.IO –
http://d.hatena.ne.jp/zentoo/20101114/128
9751462
• 動画 ->
http://www.youtube.com/watch?v=1iqgKrD
UEAo
ご清聴ありがとうございました
A. API側から見たアプリ作成のコツ
A. API側から見たアプリ作成のコツ
• gadgets.util.registerOnLoadHandler()
• gadgets.io.makeRequest()
• gadgets.flash.embedFlash()
※ただしAPI提供側視点のコツに限る
g.u.registerOnLoadHandler()
• (ほぼ) onload発火時の実行を保証• <script>/*ここで呼ばれる*/</script></body>
• これ使わないと上記タイミング無保証
• ShindigのJS APIの初期化プロセスは複雑
• なので使ったほうが何かと安心
コード例(1)
function init() {
// アプリの初期化プロセスは全てこの中で行う
}
gadgets.util.registerOnLoadHandler(init);
gadgets.io.makeRequest()
• ほぼ100%使われているだろうAPI
• 意外と多機能
• HEAD, GET, PUT, POST, DELETE
• データフォーマットの指定(JSON, DOM,
RSS)によるresponseの自動deserialize
コード例(2)
function jsonCallback(response) {
if ( response.rc === 200 )
gadgets.log(response.data.foo); // bar
}
gadgets.io.makeRequest(“http://example.com/json”,
jsonCallback,
{“format”: “JSON”}
); {“foo”:”bar”}のようなJSONを返す
gadgets.flash.embedFlash()
• Flashを利用したアプリでは必需品
• 引数での指定が細かい
• embedFlash(<url>,<Elem>,<ver>,<obj>)
• IE/それ以外で埋め込み方が違う
• 第四引数でのwmodeとid重要
コード例(3)
gadgets.flash.embedFlash(“http://example.com/myapp.swf”,
document.getElementById(“swfContainer”),
10,
{
“id”: “swfElem”, “wmode”: “opaque”
}
);後にgetElementById(“swfElem”)でアクセス可能に
アプリのコツまとめ
• 半分コツ、半分「お願い」
• よいアプリは三者にとって幸せ