ローカル用 Azure DocumentDB エミュレーターを使った NoSQL .NET Core の開発作業


 

本記事は、マイクロソフト本社の SCOTT HANSELMAN の記事を抄訳したものです。
【元記事】 NoSQL .NET Core development using an local Azure DocumentDB Emulator 2016/12/4

 

数週間前、Miguel de Icaza とニューヨークの街を歩いていると、彼が今とても気に入っている NoSQL データベース Azure DocumentDB について話をしてくれました。私も昨年あたりからなかなかよさそうな製品だとは感じていたのですが、次の理由から使うまでには至っていませんでした。

  • ローカルで開発作業ができない – 私は低帯域幅の環境や飛行機の中でよく作業をするので向いていない。
  • MongoDB がサポートされていない – Mongo を使用する Node で書かれたアプリを扱うことがあるので向いていない。
  • .NET Core がサポートされていない – 私が行う作業のほとんどはクロス プラットフォームの .NET Core アプリなので向いていない。

しかし Miguel からは、この製品のことをもっとよく知るべきだとアドバイスされました。以前とは状況が変わり、今の DocumentDB は次のようになったそうです。

  • ローカル用 DocumentDB エミュレーターが無料に (英語) – Miguel に「Azure で実行されるコードから、永続化されているローカル ファイル システムを使用するよう変更するだけで他はまったく変更しなくてよいのか」と質問したところ、「これは『エミュレーター』だが原則的に同じコア エンジン コードだ」という答えをもらいました。このローカル用 DocumentDB エミュレーターは無料で、サインインする必要もありません。
  • MongoDB プロトコルをサポート – これには驚きました。既存の Node アプリを取り込み、MongoChef をダウンロードし、標準の MongoDB 接続文字列を使用してアプリ群を Azure にコピーし、アプリを DocumentDB で指定したところ、正常に動作しました。このケースでは DocumentDB をストレージとして使用しています。これには次のようなメリットがあります。
    • レイテンシの短縮
    • 世界規模の geo レプリケーションをそのまま使用できる (数クリックで実行可能)
    • SLA (サービス レベル アグリーメント) で、読み込み 10 ミリ秒未満、書き込み 15 ミリ秒未満のパフォーマンスを保証
    • 他の Azure サービスと同様にメトリックやリソース管理が可能
  • .NET Framework SDK と同等の機能を持つ DocumentDB の .NET Core Preview SDK (英語)

また、DocumentDB 用 SDK が Node、.NET、Python、Java、C++ の各言語で用意されているため、Unity でのゲーム開発、Web アプリ、iOS 用や Android 用の Xamarin モバイル アプリなどあらゆる .NET アプリでの使用に適しています。Miguel は特にこの点を気に入っています。

AZURE DOCUMENTDB をローカルで使用するためのクイック スタート ガイド

ここでは、Azure DocumentDB をすぐに使用開始するための方法を説明したいと思います。私は先日 Azure Friday でこのプロジェクトの PM に話を聞き (英語)、さっそくローカル用エミュレーターのダウンロードとインストールを行いました。彼の話によると、現時点では Windows 用ですが将来的にはクロス プラットフォーム ソリューションへの発展を予定しているとのことでした。エミュレーターをインストールすると、Web ブラウザーが開いてローカル Web ページが表示されました。他の開発ツールもこのように手軽にスタートできるとよいものです。他にも、ASP.NET MVC で DocumentDB の使用を開始するためのクイック スタート ガイドもあるのでチェックしてみてください。

: 今回のリリースはバージョン 0.1.0 で、アルファ版です。このため、同梱のサンプルではパッケージ名が異なっている場所があるなど、一貫していません。”Microsoft.Azure.Documents.Client”: “0.1.0” は “Microsoft.Azure.DocumentDB.Core”: “0.1.0-preview” に変更する必要がありました。このようにちょっとした問題に注意する必要があります。これで正常に動作するようになるはずです。

Nice DocumentDB Quick Start

このサンプル アプリは、一般的な “ToDo” アプリです。

ASP.NET MVC ToDo App using Azure Document DB local emulator

ローカル用エミュレーターには Web ベースのローカル データ エクスプローラーも含まれています。

