さよなら Parse
はじめに
世界中の利用者の指先と視線を凝固させた突然の発表からまもなく 1年、Parse.com の全サービスが いよいよ 2017年1月28日(土)に終了します。拡張性が高く高機能でありながら使い勝手の良い優れたサービスだったので終息が惜しまれます。
手元では 2年ほど前に IoT の実験として試作した以下のしくみ「Anpi」で Parse.com を採り入れました。
- mbed と Parse で作る高齢者世帯安否確認システム - 当ブログ
一般に BaaS の主な目的はアプリケーションの対向サーバ側機能を代替・補完することにあり、サーバの管理運用やサーバ側コード開発に踏み込むコストを抑制しアプリ本体の開発に注力可能となることが利用者にとってのメリットですが、Parse にはサーバ上でユーザコードを実行することのできる「Cloud Code」というしくみが用意されています。(中略)今回作った装置は Parse サーバ上に設置した自作コードをそのまま呼び出して必要な処理を行っています。このように目的に応じて柔軟に利用できることが Parse の魅力のひとつと言ってよいでしょう。
※文中の記述はいずれも 2016年11月から12月の時点の状況に基づくものであり現在の事情とは異なる可能性があります。あらかじめご了承下さい。
手元の要件と移行先選定基準
「Anpi」において Parse.com サイドで行っていた処理は以下の内容です。
- 屋内に設置ずみの装置が人感センサ反応時に最短 30 分間隔で送信してくる情報をデータストアへ保存
- 定刻に直近 60 レコード分をレポートとして所定のアドレスへメール送信
- 装置につないだボタンが長押しされたら所定のアドレスへメールで通知(緊急メール)
- メール配信には Parse.com が 公式 API で連携している Mailgun サービスを利用
|
要件に特に煩雑なものはなくこれらを吸収可能なサービスはいくつも存在するでしょう。その上で、今回は次の三点を移行先選定の基準とすることにしました。
- 運用に手がかからないこと
- 柔軟性があること
- 費用がかからないこと
なお、要件のうち「緊急メール」の発信については以前「今、ワンボタンの IoT デバイスが面白い」でも利用した SendGrid サービスの API を装置側のコードから直接叩くことにしました。メールの内容は決め打ちなので各サービスに仲介させるよりもそのほうが合理的と考えたためです。
- V3 Mail Send API Overview - SendGrid Documentation - sendgrid.com
移行先候補 1: IFTTT + Google Drive + Google Apps Script
もっともシンプルに要件を満たす道具立てとしてまず IFTTT と Google サービスの組み合わせを考えました。IFTTT 経由で Google Drive 上の Spreadsheet をデータストアとして利用し Google Apps Script でサーバサイドの処理を実行する内容です。
1. Google Spreadsheet へデータを保存する IFTTT アプレットを作成
IFTTT アプレット(旧呼称「レシピ」)でトリガーを Maker チャネルに指定し HTTPS で POST されたデータを Google Spreadsheet「anpi」に記録するアクションを設定しておく。
- Google Sheets API を直接叩く選択もあるがハブサービスを挟むほうが簡潔であり、また、Google API は全体的に仕様変更が比較的多く発生することも微妙にマイナス
- リクエストの投げ方
curl -X POST -H "Content-Type: application/json" \ -d '{"value1":"MAKOTO","value2":"23.1","value3":"192.168.0.112"}' \ https://maker.ifttt.com/trigger/anpi/with/key/***key***
2. Google Apps Script でレポート送信処理を記述
Spreadsheet「anpi_queue」を作成し、Google Apps Script (GAS) で Spreadsheet「anpi」上の直近 60 レコード分を Gmail 送信する処理をスクリプトエディタで記述する。 当該関数の起動トリガーを「スプレッドシートの値変更」に設定しておく。
3. レポート送信処理をキックする IFTTT アプレットを作成
IFTTT アプレットでトリガーを Date & Time チャネルに設定し、所定の時刻に Spreadsheet「anpi_queue」 に対して適当に書き込みを行うアクションを設定する。
- GAS の定刻実行は GAS プロジェクト側で「時間主導型」トリガーを設定することによっても可能だが、当該トリガーでは発動時分を細かく設定することができない(時の指定には自動的に 1 時間の発動猶予が加味される)
- IFTTT は最大 15分の遅延が発生する可能性があるとされているが手元の確認では定刻処理はほぼ正確。仮に15分の遅延が発生しても GAS トリガーの緩さよりもベター
以上で完成。とてもシンプル。
仮移行を通じての * 個人的な * 印象
GOOD !
- シンプルかつ柔軟
- Google, IFTTT ともに今後課金の発生する可能性がきわめて低い
- Google, IFTTT ともに今後サービスが終息する可能性がきわめて低い
- コードを含めすべてをブラウザ上で操作できるため運用上の自由度が高い
- 今回の要件には十分だが規模の大きいデータを扱うには不向き
- あくまでも SaaS とハブサービスの組み合わせであるため当然ながらプッシュ通知など一般的な IoT プラットフォームの提供する機能は代替できない
移行先候補 2: Kii Cloud
Kii Cloud は Kii 株式会社様の提供する日本発の BaaS です。
Kii Cloud とは
概要
Kii Cloud は Kii 株式会社様(以下「Kii 社」と表記)の提供する日本発の BaaS です。2013年に正式サービスがスタート、Kii 社は東京本社の他にカリフォルニア・上海・香港・スペインに拠点を置き国際展開を進めています。
- IoT クラウドプラットフォーム Kii - jp.kii.com (公式)
- 機能
- Kii ドキュメント
- IoT クラウドプラットフォーム
https://jp.kii.com/
また、Kii 社にはベンチャーキャピタルとしての側面もあります。 Kii Capital
特徴
- 複数のリージョンが存在
- Kii Cloud サーバは日本・米国・中国・シンガポール・ヨーロッパに設置されておりアプリ作成時に任意選択可
- サーバ機能を拡張可能
- Parse.com と同じくユーザ記述の JavaScipt コードをサーバサイドで実行可能 (「Server Code」)
- サーバー機能拡張 - jp.kii.com
- サーバー機能拡張リファレンスガイド - docs.kii.com
- サーバ拡張機能の管理やサーバ側ログの閲覧には以下のツールを使用する
- コマンドラインツールガイド - docs.kii.com
- クライアント開発用リソース
- REST API セット完備
- SDK の構成とサポート環境 - docs.kii.com
- モバイル・デスクトップ環境向けに Kii Cloud SDK (Android, iOS, JavaScript, Unity) を提供
- IoT 向けに Thing-IF SDK を提供
- Thing-IF SDK の構成
リファレンス実装を提供している環境は以下の通りです。 Linux Intel Edison Ti CC3200 これら以外の環境で使用する場合、必要な API を自分で用意します。 :
Thing Interaction Framework を使ったソリューションを構築する際は、 上記の SDK の代わりに REST API を直接利用して、モバイルアプリ、 または、Thing を作成することができます。 特に、Thing Interaction Framework の機能範囲では、MQTT プロトコルだけを使って Thing を構築することもできます。MQTT プロトコルだけで実装する方法はMQTT 経由での API の利用 および MQTT プロトコルだけでの実装 をご覧ください。
- Thing Interaction Framework
- Thing-IF SDK の構成
- 料金まわり
- ひと月あたりの無料枠は以下の通り
- API コール 1,000,000 回(※1) / プッシュ通知 1,000,000 回 / ストレージ利用 1 GB(※2)
(※1)Server Code 分もカウントされる
(※2)カウントされるのは「Object Body」の容量分のみであり
通常の キーバリューペアデータのサイズはカウントされない- Object
1 つの Object には、次の 2 種類のデータを保存できます。 JSON ドキュメント 任意の JSON ドキュメントを Object に格納できます。 Object Body ファイルなどの大きなバイナリデータを Object に添付できます。 これを Object Body と呼びます。Object Body が不要な場合は 省略できます。
- Object
- API コール 1,000,000 回(※1) / プッシュ通知 1,000,000 回 / ストレージ利用 1 GB(※2)
- 利用料金の計算方法 - docs.kii.com
- Kii株式会社、モバイルアプリ開発者向けプラットフォーム「Kiiクラウド」の正式版を発表 - jp.kii.com
Kiiクラウド価格表 <Freeプラン $0/月> 1,000,000 コール/月(超過1,000コール毎に7セント) ストレージ1GB(超過1GB毎に20セント) 1,000,000 Push Notification利用(超過1,000コール毎に7セント) <Standardプラン $199/月> 15,000,000 コール/月 (超過1,000コール毎に5セント) ストレージ20GB (超過1GB毎に15セント) 5,000,000 Push Notification利用 (超過1,000コール毎に5セント) :
- ひと月あたりの無料枠は以下の通り
Kii Cloud で Anpi アプリを実装
Kii Cloud は多機能であり Parse.com と同様にユーザコードを使用してサーバ機能拡張が可能である点にも魅力がある。
正式リリースから 3年を経て Kii Cloud は BaaS として国内で広く認知されている。現時点では必ずしも際立った突出感はないが、無料枠も広くこの機会に今後手元でスムースに利用できるようにしておきたい。以下は今回の一連の手順の記録。
1. サインアップ 〜 アプリ作成 〜 環境設定
サインアップしてログインすると開発者ポータルへ誘導される。ここで「Create App」をクリックして下のアプリ作成画面へ。
サブミットするとダウンロードページへ誘導される。必要に応じて SDK とコマンドラインツール(Node.jsベース)を取得しセットアップ。
Anpi 屋内装置のデータ通信処理はクラウドへの一方通行であり REST API を利用することにする。
コマンドラインツールは Server Code の設置とサーバログの閲覧に必須。
なお、当該アプリのキーは画面右上の設定メニューから参照できる。
- アクセスキー - docs.kii.com
アプリケーションの作成が完了すると、そのアプリケーションに対して Kii Cloud から 以下 4 つのアクセスキーが発行されます。 AppID、AppKey これら 2 つの値は、クライアント SDK や REST から、対象となっている アプリケーションを指定するために使用します。値はモバイルアプリや、 クライアントにダウンロードされるJavaScript などに埋め込んで使います。 ClientID、ClientSecret これら 2 つの値は、管理者権限が必要な API を実行するときに使用します。 :
2. アプリのユーザを作成
開発者ポータルの User Console 上で当該アプリのユーザを作成する。
- ユーザーとグループ - docs.kii.com
Anpi アプリにユーザ "makoto" を作成。
必要に応じてグループを作成する。メンバーは当該グループのセキュリティコンテキストを共有する。今回グループは作成せず。
3. データ格納用の Bucket を作成 1
Anpi 屋内装置から POST されるデータを保持するための Bucket を用意する。
- Object - docs.kii.com
Kii Cloud 上のデータは Object と呼ばれます。モバイルアプリのデータは、 Object を介して Kii Cloud に保存または取得することができます。
- Bucket - docs.kii.com
Bucket はバケツを意味しており、Object の入れ物として機能します。
Bucket はアプリケーション, グループ, ユーザのいずれかのスコープのもとに作成する。
- スコープとアクセス権 - docs.kii.com
アプリケーションスコープ この Bucket はアプリケーションに所属します。アプリケーション内の すべてのユーザーから共有される、ゲームのハイスコアや設定の デフォルト値のようなデータを扱うのに向いています。 グループスコープ この Bucket はグループに所属します。掲示板のデータのように、 グループ内のユーザーの間で共有されるデータを扱うのに向いて います。 ユーザースコープ この Bucket はユーザーに所属します。個人の所有データや設定 情報など、ユーザー個人の 持ち物としてデータを扱うのに向いています。
- アクセス制御 - docs.kii.com
Kii Cloud に格納されているオブジェクトにアクセスする際には、 アクセス権チェックが行われ、許可されたユーザーだけが操作を 実行できます。 アクセス制御の対象となるのは、Bucket、Object、トピック (プッシュ機能)です。 これらは ACL(Access Control List)を持っており、それを カスタマイズすることによって、対象にアクセスできるユーザーを 設定することができます。
4. データ格納用の Bucket を作成 2
作成する Bucket 名は "detected" とする。
Anpi は小規模なアプリでありユーザ "makoto" での運用で事足りるため detected Bucket は makoto のユーザースコープ下で作成・管理することにした。
detected Bucket の Object に必要な項目は POST された日時・送信元装置の ID・室温情報・送信元装置の IP アドレスのよっつ。
管理者ポータルのデータブラウザからユーザ makoto のスコープに detected Bucket の追加を行った。
- データブラウザー - Bucket を追加する - docs.kii.com
detected Bucket が作成された。が、データブラウザの UI による Object 内の既定の項目の削除や新しい項目の追加方法が不明。ここでできるのは所定の項目を非表示にすることのみ?
結局 UI での操作方法が判明せずこの detected Bucket は一旦削除。REST API で明示的に項目を指定して再作成することにする。
5. データ格納用の Bucket を作成 3
ユーザスコープ Bucket の作成には当該ユーザのログインによって得られるアクセストークンが必要。
- ログイン - docs.kii.com
: また、REST API におけるログインを行うと、Kii Cloud は アクセストークンを返します。以後、ユーザーログインを必要と する REST API を利用する際には、このアクセストークンを HTTP ヘッダに埋め込むことになります。アクセストークンの 機能概要についてはログインとアクセストークン をご覧ください。 ログイン ログインを行い、アクセストークンを取得する例を以下に挙げます。 curl -v -X POST \ -H "Authorization: Basic {BASE64_ENCODED_APPID:APPKEY}" \ -H "Content-Type: application/json" \ "https://api-jp.kii.com/api/apps/{APP_ID}/oauth2/token" \ -d '{ "grant_type": "password", "username": "user_123456", "password": "123ABC" }' : ログインが成功すると、Kii Cloud は次のようなレスポンスを返します。 このレスポンスにおける "access_token" の値がアクセストークンです。 また "expired_in" は、アクセストークンが有効な時間(秒)となります。 < HTTP/1.1 200 OK < Server: Apache-Coyote/1.1 < Content-Type: application/json < Transfer-Encoding: chunked < Date: Mon, 14 May 2012 22:52:52 GMT < { "id" : {USER_ID}, "access_token" : {ACCESS_TOKEN}, "expires_in" : 2147483647, "token_type" : "bearer" }
- AppID と AppKey - docs.kii.com
Kii Cloud は、以下の HTTP ヘッダを元にアプリケーションを特定します。 Authorization ヘッダ X-Kii-AppID/X-Kii-AppKey ヘッダ なお X-Kii-AppID/X-Kii-AppKey ヘッダによるアプリケーション特定は 後方互換のための機能です。原則 Authorization ヘッダ方式を 利用してください。 : アクセストークンを必要としない API については、Basic 認証を使わずに 直接 AppID と AppKey を X-Kii-AppID、X-Kii-AppKey ヘッダに埋め込んで リクエスト送信することも可能です。
- アクセストークンと me リテラル - docs.kii.com
: ユーザーのアクセストークンを指定している場合は、リクエスト URL に 自分自身を表す "/me" リテラルを使用できます。
- Bucket の作成 - docs.kii.com
: Bucket の名前は、本ガイドやリファレンスマニュアルでは {BUCKET_ID} と して表現されています。{BUCKET_ID} には Bucket の名前を指定してください。 : ユーザースコープの Bucket curl -v -X POST \ -H "Authorization: Bearer {ACCESS_TOKEN}" \ -H "Content-Type: application/vnd.{APP_ID}.mydata+json" \ "https://api-jp.kii.com/api/apps/{APP_ID}/users/me/buckets/{BUCKET_ID}/objects" \ -d '{"score": 1800, "name": "game1"}' :
前掲のように Anpi アプリの APP_ID は "ac8e5f9a"、APP_KEY は "30caec2f074c6fc55287e195e9XXXXXX" であり
作成する detected Bucket の BUCKET_ID (=「Bucket の名前」)は "detected"。
まずはログインから。
curl -v -X POST \ -H "X-Kii-AppID: ac8e5f9a" \ -H "X-Kii-AppKey: 30caec2f074c6fc55287e195e9XXXXXX" \ -H "Content-Type: application/json" \ "https://api-jp.kii.com/api/apps/ac8e5f9a/oauth2/token" \ -d '{ "grant_type": "password", "username": "makoto", "password": "XXXXXXXXXX" }'
レスポンス。JSON データからアクセストークンを得る。
< HTTP/1.1 200 OK < Accept-Ranges: bytes < Access-Control-Allow-Origin: * < Access-Control-Expose-Headers: Content-Type, Authorization, Content-Length, X-Requested-With, ETag, X-Step-Count, X-HTTP-Status-Code < Age: 0 < cache-control: max-age=0, no-cache, no-store < Content-Type: application/json;charset=UTF-8 < Date: Thu, 10 Nov 2016 09:14:06 GMT * Server openresty is not blacklisted < Server: openresty < X-HTTP-Status-Code: 200 < Content-Length: 173 < Connection: keep-alive < { "id" : "9980daa00022-3b7a-6e11-8899-01186667", "access_token" : "UQhn37CHk-Q7vyRbgOel1rlPQ61Jc-YMGChgYXXXXXX", "expires_in" : 2147483646, "token_type" : "bearer" }
アクセストークンを指定して detected Bucket を作成する。Object の項目を明示的に指定。
curl -v -X POST \ -H "Authorization: Bearer UQhn37CHk-Q7vyRbgOel1rlPQ61Jc-YMGChgYXXXXXX" \ -H "Content-Type: application/vnd.ac8e5f9a.detected+json" \ "https://api-jp.kii.com/api/apps/ac8e5f9a/users/me/buckets/detected/objects" \ -d '{"posted": "", "deviceAddress" : "", "temperature" : "", "deviceId": ""}'
正常終了。
< HTTP/1.1 201 Created < Accept-Ranges: bytes < Access-Control-Allow-Origin: * < Access-Control-Expose-Headers: Content-Type, Authorization, Content-Length, X-Requested-With, ETag, X-Step-Count, X-HTTP-Status-Code < Age: 0 < cache-control: max-age=0, no-cache, no-store < Content-Type: application/vnd.kii.ObjectCreationResponse+json;charset=UTF-8 < Date: Thu, 10 Nov 2016 09:15:22 GMT < ETag: "1" < Location: https://api-jp.kii.com/api/apps/ac8e5f9a/users/9980daa00022-3b7a-6e11-8899-01186667/buckets/rw:detected2/objects/356fbd10-a726-11e6-a7b3-22000aad0899 * Server openresty is not blacklisted < Server: openresty < X-HTTP-Status-Code: 201 < Content-Length: 146 < Connection: keep-alive < { "objectID" : "356fbd10-a726-11e6-a7b3-22000aad0899", "createdAt" : 1478769322849, "dataType" : "application/vnd.ac8e5f9a.detected+json" }
作成した Bucket を管理者ポータルのデータブラウザから確認。期待どおりの内容。
6. detected Bucket の ACL を設定
detected Bucket の ACL を設定。オーナーであるユーザ makoto にのみ操作を許可。
7. データを POST する
detected Bucket に Object を登録する。
- Object の作成
: ユーザースコープに存在する "mydata" Bucket 内に Object を作成する例を以下に示します。 curl -v -X POST \ -H "Authorization: Bearer {ACCESS_TOKEN}" \ -H "Content-Type: application/vnd.{APP_ID}.mydata+json" \ "https://api-jp.kii.com/api/apps/{APP_ID}/users/me/buckets/{BUCKET_ID}/objects" \ -d '{"score": 1800, "name": "game1"}' Object のメディアタイプには "application/json" か "application/vnd.{APP_ID}.{DATA_TYPE}" が指定できます。後者の場合、{DATA_TYPE} には任意の値が利用可能です。 格納できるデータの最大サイズは JSON 形式で表現した状態で Unicode 換算で 65534 文字まで です(サイズには Kii Cloud が内部で使用するフィールドも含まれます)。 :
書式は Bucket 作成時と同じ。
curl -v -X POST \ -H "Authorization: Bearer UQhn37CHk-Q7vyRbgOel1rlPQ61Jc-YMGChgYXXXXXX" \ -H "Content-Type: application/vnd.ac8e5f9a.detected+json" \ "https://api-jp.kii.com/api/apps/ac8e5f9a/users/me/buckets/detected/objects" \ -d '{"posted": "", "deviceAddress" : "192.168.0.112", "temperature" : "16.5", "deviceId": "MAKOTO"}'
正常終了。
< HTTP/1.1 201 Created < Accept-Ranges: bytes < Access-Control-Allow-Origin: * < Access-Control-Expose-Headers: Content-Type, Authorization, Content-Length, X-Requested-With, ETag, X-Step-Count, X-HTTP-Status-Code < Age: 0 < cache-control: max-age=0, no-cache, no-store < Content-Type: application/vnd.kii.ObjectCreationResponse+json;charset=UTF-8 < Date: Thu, 10 Nov 2016 10:45:06 GMT < ETag: "1" < Location: https://api-jp.kii.com/api/apps/ac8e5f9a/users/9980daa00022-3b7a-6e11-8899-01186667/buckets/rw:detected2/objects/be9380c0-a732-11e6-8b07-22000aaf0c30 * Server openresty is not blacklisted < Server: openresty < X-HTTP-Status-Code: 201 < Content-Length: 146 < Connection: keep-alive < { "objectID" : "be9380c0-a732-11e6-8b07-22000aaf0c30", "createdAt" : 1478774706892, "dataType" : "application/vnd.ac8e5f9a.detected+json"
データブラウザで確認。
"_created" は Kii 既定の項目であり当該 Object 作成日時が UTC で記録される。自前で用意した "posted" は使わずアプリではこれをそのまま使うことにする。
8. Server Code を書く・設置する・実行する・ログを参照する
サーバ側で実行する処理を JavaScript で記述する。
記述したプログラムはコマンドラインツールでサーバへ転送し REST API で所定の関数をキックしてテスト。
サーバログはコマンドラインツールで参照可能。
- サーバー機能拡張リファレンスガイド - docs.kii.com
サーバー機能拡張の基本的な利用方法は次の通りです: 1. Server Code を書く: Kii JavaScript SDK や一般公開されているモジュールを使い、 カスタムロジックを JavaScript で書きます。 詳しくは Server Code を書く を参照してください。 2. Server Code を管理する: Kii Cloud が提供するコマンドラインツールを使い、 Server Code の Kii Cloud 上への設置、Server Code のバージョン管理、Server Hook の 設置などを行います。 詳しくは Server Code を管理する を参照してください。 3. Server Code を実行する: Kii Android/iOS/Unity Cloud SDK や REST API より Server Code を手動実行、もしくは Server Hook を用いて自動実行します。手動で実行する場合は、 クライアントより Server Code にカスタムパラメータを渡すこともできます。 詳しくは Server Code を実行する を参照してください。
- コマンドラインツールガイド - docs.kii.com/
アプリ開発のお手伝いをするために Kii Cloud はコマンドラインツールを提供しています。 コマンドラインツールが提供する機能は以下の 2 つです。 1. サーバー機能拡張の管理:サーバー機能拡張 を利用する際に必要となる Server Code が 管理できます。コマンドラインツールを利用することで、Server Code の設置やバージョン管理が 行えます。 詳しくは Server Code を管理する を参照してください。 2. 開発者ログの閲覧(ベータ版):KiiCloud 上のサーバーログが確認できます。ログ確認の 際には、ログレベルやログ出力日時などのフィルターによる絞り込みができます。 詳しくは 開発者ログの閲覧 を参照してください。 コマンドラインツールのインストール :
今回 Kii Cloud でサーバ側に実行させる処理は以下の内容。
- ユーザ "makoto" スコープ配下の "detected" Bucket より直近の Object 最大 60 件を抽出
- 抽出した Object のデータを所定の書式で所定のアドレスあてにメールで送信
myServerCode.js
- ログイン - docs.kii.com
- Object の検索 - docs.kii.com
- Kiiを使ってスマホアプリからメールを送信する方法 - sendgrid.kke.co.jp
コマンドラインツールを使って myServerCode.js をサーバへ設置する。
- Server Code の設置 - docs.kii.com
~/Kii/kii-cli-v1.4.2$ node bin/kii-servercode.js deploy-file \ --file ../myServerCode.js \ --site jp \ --app-id ac8e5f9a \ --app-key 30caec2f074c6fc55287e195e9XXXXXX \ --client-id 8d2bebca173433eb9ff33f48deXXXXXX \ --client-secret f833af34c518f4fbc43cb9XXXXXX
10 Nov 20:26:12 - Deploying file... 10 Nov 20:26:12 - File deployed as version 635jhzpj0awsztgd29aev9uv6 10 Nov 20:26:12 - Setting current version to 635jhzpj0awsztgd29aev9uv6... 10 Nov 20:26:13 - Current version set to 635jhzpj0awsztgd29aev9uv6
curl で Server Code の main() 関数を叩く。
- REST API で Server Code を実行する - docs.kii.com
$ curl -v -X POST \ -H "X-Kii-AppID: ac8e5f9a" \ -H "X-Kii-AppKey: 30caec2f074c6fc55287e195e9XXXXXX" \ -H "Content-Type: application/json" \ "https://api-jp.kii.com/api/apps/ac8e5f9a/server-code/versions/current/main" -d '{}'
< HTTP/1.1 200 OK < Accept-Ranges: bytes < Access-Control-Allow-Origin: * < Access-Control-Expose-Headers: Content-Type, Authorization, Content-Length, X-Requested-With, ETag, X-Step-Count, X-HTTP-Status-Code < Age: 0 < cache-control: max-age=0, no-cache, no-store < Content-Type: application/json;charset=UTF-8 < Date: Thu, 10 Nov 2016 11:27:02 GMT * Server openresty is not blacklisted < Server: openresty < X-HTTP-Status-Code: 200 < X-Step-count: 10 < Content-Length: 24 < Connection: keep-alive < {"returnedValue":"done"}
コマンドラインツールを使ってサーバログを閲覧する。(注:実行結果のログへの反映には 1分程度のラグがある)
- 開発者ログの閲覧 - docs.kii.com
~/Kii/kii-cli-v1.4.2$ node bin/kii-logs.js -n 40 \ --site jp \ --app-id ac8e5f9a \ --app-key 30caec2f074c6fc55287e195e9XXXXXX \ --client-id 8d2bebca173433eb9ff33f48deXXXXXX \ --client-secret f833af34c518f4fb3e2f95XXXXXX
9. Server Hook 設定により Server Code を定刻に実行する
所定の Server Code 関数の定刻実行には Server Hook 設定を利用する(cron_expression は UTC で指定)。
- Server Hook 設定ファイル - スケジュール起動 - docs.kii.com
{ "kiicloud://scheduler": { "<job_name>": { "cron": "<cron_expression>", "endpoint": "<endpoint_name>", "parameters": { "arg1": "xxxx" }, "what": "EXECUTE_SERVER_CODE" } /* more hooks */ } /* more paths with more hooks */ }
以下の要領で毎日 11:30, 17:30, 23:30, 05:30 に Server Code の main() 関数が実行される。
myServerHook.cfg
{ "kiicloud://scheduler": { "SendReport": { "cron": "30 02,08,14,20 * * *", "endpoint": "main", "parameters": { "arg1": "" }, "what": "EXECUTE_SERVER_CODE" } } }
コマンドラインツールを使って Server Hook 設定ファイルをサーバへ設置すればそのまま反映される。
~/Kii/kii-cli-v1.4.2$ node bin/kii-servercode.js deploy-file \ --file ../myServerCode.js \ --site jp \ --app-id ac8e5f9a \ --app-key 30caec2f074c6fc55287e195e9XXXXXX \ --client-id 8d2bebca173433eb9ff33f48deXXXXXX \ --client-secret f833af34c518f4fbc43cb9XXXXXX \ --hook-config ../myServerHook.cfg
- スケジュール実行の結果取得 - docs.kii.com
仮移行を通じての * 個人的な * 印象
GOOD !
- 多機能かつ無料枠が広い
- Parse.com と同様に BaaS でありながらサーバ機能拡張が可能
- サーバのリージョンを自由に選択可能であり特に中国リージョンの存在は大きい
- キーバリュー形式のデータは使用容量にカウントされないため他のサービスとの併用にも好適か
- アクセス制御機能が充実
- 日本語のリソースが充実している
! GOOD ?
- ドキュメントの情報量は豊かだが通読性がもうひとつ?リンクの張り方にも改善の余地がありそうな印象(このあたりが改善されればより利用しやすくなるかも)
- 開発者ポータルは UI・機能ともに今後の進化が期待される
- 開発用のコマンドラインツールが Node.js ベースなのは利点と欠点が半々くらい? バッチジョブのスケジュール変更といった操作はブラウザ上でできると嬉しい・・
移行先候補 3: back4app(+ AWS Lambda)
back4app は BACK4APP SERVICOS DIGITAIS LTDA(本社 米カリフォルニア)の提供する BaaS です。
back4app とは
概要
back4app は BACK4APP SERVICOS DIGITAIS LTDA(本社 米カリフォルニア)の提供する BaaS です。同社の設立は 2015年8月です。
- back4app - Parse Alternative - Create Parse APP in minutes using Parse Server - www.back4app.com (公式)
Alternative to Parse Shutdown Migrate your app from Parse developer platform to Parse Server in 5 minutes. Keep using the same API and take advantage of Parse.com features. Shared and self-hosting solutions.
- What alternatives exist to Parse now that it is shutting down?
by Alysson Melo, Computer Engineer, back4app Founder (2016-03-02) - www.quora.com: You can build and host APIs for web, mobile and IoT apps, working up to 80% faster. back{4}app uses Parse Open Source framework to make it happen. We developed a quick wizard migration to Parse Users. : 2) We will use all the Parse server structure to run your backend apps. You won’t need to learn how it works a new service and rebuild your app. At this point you don’t need additional effort on your apps migration; 3) You don’t need rewrite your app to communicate with another API standard because we will use the same API. You just need to change the API server address. At this point you will have an effort to change the API endpoint address, republish your new app and communicate your users. :
特徴
- Features - www.back4app.com
- Back4app Documentation - Guides, Tutorials And Examples; - docs.back4app.com
- Parse Migration - docs.back4app.com
Parse Server The open source Parse Server makes possible to serve the Parse API from back{4}app platform. back{4}app provides a way for you to keep your application running without major changes on your App integration. The Parse client SDKs now support changing the API server location to direct them to your own. This also lets you use the Parse client SDKs with entirely new applications that have no dependency on the Parse hosted services. :
- Parse.com 終息宣言後に Parse Alternative であることを前面に打ち出してリリースされた BaaS であり Parse.com に似せた UI を用意するといった配慮も伺える
- Parse.com が OSS として公開している Parse Server ソフトウェア資産をベースに独自拡張を付与することで Parse ユーザが自前で Parse Server を立てることに対する優位性を標榜
- Parse.com でのサーバサイド拡張プログラム(Cloud Code)がほぼそのまま動作する
- 全自動に近い「Parse migration wizard」を装備
- How to migrate your database - docs.back4app.com
- Migrating an Existing Parse App - parse.com
- 各プラットフォーム用 SDK は Parse.com のものをそのまま利用可能。対向サーバのみ変更する
- Parse SDK - docs.back4app.com
In order to complete the migration of your app from parse.com to back{4}app’s servers, you have to do the following steps for each of the devices that your app is currently running in: Install the latest version of Parse SDK (you can find the latest versions of the SDKs here); Configure your app to connect to https://parseapi.back4app.com instead of https://api.parse.com (you can find more details here); Publish the new version of your app with the updates of the previous steps. :
- Parse SDK - docs.back4app.com
- 無論、Parse.com とは無関係にひとつの BaaS としても成立している
- 料金まわり
- Parse.com ほどではないが以下のようになかなか大らか
- Pricing
Free High Limits for Devs. 1 GB Database Storage 5 GB File Storage 10 Requests/second 50 K Requests/month 1 Cloud Code Job
Shared Hosting Designed to assure performance for small apps. Enjoy the best of Parse Server and MongoDB with predictable pricing. 1.5 GB Database Storage 10 GB File Storage 30 Requests/second 100 K Requests/month 1 Cloud Code Job $4.99
F.A.Q. 1 - What is an API request? Every time you make a call to Back4app in name of your application using one of the SDKs or REST API, it counts as an API request. :
back4app で Anpi アプリを実装
以下は back4app 上で Anpi アプリを実装した過程の記録。
1. サインアップ 〜 Parse.com からの Migration を開始
back4app へのサインアップを完了するとメイン画面へ誘導される。ここで「Migrate Parse App」ボタンを押下し Migration Wizard へ移動。
2. App Id および App Name を設定
下の App Id, App Name 設定画面が開く。Parse.com UI(右図)の App Settings - Security & Keys より「Application ID」をコピーしてペースト。App Name は任意の内容で可。
3. Parse.com アプリのデータを移行
下のデータ移行画面が開く。表示されている back4app 管理下の MongoDB URL をコピー。
Parse.com 側 UI で当該アプリの App Settings - General 上の「Migrate to external database」ボタンを押下しポップアップパネルに MongoDB URL をペーストして「Begin the migration」。
コピー完了。ここで「Finalize」ボタンを押下すると Parse.com 上で当該 DB が凍結され利用不可となるので注意。ほっとけばよい。右の back4app 画面に戻り完了のボックスをチェックして NEXT ボタンを押下。
4. アプリケーションキーを移行
下のキー移行画面が開く。右の Parse.com 側当該アプリの App Settings - Security & Keys 画面上の各キーをコピー&ペーストし最後に NEXT を押下。
5. データとキーの移行完了
下の画面で Parse.com 側対向サーバ代替の back4app 対向サーバ URL が示される。NEXT を押すとNeumob の SDK をインストールするかと尋ねてくる。必要なければそのまま FINISH を押下。
これでデータとキーの移行は完了。機能一覧上の「Parse Dashboard」をクリックすると、、
本家の Dashboard によく似た下の UI が開く。(右は本家 Parse.com の Dashboard)
6. Cloud Code を移行
サーバサイド機能拡張用の Cloud Code を Parse.com から移行する。Parse.com 側の当該アプリの Cloud Code をローカル PC 上に保存する。
back4app の機能一覧から「Cloud Code」をクリックすると Cloud Code アップロード画面へ移動する。ここでローカル PC 上の Cloud Code ファイルをアップロードして SAVE ボタンを押下すれば移行完了。
back4app へアップロードした Cloud Code 内の所定の関数は下の要領で実行できる。App ID と REST API キーを指定。
curl -X POST \ -H "X-Parse-Application-Id: 9DwPK4M1qbTIvNjrLCXXXXXXXXXXXXXXXXX" \ -H "X-Parse-REST-API-Key: PyKdFUTa6DiB0g2J4nVFXXXXXXXXXXXXXXXXX" \ "https://parseapi.back4app.com/functions/hello"
なお、オブジェクト Detected へのデータ POST は以下の要領。IoT 装置側のコードにこれを反映する。
curl -v -X POST \ -H "X-Parse-Application-Id: 9DwPK4M1qbTIvNjrLCXXXXXXXXXXXXXXXXX" \ -H "X-Parse-REST-API-Key: PyKdFUTa6DiB0g2J4nVFXXXXXXXXXXXXXXXXX" \ -H "Content-Type: application/json" \ "https://parseapi.back4app.com/functions/detected" \ -d '{"temp" : "11.1", "devid" : "MAKOTO", "ip" : "10.10.0.1"}'
7. 完了
残りの TODO
これで終わりかと思ったが実はまだやるべきことがあった。
Cloud Code の修正
- main.js - GitHub/mkttanabe/Anpi
back4app は Parse.com の Cloud Code をそのまま動かせると謳っているが例外もある。以前 Parse.com 用に作成した上のコードはメール送信に Mailgun を使用しているが、Parse.com 上の mailgun モジュールと base4app 上の mailgun-js では I/F が異なるため下記要領の変更が必要だった。
Before:
Parse.Cloud.define("sendmail", function(request, response) { var Mailgun = require('mailgun'); Mailgun.initialize(MAILGUN_DOMAIN, MAILGUN_KEY); Mailgun.sendEmail({ to: MAILGUN_TO, from: MAILGUN_FROM, subject: "** Notification (" + request.params.devid + ") **", text: "[" + request.params.devid + "] のボタンが押されました \r\n(" + now() +")" },{ success: function() { response.success("email sent"); }, error: function() { response.error("Failed to send a mail.."); } }); });
After:
Parse.Cloud.define("sendmail", function(request, response) { var mailgun = require('mailgun-js')({apiKey: MAILGUN_KEY, domain: MAILGUN_DOMAIN}); var mailOptions = { from: MAILGUN_FROM, to: MAILGUN_TO, subject: '** Notification (' + request.params.devid + ') **', text: '[' + request.params.devid + '] のボタンが押されました \r\n(' + now() +')' }; mailgun.messages().send(mailOptions, function (error, body) { if(error){ console.log(error) response.error("Failed to send a mail.."); } else { console.log(body) response.success("email sent"); } }); });
ジョブ登録上の問題
現時点の back4app では Parse.com ほどには細かいジョブ設定ができない様子。現在も開発中?
図のように UI はあっさりしている。
関係のありそうな記事
- How can I use background job? - groups.google.com
ジョブ登録の問題のみで back2app を丸ごと諦めるのは惜しく、前出の例のように IFTTT からリクエストを投げる線も考えた。しかし、IFTTT の Maker チャネルからの HTTP(s) リクエストにはヘッダにカスタムフィールドを加えることができないためここでは利用できない。そこで、何かと融通の効く AWS Lambda を利用することにした。無料枠で十分に対応可能。[料金]
仮移行を通じての * 個人的な * 印象
GOOD !
- 無料枠が広い
- 最初から Parse.com の代替用として起ち上げられた純度の高い Parse Alternative であるため Parse.com との親和性が高く移行が相対的に容易
- UI, ドキュメントがわかりやすい
! GOOD ?
- 記事中のジョブ設定の問題など現時点では荒削りな側面も見られる
- Parse.com を継承するサービスとしては良好だが、逆にそのことが独立した BaaS としての新鮮味や個性の発露を削いでいる印象も?
移行先候補 4: Backand
Backand は ModuBiz Ltd(本社イスラエル Tel Aviv)の提供する BaaS です。
Backand とは
概要
Backand は ModuBiz Ltd(本社イスラエル Tel Aviv)の提供する BaaS です。米カリフォルニアにも拠点を置いています。
- AngularJS Backend - Back& - www.backand.com (公式)
Instant Backend in the Cloud Backand is a powerful backend-as-a-service for AngularJS and ReactJS that provides out-of-the-box social login, real-time communication, Ionic integration and much more.
日本での知名度は高くありませんが、Backand は Parse Alternative としてもアピールしています。
- The Parse-to-Backand Migration Guide - www.backand.com
- Choosing a Parse Alternative - blog.backand.com
Parse.com と FireBase, Backand の機能比較
Server Side Code Execution, Push Notifications あたりがポイント
- Backand Presentation by Backand Cohen (2014-09-02) - www.slideshare.net
特徴
- サーバサイドコードの記述・設置を行う上での便宜が重視されている
- Custom Actions
- イベントトリガー起動 / オンデマンド起動 / スケジュール起動に対応
- データストアインフラとして Amazon RDS を採用。リレーションシップの構築、SQL, NoSQL のサポートなどデータを扱う上での柔軟性が高い
- REST API 完備
- モバイルクライアントアプリ開発向けに Ionic Framework との統合セットを提供
- 4 easy steps to start mobile ionic project
- Ionic with Backand
- 現時点でプラットフォーム個別の SDK は用意されていない
- 連携サービスの幅が広い
- Integrations
- と言うより、自前ですべての機能を開発・提供するのではなく、むしろ利用可能な既成のサービスとの統合による合理化を旨としている模様。Ionic、プッシュ通知、メール配信 etc..
- ブラウザ UI 上でほとんどの操作を完結できる
- ファイル・モジュールのホスティング用に Node.js ベースのコマンドラインツールも用意されている
- Hosting
- 料金まわり
- Pricing & Plans
表の「Prototype」Plan が無料枠
プラン境界には Requests per Second や Database Size といった客観的に把握・調整のしやすい基準以外に Cache Memory のように内部的かつ累積値で評価される尺度も含まれる - ちなみに試用開始から一週間経過した時点での利用状況。すでに「Cache Memory」がきわどい
- Frequently Asked Questions
: How is Backand Compute calculated? Backand Compute is calculated by accumulating the compute resources allocated to an application in order to run its tasks. It is affected by application characteristics, such as the type and complexity of a task, the number of requests and size of the database, and the number of objects and functions involved in a task. How is Cache Memory KB/hour calculated? When an application runs in Backand, it stays in the cache to optimize its performance until the system’s algorithm finds it unnecessary and clears it out. Cache KB/H is the amount of cache memory allocated to an application and the time it is allocated for. For example, if an application requires 700KB of memory and stays in the cache for 24 hours, it uses 24X700=16,800 Cache Memory KB/H :
「Cache Memory (KB/H)」という表記はあたかも一時間あたりのメモリ占有量を指すもののように見えるが実は上の説明の通り通算の累積値。念のため Cache Memory がリセットされる機会について尋ねたところ Backand からの回答は以下の内容だった。基本的にはやはり累積するのみで唯一 Billing Cycle ごとにリセットされるらしい。この「Cache Memory」は運営側の内部的な指標であるため利用者側が状況に応じてコントロールすることは難しい。とりあえずフリープランのリミットまで使ってみることにする。
- Pricing & Plans
Backand で Anpi アプリを実装
以下は Backand 上で Anpi アプリを実装した過程の記録。
- 例によってモバイルアプリやメッセージング、プッシュ通知の要素は含まれない
- Backand のファイル・モジュールのホスティング機能は利用していない
- 「Parse to Backand Migration tool」により Parse.com 上のデータを移行可能だが、back4app とは違い手作業での煩雑さに加え移行後のオブジェクトの "id" ユニークキーがシンプルな整数型ではなく UUID 文字列型であり全体としてあまり効率が良くないため利用を見送った
1. サインアップ 〜 アプリ作成
サインアップ後にメイン画面へ誘導される。ここで所定のアプリケーションを作成し、必要に応じガイド表示に添ってソフトウェアをインストールする。
2. 必要なオブジェクトを作成
Backand のプログラム要素はすべて所定のオブジェクトに付随する存在であるため必要なオブジェクトを作成する。ここでは Anpi で常用の Detected オブジェクトを作成し必要なフィールドを設定する。
3. オブジェクトの Data と Actions
とりあえず Securiry & Auth - Configuration で Anonymous Token を有効にして以下の要領で Detected オブジェクトへ何件かデータを登録してみる。
Detected へデータを登録する REST API 書式。IoT 装置側のコードはこの要領で記述を加えた。
curl -v -X POST \ -H "AnonymousToken: 66dfbbb6-6d49-4ad7-XXXXXXXXXXXX" \ -H "Content-Type: application/json" \ "https://api.backand.com:443/1/objects/Detected?returnObject=true&deep=false" \ -d '{"posted": "", "deviceId": "MAKOTO", "deviceAddress" : "192.168.0.112", "temperature" : "12.3"}'
Data の一覧
Actions にはユーザ定義のプログラムやアクションを指定可能。Actions は、任意の時点での実行を前提とする「on Demand」に加え、データ新規登録をトリガーとする「Create」、データ更新がトリガーの「Update」, データ削除がトリガーの「Delete」に分類される。
Create/ Update/ Delete の各トリガーはさらにそれぞれ Before, During, After のタイミングに細分される。
所定の Action の Type は 1. Server Side JavaScript Code(AngularJS コード実行)/ 2. Server Side Node.js Code(ホスティングしたモジュールの実行)および 3. Send Email / 4. Transactional sql script の実行から選択可能。
差し当たり 2,3,4 は特に必要がなく「Server Side JavaScript Code」のみを利用した。
4. クエリ文を記述
Queries - New Query で所定のクエリ文の静的記述と保存・テスト実行ができる。
もちろんプログラムから呼び出すことも可能。後述。
「SELECT * FROM Detected ORDER BY id DESC LIMIT 60」
5. Custom Action コード を書く・テストする
Settings - General において「Debug Mode」を ON にすることで console.log() 出力が有効となる。
また「Global Configuration」に各プログラムに共通の定義を記述可能。
Objects - Detected - Actions - Create - Before に「onBefore01」の名前で以下の Server Side JavaScript Code を記述した。一件の Detected データ登録前に created フィールドへ現在日時を設定する内容。
画面上の「Test Action」ボタン押下により Action をテストするための UI が開き、ここで手早く当該 Action のテスト実行が可能。これは便利!
Objects - Detected - Actions - on Demand - Execute に「onDemand01」の名前で以下の Server Side JavaScript Code を記述した。
前掲の Query01 を使って Detected オブジェクトから直近の 60件のデータを抽出して整形しレポートとしてメールで送信する内容。
画面上の「Test Action」ボタン押下により Action をテストするための UI が開き、ここで手早く当該 Action のテスト実行が可能。
REST API で onDemand01 を実行する書式は以下の通り。
curl -v -X GET \ -H "AnonymousToken: 66dfbbb6-6d49-4ad7-XXXXXXXXXXXX" \ -H "Content-Type: application/json" \ "https://api.backand.com:443/1/objects/action/Detected?name=onDemand01"
6. onDemand コードを定刻実行する
Background jobs - New Job において任意のタイミングでの以下の実行を定義可能。
- Actions へ記述ずみの on Demand Action
- Queries へ定義ずみの Query
- 所定の HTTP Request (GET / POST)
以下の要領で Detected.onDemand01 を毎日 05:30, 11:30, 17:30, 23:30 に実行する。
(サービス利用状況の確認)
現在の Usage は以下のように Settings - Upgrade Plan から確認できる。
- Frequently Asked Questions
What if I exceed my plan limits? : Free plan users will be granted a grace period of a few days to provide a payment method. After the grace period is over, the app will be blocked until a payment method and an appropriate price plan will be set.
「Cache Memory」がリミットを超過した状況であり試用を中止。上記 FAQ での説明に記述されているとおりアプリがブロックされるにまかせることにした。その後、「Next Billing Cycle」として記載されていた 12月20日に支払いを打診するメールが届くが上の説明どおりの措置で構わないため取り合わずにおく。その後数回に渡り同様のメールが届き最終的に「Your application has been canceled」の旨が通知された。
仮移行を通じての * 個人的な * 印象
GOOD !
- 多機能かつ拡張性に優れている上に非常に使いやすい
- テスト・デバッグ機能も充実しており UI もわかり易い
- ファイルホスティングまわりの操作以外はすべてブラウザ上で完結できるため機動性が高い
- ユーザビリティは今回の中で一番。あとは可用性とスケーラビリティ次第か
! GOOD ?
- 無料枠の狭さが残念。また、Prototype Plan $0 -> Hobby Plan $19/月 -> Work Plan $49/月 ... といった大きめの料金差に比して待遇差が小さめ
- 運営側の内部的な指標である「Cache Memory」「Compute Units」のように利用者が主体的にコントロールすることの難しい指標がプランの基準に含まれているため利用目処を立てにくい(むしろ、利用するならはじめから UNLIMITED な料金プランを選ぶべき)
- 日本のみならず国外でもまだあまりメジャーではなく情報がとても少ない。優れたサービスであるにもかかわらず世間への浸透圧が低い一因は上の料金体系にもあるのではないか?
(2018-01-19 追記)
2018年1月18日、Backand より 2月28日にサービスを終了する旨のメールが届きました。その後手元では利用していませんでしたが、品質の高いサービスであっただけに残念です。
-
メール原文と Gmail 自動翻訳結果
- 公式サイトでの表示
おわりに
手元要件の Parse.com からの移行にあたり以上よっつの環境を試してみました。最終的にこの中のひとつを「Anpi」の乗り換え先に決定して現在に至ります。当初はどれを選んだのかを書くつもりでしたが無粋にも思いやめておくことにしました。いずれも質の高いサービスでそれぞれに十分なメリットがあります。
ほんの10年ほど前には影もなかったものが日進月歩で進化していく状況にリアルタイムで向き合っていると10年後の世界への想像が膨らみます。この時代の傍らを去っていく Parse.com をユーザのひとりとして敬意と感謝の念をもって見送りたいと思います。
(tanabe)