愚痴
- 車輪の再発明したくない(見飽きた、モチベーションあがんない)
- スマホとかOSのアップデートとかに引っ張られてアプリの保守したくない
- 同じビジネスロジックをいろんな環境(プログラミング言語)で書きたくない
- サービスの本質の部分に時間を割きたい
- 極力作りたくない病(保守するものが増える)
やりたいこと
- パラメータ受け取ってJSONを返す関数(ビジネスロジック)を共通化
- 色々な環境からコールができる、古いコードも動くJavaScriptが良さげ(サーバサイド、フロントエンド、ネイティブコール、デスクトップアプリ化)
- Firebaseぽくローカルとサーバのデータを同期させたい(オフラインでも動く)
- 速度?セキュリティ?
なにそれおいしいの? Java?いえ、知らない子ですね
動かしたい環境
- Rest APIとして提供(NodeJS)
- ブラウザ(Chrome,Mobile Safari,IE)
- スマートフォンネイティブ(iOS,Android)
- デスクトップアプリ(Windows,Mac OSX)
実現方法
- ビジネスロジックはNodeJSのモジュールとして記述し、Browserifyでブラウザモジュール化
- iOS、AndroidはWebView経由でJavaScript関数コール
- ストレージはlocalStorageDBでローカル保存、サーバ同期
- Electronでデスクトップアプリ化
イメージ
Why localStorageDB?
- SQLiteとかだとそれぞれの環境でDB呼び出しの実装が必要(
めんどいというか本末転倒) - localStorageだと守備範囲広い
- 単純なlocalStorageだとKVSなので検索とかしたいし
- 少し工夫したらNodeJSでも使えたのでブラウザ間とのデータ同期に使えそう
- ブラウザにもよるけどlocalStorageの上限5MBほどらしいのでイメージとかバイナリ保存には向いてない
やってみた
サンプルソースおいてます。
GitHub:https://github.com/teradonburi/bridge
配布物
- NodeJSサンプル(Rest API)
- ブラウザサンプル
- iOS、Androidサンプル(WebView経由で呼び出し)
- PCアプリサンプル(Electron)
gulpで自動化
コード修正したら面倒くさい作業はgulpで自動化
- NodeJSサーバ再起動(execSync)
- ブラウザ再読み込み(gulp-webserver)
- 単体テスト(jasmine-node)
- コードレビュー(grunt-plato)
- APIドキュメント作成(gulp-yuidoc)
- ブラウザコード化(Browserify)
- PCアプリ生成(electron-packager)
データ同期の仕組み
- ページ表示にサーバからデータ同期(全ユーザデータ読み取り)
- オンライン状態はローカルデータ書き込み時にサーバに自ユーザデータを同期
- オフライン→オンライン時にサーバとデータ同期
- 他ユーザデータが更新されたらWebSocketでプッシュ受信でローカルデータ更新
- 自ローカルで他ユーザ更新はやらない(同期時にデータ整合性取れなくなるので)
本当にWrite Once?
- WebViewからの呼び出し部分はOS依存(iOS、Android)
- Electronのバージョンアップに依存
修正範囲は狭くなるけど、OSのバージョンアップされたら保証は無理ぽ
課題
- HTMLをローカルファイルにして提供するとクロスドメインの問題が・・・(サーバ側でCORS許可するか
ローカルファイルやめてHTMLページをサーバ提供に?) - 別のPCアプリからElectronアプリのAPIコール(プロセス間通信)したい場合、どうすりゃいいの?・・・(
いっそElectronのメインプロセス側にNodeJSのHTTPサーバを立てる?) - GUIコンポーネントもライブラリ化したい