image

ToDo の項目は、下記のような単純な POCO (Plain Old CLR Object) です。

namespace todo.Models
{
using Newtonsoft.Json;

public class Item
{
[JsonProperty(PropertyName = "id")]
public string Id { get; set; }

[JsonProperty(PropertyName = "name")]
public string Name { get; set; }

[JsonProperty(PropertyName = "description")]
public string Description { get; set; }

[JsonProperty(PropertyName = "isComplete")]
public bool Completed { get; set; }
}
}

サンプル内の MVC コントローラーでは基盤となるリポジトリ パターンが使用されているため、この階層では下記のようにコードがとてもシンプルです。

[ActionName("Index")]
public async Task<IActionResult> Index()
{
var items = await DocumentDBRepository<Item>.GetItemsAsync(d => !d.Completed);
return View(items);
}
 
[HttpPost]
[ActionName("Create")]
[ValidateAntiForgeryToken]
public async Task<ActionResult> CreateAsync([Bind("Id,Name,Description,Completed")] Item item)
{
if (ModelState.IsValid)
{
await DocumentDBRepository<Item>.CreateItemAsync(item);
return RedirectToAction("Index");
}
 
return View(item);
}

リポジトリ自体は抽象化されていて、複雑なことはありません。コードの長さは 120 行ほどで、空行や中括弧だけの行を除けば実質 60 行程度で、そのうちの約半分は初期化とセットアップです。DocumentDBRepository<T> も含まれているため汎用的で、必要に応じて自由に変更して使用することができます。

このサンプルで唯一目立つところは GetItemsAsync のループで、ページングやチャンクに利用できる可能性があります。述語で渡すことができるのはよいですが、大規模なコレクション向けに何らかのページング ロジックを実装したいと思います。

public static async Task<T> GetItemAsync(string id)
{
try
{
Document document = await client.ReadDocumentAsync(UriFactory.CreateDocumentUri(DatabaseId, CollectionId, id));
return (T)(dynamic)document;
}
catch (DocumentClientException e)
{
if (e.StatusCode == System.Net.HttpStatusCode.NotFound){
return null;
}
else {
throw;
}
}
}
 
public static async Task<IEnumerable<T>> GetItemsAsync(Expression<Func<T, bool>> predicate)
{
IDocumentQuery<T> query = client.CreateDocumentQuery<T>(
UriFactory.CreateDocumentCollectionUri(DatabaseId, CollectionId),
new FeedOptions { MaxItemCount = -1 })
.Where(predicate)
.AsDocumentQuery();
 
List<T> results = new List<T>();
while (query.HasMoreResults){
results.AddRange(await query.ExecuteNextAsync<T>());
}
 
return results;
}
 
public static async Task<Document> CreateItemAsync(T item)
{
return await client.CreateDocumentAsync(UriFactory.CreateDocumentCollectionUri(DatabaseId, CollectionId), item);
}
 
public static async Task<Document> UpdateItemAsync(string id, T item)
{
return await client.ReplaceDocumentAsync(UriFactory.CreateDocumentUri(DatabaseId, CollectionId, id), item);
}
 
public static async Task DeleteItemAsync(string id)
{
await client.DeleteDocumentAsync(UriFactory.CreateDocumentUri(DatabaseId, CollectionId, id));
}

今後もしばらくこの機能を試してみようと思っていますが、飛行機でも使用できるので今のところそれで十分ハッピーです。ただオブジェクトを渡して保存するだけなのでとても簡単です (最近は SQL よりも NoSQL がお気に入りですが)。

今後は、.NET Core で動く優秀なオープン ソース NoSQL ドキュメント データベース RavenDB に関する記事 (英語) も公開予定ですので、どうぞご期待ください。


筆者紹介

Scott Hanselman は、大学教授と金融会社のチーフ アーキテクトという職歴を経て、現在はマイクロソフトに勤務する傍ら、講演やコンサルティング活動を行っています。父親であり、糖尿病と戦っているほか、漫才師のなり損ない、コーンロウ ヘアーのスタイリスト、著者という肩書きも持っています。
Comments (0)

Skip to main content