2015年4月6日月曜日

GAE/J上のGoogle Cloud EndpointsをバックエンドにしてSupersonicのdataアクセスを試してみた


Supersonic data セットアップ



1. データプロバイダの追加


プロジェクトディレクトリ下でconnectを発動し、プロジェクトのコネクトスクリーンを開く。
$ steroids connect

コネクトスクリーンの"Data"タブで「Custom Provider」を選択。




NAMEに任意のデータプロバイダ名を入力。
BASE URLは「https://YOUR_APP.appspot.com/_ah/api/」まで設定。v1などバージョンナンバーまでのパスにしない(後述のリソース追加設定のため)。



また、Google Cloud Endpointsはhttpsアクセスしか認めていないので、http://ではなく、https://にしておく。


2. リソースの追加


「ADD NEW RESOURCE」ボタンをクリックして、リソースを設定する。

NAMEに任意のリソース名を入力。
URL PATHは「yourApi/v1/」を入力。
例えば、API名が「playlistApi」、バージョンが「v1」の場合、URL PATHは「playlistApi/v1/」になる。



前述のプロバイダのBASE URLで「〜/v1/」まで含めてしまうと、必須入力であるリソースのURL PATHに何も設定できなくなるので、プロバイダのBASE URLを「api/」までと設定した。

これにより、リソースへのパスは、BASE URL + RESORCE URL PATH = 「https://YOUR_APP.appspot.com/_ah/api/playlistApi/v1/」となる。


3. アクションのカスタマイズ


「CUSTOMIZE ACTIONS」ボタンをクリックして、get/postなどのリクエストの、URL PATHやROOT KEYSを設定する。

例えば、コレクションを取得するgetのAPIパスが「playlist」の場合、URL PATHは「playlist」になる。



これにより、完成したエンドポイントへのパスは、BASE URL + RESOURCE URL PATH + ACTION URL PATH = 「https://YOUR_APP.appspot.com/_ah/api/playlistApi/v1/playlist」となる。


更に、Google Cloud Endpointsのコレクションのルートは「items」なので、ROOT KEYSに「items」を指定する。


「RELOAD MODEL FROM API」ボタンをクリックすると、エンドポイントとの通信が行われる。無事にコレクションが取得できると、最新のエンティティモデルの内容が表示される。





デバイスから data access 確認



トップ画面には、「https://YOUR_APP.appspot.com/_ah/api/playlistApi/v1/playlist」へアクセスした結果が表示されている。




API Explorerで、dataStoreにエンティティを1つ追加してみる。




デバイスで起動しているアプリ側のリストも、数秒後に、自動的に更新される。





10秒間隔で同期が発動する



ログを見ると、ほぼ10秒間隔でエンドポイントが叩かれている。




データバインディングはいいのだが、10秒おきにプルリクエストが発動するのでは、GAEのdataStoreのRead Quotaの消費が激しくなってしまう。

2015年4月現在の無料枠では、Read Operationsのリミットは50,000回/日なので、

( 60秒 / 10秒間隔 ) x 60分 = 360回/時

1時間アプリを起動しているだけで、360回のRead Operationsが発生する。

50,000回 / 360回 = 138.889

例えば、同時に138人が1時間アプリを起動しているだけで、50,000回のRead Operationsのクオータはすぐに消費されてしまう。


データバインディングは、supersonic.data APIのwhenChanged()で実現されている。
Playlist.all().whenChanged( function (playlists) {
        $scope.$apply( function () {
          $scope.playlists = playlists;
          $scope.showSpinner = false;
        });
    });

クオータの消費を避けたいなら、whenChanged()を使わずに、適切なタイミングで自作でデータの同期を行う必要があるなと。


参考:Supersonic Guides - Supersonic Framework