AppEngine Java と JSONIC と OpenSocial OAuth Filter を使うと、OpenSocial アプリの外部サーバをお手軽に立てることができますよ ... というおはなしです。ただ、大規模な運用実績はありませんので、その点は割り引いて読んでくださいね。
はじめに、JSONIC というライブラリを使って、AppEngine Java 上に、独自の REST API を構築します。そして、OpenSocial アプリから gadgets.io.makeRequest メソッドを使って、その REST API を呼び出すことにします。JSONIC とは、↓というものです。
JSONIC - simple json encoder/decoder for java
JSONICは、Java用のシンプルかつ高機能なJSONエンコーダー/デコーダーライブラリです。Java用のJSONライブラリはすでに多数存在しますが、JSONICはRFC 4627に従った正式なJSON形式でのデコード/エンコードを行いながらも、プログラミング言語に依存する情報をJSON内に含めることなくPOJO(Plain Old Java Object)と自然な変換を行える点に特徴があります。次のとおり、REST API のインタフェースを想定します。
* GET http://example.com/api/entries.json?count={count} // エントリ取得
* GET http://example.com/api/entries/{id}.json // エントリ取得
* POST http://example.com/api/entries.json // エントリ投稿
* PUT http://example.com/api/entries/{id}.json // エントリ更新
* DELETE http://example.com/api/entries/{id}.json // エントリ削除
jsonic-1.2.0.jar をビルドパスに追加して、次のとおり、web.xml に JSONIC の REST サーブレットを追記します。このとき、config パラメータの mappings を使って、REST API のインタフェースとクラスの対応を指定します。ここでは、EntryService クラスとします。
<servlet>
<servlet-name>JSONIC</servlet-name>
<servlet-class>net.arnx.jsonic.web.RESTServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>
{
"mappings": {
"/api/entries.json": "com.example.EntryService",
"/api/entries/{id}.json": "com.example.EntryService"
}
}
</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>JSONIC</servlet-name>
<url-pattern>*.json</url-pattern>
</servlet-mapping>
次のとおり、EntryService クラスを記述します。find が GET リクエスト、create が POST、update が PUT、delete が DELETE を表します。リクエストのパラメータは、各メソッドの params に格納されます。また、各メソッドの戻り値が JSON 形式のレスポンスに相当します。public class EntryService {
public Map<String,Object> find(Map<String,String> params) {
Map<String, Object> json = new HashMap<String, Object>();
json.put("viewer", params.get("opensocial_viewer_id"));
json.put("id", params.get("id"));
json.put("count", params.get("count"));
return json;
}
public Map<String,Object> create(Map<String,String> params) {
...
}
public Map<String,Object> update(Map<String,String> params) {
...
}
public Map<String,Object> delete(Map<String,String> params) {
...
}
}
次のとおり、OpenSocial アプリから gadgets.io.makeRequest メソッドを使って、その REST API を呼び出します。var url = 'http://example.com/api/entries/1.json?count=10';
var params = {};
params[gadgets.io.RequestParameters.METHOD] =
gadgets.io.MethodType.GET;
params[gadgets.io.RequestParameters.AUTHORIZATION] =
gadgets.io.AuthorizationType.SIGNED;
params[gadgets.io.RequestParameters.CONTENT_TYPE] =
gadgets.io.ContentType.JSON;
gadgets.io.makeRequest(url, function(res) {
console.log(res.data.viewer);
console.log(res.data.id);
console.log(res.data.count);
}, params);
PUT リクエストと DELETE リクエストが使えないコンテナのときは、リクエストのパラメータに _method=put や _method=delete を指定すると、疑似的に PUT や DELETE リクエストを表現できます。 次に、OpenSocial OAuth Filter というライブラリを使って、構築した REST API に対するリクエストの署名を検証するようにします。 OpenSocial OAuth Filter とは、↓というものです。
OpenSocial OAuth Filter
OpenSocial OAuth Filter is a JavaEE filter to validate OpenSocial requests. This filter blocks illegal requests to prevent spoofing and tampering.opensocial-oauth-filter-0.7.jar をビルドパスに追加して、次のとおり、web.xml に OpenSocial OAuth Filter のフィルタサーブレットを追記します。このとき、config-class パラメータを使って、公開鍵と検証条件を実装したクラスを指定します。ここでは、MixiRegistryConfigurator クラスとします。
<filter>
<filter-name>opensocial-oauth-filter</filter-name>
<filter-class>
org.hidetake.opensocial.filter.RequestValidationFilter
</filter-class>
<init-param>
<param-name>config-class</param-name>
<param-value>com.example.MixiRegistryConfigurator</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>opensocial-oauth-filter</filter-name>
<url-pattern>*.json</url-pattern>
</filter-mapping>
次のとおり、MixiRegistryConfigurator クラスを記述します。公開鍵とコンシューマキー、アプリID、ガジェットURL を指定します。この条件を満たさないリクエストには、403 Forbidden をレスポンスします。public class MixiRegistryConfigurator
implements RegistryConfigurator {
private static final String cert =
"-----BEGIN CERTIFICATE-----\n"
+ "MIICdzCCAeCgAwIBAgIJANCWpLIspxwbMA0GCSqGSIb3DQEBBQUAMDIxCzAJBgNV\n"
...
+ "IpqnsHwF1pm0bTY=\n"
+ "-----END CERTIFICATE-----";
@Override
public void configure(AppRegistry registry)
throws ConfigurationException {
registry.register(new OpenSocialApp(
"16271", "http://example.com/gadgets.xml",
OpenSocialApp.createOAuthAccessorRSASHA1("mixi.jp", cert)));
}
@Override
public void configure(ExtensionRegistry registry)
throws ConfigurationException {
registry.register(new ValidationLogger());
}
}
最後に、EntryService クラスで、AppEngine のデータストレージを使って、エントリを検索したり、保存したり、削除するように実装すればよいでしょう。-- 2010-04-28 追記
CREYLE 用 RegistryConfigurator クラスの雛形を置いておきますので、参考にしてください。
CrelyeRegistryConfigurator.java