Android+slim3(appengine)連携の冴えたやり方?
わかめの言ってること分からんって言われたのでちょっと書き直しました。
Android+appengineは、昔きょーりゅーてんていが言ってた通り、夢の組み合わせなわけですよ。
世界中で動く端末!個人が気軽に使える(気分的に)無限にスケールするサーバ!!
ただ、今まで冴えたサーバ、クライアント間連携の仕方って思いつかず、2〜3ヶ月くらいずっと悩んでました。
最近、一応現実的な解を思いついたので、ここに書いてみんなから意見を貰えたらなぁと思います
目指すこと
サーバ側とクライアント側での通信内容を解釈するためのコーディングをほぼゼロで済ませたいし、テスト可能な作りにしたい。
手作業で通信内容をパースするような処理を書くと、エンバグする可能性がある。こわい><
そのために、フォーマットを規定するPOJO自体を共有化したい。
前提
通信は基本的にJSONで行う。
JsonPullParserをガンガン使う (次バージョン(0.3?)からDeserializeだけじゃなくSerializeも出来るようになる予定)
結論
クライアント←クライアント用モデルプロジェクト→サーバUnitTest こうする。
方針
で、そのためには、サーバとクライアントの間でモデルの共有(Encoder, Decoderの共有化)が必要だとずっと思っていました。
つまり、 クライアント←共通モデル共有用プロジェクト→サーバ っていう形ですね。モデルにJsonPullParserを適用してJSONでやりとりする感じです。
ただ、単純にこの方法を推し進めようとすると無理があることがようやくわかりました。
困ること
1. Slim3のアノテーションが邪魔
ただまぁ、これはSlim3の@ModelはリテンションがSOURCEでコンパイルすれば消えてしまうアノテーションであることと、@AttributeはリテンションがRUNTIMEですが、これもまぁAttributeのモックアノテーションを作ってクライアント側で利用するか、ProGuardかなんかでアノテーションを取り除いたclassを生成してやればいいのかなという気がしなくもないです(できるか知らないけど)。
2. サーバ側EntityとAndroidのモデルを共有化するとデコンパイルされてサーバ側の保持データがバレる
デコンパイルされるとかなり困る。例えば、JSONでやりとりしているデータ以外に更新日付やアクセス元IPアドレスを保持している、とか、JSONでやりとりしないデータに、サーバ側の動作制御用Entityが絡んでいて、コンパイルを通すためにはそのEntityも含めないといけないので制御用Entityの構造も一緒くたにバレる。
とかがあって、サーバ側とクライアント側のモデル(=JSON変換ライブラリ)を共有化するのは辛いよなぁ…という結論になりました。
最初は1だけしか気がついてなくてここさえクリア出来れば…!!とか思ってたんですけど、2がでた瞬間サーバ側Entity構成を全部バラさざるを得ないことが判明して挫折したわけです。
解決方法
結局、サーバ側とクライアント側のモデル共有化は諦めることにしましたorz
で、代替案としてどうすることにしたのか?
クライアント←クライアント用モデルプロジェクト→サーバUnitTest こうすることで、クライアント側とのIFの整合性が取れていることを自動的に担保するようにすればいいのではないかと思いました。
具体的には
- クライアント用モデルプロジェクト作成
- サーバから送られてくるデータにあわせてPOJOを作成
- JsonPullParserを適用
- antでコンパイルし、クライアントにjarをインポートして利用 (POJO+JsonPullParser生成物)
- mvnでコンパイルし、サーバ側で scope test で利用
- UnitTestで処理結果をクライアント側モデルに突っ込み、エラーが発生しないことを確認
ていう感じでやっていってみようかと。
今回テストしているのはサーバ→クライアント側の通信だけですが、まぁ今回はこれでいいかなと
クライアント→サーバ側通信で考えられるのは
の2パターンないしその組み合わせかと思います。
1についてはまぁ適当にやればいいですし、2についてはSlim3 1.0.6からSimpleControllerというInputStreamが扱えるコントローラが増えたので、それを使えば楽に検証できていいと思います。
参考リンク 404 shin1のつぶやき ないわー Not Found: #slim3 1.0.6 のSimpleControllerを使った場合のテスト方法 #appengine
問題点
クライアント側とモデル編集をする人と、サーバ側の担当者が別だと、モデル編集されてコミットされるとサーバ側のテストが壊れてHudsonさんに超絶怒られる。
→めんどくなって手動でjarを更新したものがHudsonさんにも適用されるように設定を変える→即時チェックの恩恵が薄れる→喧嘩になる
こういう未来が見える('A`)ドウシヨウ
将来的には
モデルの共有化は辛いということがわかったので、O/RマッパーならぬO/Oマッパーが必要なのかなぁ…と思ったり。あるクラスとあるクラスで、名前が同じフィールドがあったら相互変換できればいいよね的な。