09

ASP.NET の 永続化層で悩む

現在作成しているシステムは諸事情あってクライアントサイドがAngularJSでサーバサイドがASP.NET(VB) / WebAPI2 になっている。なるべく早く顧客に動きを見せるためにおおざっぱに全体を実装する感じでやっている。クライアントサイドはまあAngularJSで適当にやっているけど、サーバサイドはいわゆるREST API的に実装しているのだけど、ロジックのほとんどがSQLだ。

  1. HTTPリクエスト受付
  2. ⇒SQL生成
  3. ⇒実行
  4. ⇒結果取得
  5. ⇒そのまま1レコードを連想配列とするようなオブジェクトの配列としてJSON変換
  6. ⇒HTTPレスポンス

みたいな流れがほとんど。

今のところまだバリデーションやらセキュリティやらは考慮していないので今後その辺増えていく可能性はあるけれど、サーバサイドがほとんどSQLで済むのならば、サーバサイドレイヤーはほんとに薄くなりそう。

本当はORマッピングレイヤーを何かしら入れるつもりでいたのだけど、いろいろいじってみているうちにどれも.NET初心者(自分)にとって学習コスト含め重すぎるという結論になってやめた。

EntityFramework6

方式がモデルファーストとコードファーストとDBファーストの3種類ある。らしい。モデルファーストは専用のモデルエディタを使ってエンティティの定義を作ってやるとデータベースのスクリプトとそれにマッピングされるモデルクラスを自動生成してくれるようだ。はじめこれを使ってやっていたのだけど、いろいろがちゃがちゃとやっているうちにモデルエディタがうんともすんとも言わなくなってしまって全く原因もわからないのでパスした。他の方法はあまり試してないのだけど、このあたりでEntityFrameworkの評判を聞いてみたところあまりよい反応はなさそうだったので、別な方法を探した方がよさそうな空気になった。

Linq to SQL

EntityFrameworkを使いたかった理由の一つがLinq to Entitiesを使えるからということで調べていたのだけど、それ以外の方法としてLinqをSQLにマッピングするLink to SQLとやらがあるらしいのでそちらの使用方法も調べてみた。しかしどうもこれDeprecated扱いにしたい雰囲気を感じるのと、こちらでも妙なGUIを使ったモデルエディタの力が必要になるっぽいのでパス。

Dapper

SQLはSQLとして発行してその結果をクラスにマッピングしてくれるだけの薄いDBアクセスフレームワークらしい。いいんだけど、正直結果の数だけクラス作るのかなあと思うと、どうせ結果はそのまま画面に出すだけなんだから結果セットをそのままJSONに変換するくらいの勢いでいいんじゃないだろうか、と思い当った。

といった経緯で、SQLの実行結果はそのままクライアントに転送してもいいのではないかと思い始め、単純にSQL編集の補助をしてくれて結果をJson関数に渡せる形で返すというだけのラッパーを書いてみた。現状サーバサイドロジックは大体こんなような書き方になっている。

Using db as new DB()

    dim sql as new SQLBuilder
    sql.Add("select * from hoge_table ")
    sql.Add("where foo=@bar", barValue)

    return Json(db.Q(sql))

End Using

今のところは(プロトタイプであることもあってか)特に問題とはなっていないけれども、エンティティの整合性を保つためにHTTPのインプット側に関してはサーバサイドでも強固なチェックの必要性はありそうかな。 詳細画面なんかだと、情報の構成がいわゆるヘッダー - 明細構成になっているものがあったりして、その場合はSQLの実行結果から、クライアントサイドで使いやすそうなオブジェクトの形へ整形処理を行ったりしている部分も若干ある。

この辺うまくというか、宣言的な方法でわかりやすい記述でやれるといいんだけどなあ。まあその辺はこれから。

あ、あとエラーハンドリングに関してもまだ方針を決めていない。 個人的にはエラーと正常のフラグを持つオブジェクトを一つ作って、その中に適当に結果を入れて返すのがいいかなあと漠然と考えていたのだけど、どうせならHTTPヘッダにそれらしい情報を埋めてしまうのがいいのかもしれない。

YappoLogs: 2014年に向けた JSON API の実装の方向性と X-JSON-Status 改め X-API-Status header のご提案