GAEは運用を考えるとMAP時代にもどったほうがいいのかな

Google App Engineのデータストアはすごい癖がある。

他のコントローラがどうだとかそういうのはどうでもよくて、ここが一番難しい。従来の考え方を変える必要がある。

トランザクションとかロックの範囲から逃れるようなコードは書くことはできるんだけれども、実際はレスポンスがものすごく悪いので、それらの制限を回避するような込み入ったことをやろうとすると余計に時間がかかるというオチ。おとなしくすべてのエンティティが1つのエンティティグループに属させるほうがましというくらい。


というわけでデータストアサービスになるべく近い方向に思考をもっていく必要があるのだと思う。従来のO/Rマッパのようなものを用意してもしょうがない。意味がない。ローレベルAPIを直で使うくらいの勢いが必要。


長期的な運用を考えるとこの辺が必要なんだよね。たとえばバージョンアップでエンティティの構成が変わるなんてことはよくあると思う。バッチを流すのが容易ではないGAEにおいてこれは致命的。なるべくデータはそのままで、「プログラマが責任を持って扱う」べきと考える。

その判断材料としてエンティティやアプリのバージョンを保持するというのはまず考えられる。実際自分もデータベースが使えない環境でXMLやテキスト、バイナリファイルをあつかうときにはこれをしていた。美しくないかもしれないけど、バージョンによって扱い方を変えるというもの。



もちろん、エンティティのプロパティも一定ではない。最初は数値型でよかったところがやっぱり文字列で、ということになったりすることもあるかもしれない。バッチが流せないのだから仕方がない、そのままで「いいように」やっていく必要がある。

ということはよくあるエンティティをPOJOで作成とかいうのもそのままマッピングさせてはならない。1枚バージョンごとにアクセスできるものを変換用にかぶせるか、自由な型での取得できるもんを用意する必要がある。実際は前者をやる場合校舎が必要になるので排他的な考えではないけど。


つまり、具体的にいうと。

JDBCでいえば

  • ResultSet#getString
  • ResultSet#getInt

DelphiとかC++Builder触ってきた人種なら

  • FieldByName("hoge").AsString
  • FieldByName("hoge").AsInteger

のような必要なものがあると便利かもねということ。

型もプロパティ名も柔軟に。型と名前を持ったエンティティクラスを用意するならマッピングにこれを使う。



この時代に戻るべきなんかな。

個人的にはエンティティのプロパティ名はIDEのサポートがあるとミスが減って便利だと感じる(RDBのようなものなら普通に文字列だけでアクセスさせて問題ない。フィールドが存在しなければ例外を出せばよいだけのこと)ので、文字列以外にもEnum等をうけとれるようにしてプロパティ名のEnumを持ってるだけが楽なのかなと思う。


Cubby 1.xの時にフィールドの型のテストとかしてた時に結構テストやってた。リクエストで入ってきた数字をそのままDBへ格納、取得時にはIntegerでもOKとか。そのときに文字列だけだとつらいということを思い知った。型はわりとどうにでもなる(というか、どうせ自前で変換していた)ってのも思い知った。EnumにしておけばJavadocでいつからこの項目が追加されたか、使用に関して注意すべきか等がまとめられるのもよかったかな。

変換できるかどうかのメソッド(isIntegerとか)を用意しておけばまぁ問題ないかなと。GAEは考え方を変える必要あると思うよ。IntegerからDecimalへとかよくあるしね。