5/29-30 de:code セッション SV-007 “パワフル モバイル アプリ開発 ~ 最新 Microsoft Azure Mobile Services をフル活用しよう!~ ” フォローアップ (1)
皆様、こんにちは!de:code では多くの皆様に参加いただき誠に有難うございました。セッション内でもお約束しました通り、さっそく、セッションフォローアップしていきたいと思っています。
詳細は、ビデオが出てからということになりますが、今回は概要と、ASP.NET Web API バックエンドのところの解説をしたいと思います。
全体像
セッションでもご紹介した通り、これがMobile Services の全体像です。クライアントはほぼすべてのクライアントに、ネイティブで対応、HTML5クライアントももちろんあります。データベースは、SQL Azure Database 以外に、Azure Table Storage、Azure Blob Storage、それにOSS で MongoDBがくわわりました。Hybrid Connections というところは、BizTalk を介して様々なデータベースが連携できます。
ASP.NET Web API バックエンド
これまでの Mobile Services は、Node.js バックエンドのみでしたので、クライアントで定義されたクラスから渡された JSON のデータは、そのまま、ダイナミックにスキーマが構成されて、3列あるDBであれば3列に構成されました。そのイメージはこちらです。
1: public class Favorites
2: {
3: public string Id { get; set; }
4:
5: [JsonProperty(PropertyName = "text")]
6: public string Text { get; set; }
7:
8: [JsonProperty(PropertyName = "userid")]
9: public string UserId { get; set; }
10:
11: [JsonProperty(PropertyName = "complete")]
12: public bool Complete { get; set; }
13:
14: }
これは、SQL データベースの動的スキーマがデフォルトで ON になっているためです。
これに対して、新しいデータモデルでは、.NET バックエンドが採用されたため、データベースは自分で選べるようになり、またオフラインデータ対応もSQLiteを使ってできるようになりました。
したがって、これまでの Mobile Services は、どちらかというとデータベースはSQL固定で、クライアント側の開発者が手軽にバックエンドのNode.jsを使って開発しやすいというモデルになっていたのに対して、新しいMobile Services では、.NET バックエンドが追加されたために、自由なデータベースの選択ができるようになり、バックエンドのロジックを自分で作らなければならなくなりました。バックエンドの開発者にとっては自由度が高まったといえます。
また、.NET バックエンドでは、Entity Framework/CodeFirst を採用しており、最初からこれが含まれています。
したがって、いままでは、これを追加してから、ASP.NET Web API(.NETバックエンド)でコントローラーを追加してRESTでデータ公開ということが必要だったのに対して、これからは、ASP.NET Web APIバックエンドを追加してやるだけで、その中に、Entity Framework/CodeFIrst も含まれています。
ですので、using Microsoft.WindowsAzure.Mobile.Services; でこの名前空間を加えるだけで、EntityData からクラスを継承できるわけです。
Mobile Services の作成
では、ここから実際に、Visual Studio の Mobile Services テンプレートを使って、アプリを作ってみましょう。適当な名前でOKをおして保存します。
Mobile Services .NET バックエンドによる CRUD 処理の実装とデバッグ
ここでは、スーパーマーケットのタイムセールのストアアプリをご紹介しました。
上記の手順で、クラスを作成し、DBコンテキストに DbSet を追加し、初期データを DB に挿入してみてください。クラスはこんな感じです。
1: using Microsoft.WindowsAzure.Mobile.Service;
2:
3: namespace TimeSaleAPMobileService.DataObjects
4: {
5: public class ProductWithPrice : EntityData
6: {
7: public string StoreId { get; set; }
8: public string StoreName { get; set; }
9: public string PriceChangedDate { get; set; }
10: public string ProductName { get; set; }
11: public string RetailPrice { get; set; }
12: public string ReasonforChangePrice { get; set; }
13: public string PriceFixedDate { get; set; }
14: public string Contact { get; set; }
15: }
16: }public string Text { get; set; }
そして、DBコンテキストに DbSet を追加します。
1: public DbSet<ProductWithPrice> ProductWithPrices { get; set; }
次に、Controller を追加します。フォルダーを右クリックして、コントローラーの追加を選び、
テーブルコントローラーを選びます。
上記のように選択します。追加を行います。
次に、初期データを、WebAPIConfig の Seed メソッドの中にメンバーとして追加してやります。
1: List<ProductWithPrice> productWithPrices = new List<ProductWithPrice>
2: {
3: new ProductWithPrice
4: {
5: Id ="1",
6: StoreId = "1",
7: StoreName = "品川店",
8: PriceChangedDate = "2013/1/16 9:00",
9: ProductName = "白菜1個",
10: RetailPrice = "300",
11: ReasonforChangePrice = "通常価格",
12: PriceFixedDate = "2013/1/15 18:00",
13: Contact = "野菜担当 山田"
14: },
15: new ProductWithPrice
16: {
17: Id ="2",
18: StoreId = "2",
19: StoreName = "白金高輪店",
20: PriceChangedDate = "2013/1/16 16:00",
21: ProductName = "ブドウ1房",
22: RetailPrice = "650",
23: ReasonforChangePrice = "夕方のタイムセール",
24: PriceFixedDate = "2013/1/16 12:00",
25: Contact = "店長 鈴木"
26: },
27: new ProductWithPrice
28: {
29: Id ="3",
30: StoreId = "3",
31: StoreName = "五反田店",
32: PriceChangedDate = "2013/1/16 18:00",
33: ProductName = "トマト3個",
34: RetailPrice = "150",
35: ReasonforChangePrice = "タイムセール終了",
36: PriceFixedDate = "2013/1/16 12:00",
37: Contact = "店長 松本"
38: },
39:
40: new ProductWithPrice
41: {
42: Id ="4",
43: StoreId = "4",
44: StoreName = "目黒店",
45: PriceChangedDate = "2013/1/17 9:00",
46: ProductName = "玉ねぎ3つ",
47: RetailPrice = "260",
48: ReasonforChangePrice = "木曜セール",
49: PriceFixedDate = "2013/1/16 18:00",
50: Contact = "野菜担当 山田"
51: },
52: new ProductWithPrice
53: {
54: Id ="5",
55: StoreId = "5",
56: StoreName = "渋谷店",
57: PriceChangedDate = "2013/1/17 9:00",
58: ProductName = "人参3本",
59: RetailPrice = "260",
60: ReasonforChangePrice = "木曜セール",
61: PriceFixedDate = "2013/1/16 18:00",
62: Contact = "野菜担当 青木"
63: },
64: new ProductWithPrice
65: {
66: Id ="6",
67: StoreId = "6",
68: StoreName = "川崎店",
69: PriceChangedDate = "2013/1/17 9:00",
70: ProductName = "玉ねぎ3本",
71: RetailPrice = "240",
72: ReasonforChangePrice = "タイムセール終了",
73: PriceFixedDate = "2013/1/16 18:00",
74: Contact = "野菜担当 金子"
75: },
76: new ProductWithPrice
77: {
78: Id ="7",
79: StoreId = "1",
80: StoreName = "品川店",
81: PriceChangedDate = "2013/1/17 9:00",
82: ProductName = "ながのパープル1房",
83: RetailPrice = "700",
84: ReasonforChangePrice = "タイムセール終了",
85: PriceFixedDate = "2013/1/16 18:00",
86: Contact = "野菜担当 藤田"
87: },
88: new ProductWithPrice
89: {
90: Id ="8",
91: StoreId = "5",
92: StoreName = "目黒店",
93: PriceChangedDate = "2013/1/17 9:00",
94: ProductName = "玉ねぎ3本",
95: RetailPrice = "240",
96: ReasonforChangePrice = "木曜タイムセール",
97: PriceFixedDate = "2013/1/16 18:00",
98: Contact = "野菜担当 栗田"
99: },
100: };
101:
102: foreach (ProductWithPrice productWithPrice in productWithPrices)
103: {
104: context.Set<ProductWithPrice>().Add(productWithPrice);
105: }
106:
107: base.Seed(context);
これで完了です。ビルドして、実行してみてください。画面右下のTry it out から実行して、GETメソッドを実行し、全初期データレコードが出てくればOKです。この時、Id列も、文字列型でいれることを忘れないでください。これは仕様ですので、いつもの癖?で整数値型等にしてしまうと、ビルドエラーも起きない代わりに、初期データが挿入されないので、もう一度やり直して実行しましょう。
上記の通り試します。OKであれば、プロジェクトを右クリックして、Microsoft Azure に発行しましょう。
この時、Debug に設定しておくと、リモートデバッグが有効になります。
なおプログラムの変更点は、プレビューで確認できます。OKであれば、発行をクリックして発行します。
まとめは以下の通りです。
以上です。ぜひ皆様もやってみて下さい。これだけでバックエンド作成は終了です。
ここまでのコードは、こちらにありますので、ぜひご利用ください。
次は、クライアントアプリケーションとしての Windows ストアアプリ側のコードの解説です。
鈴木 章太郎