Azure Web Sites
Node.js と MongoDB で Web サービスをビルドする
クラウドではどのような言語でも利用できます。クラウドでは、実行するアプリが Node.js、ASP.NET、Java、PHP のいずれであっても問題ありません。クラウドにはあらゆるアプリを実行するためのインフラストラクチャが標準で備わっています。クラウドの信条はアジリティです。このアジリティがあるから、新しいアイデアをすぐに実装することも、マーケットプレイスで人気のないアプリの掲載を取りやめることも可能になります。近年、非同期プログラミングのパラダイムを好む新しい開発者グループの間で、Node.js が普及しています。Node.js は、クライアントやサーバーのアプリケーションをビルドするための JavaScript ランタイム エンジンです。このランタイム エンジンに、CPU やメモリのオーバーヘッドを最小限に抑えて、シングル スレッドで多数の同時接続を処理できるようにする非同期 I/O フレームワークが含まれています。Node.js は、Web 開発フレームワークだと思われがちですが、実際には、JavaScript コードを実行するためのシングル スレッド ランタイム エンジンです。Node.js はモジュール ベースのアーキテクチャになっているため、Web 開発や MongoDB データベースへのアクセスなどの特定のタスクを処理するモジュールを自由にビルドして公開することができます。たとえば、Express テンプレート エンジンは、モジュールとして Node.js にダウンロードできる Web アプリケーション フレームワークです。コアとなる Node.js エンジンは、Chrome ブラウザー用に設計された Google V8 JavaScript エンジンを基盤として C++ でビルドされています。 Node.js は Microsoft Azure Web Sites でサポートされます。また、マイクロソフトは、Azure API を使ってプログラミングするための開発ツールやネイティブ SDK も提供しています。Azure ポータルには、Node.js 専用のデベロッパー センター (https://azure.microsoft.com/ja-jp/develop/nodejs/) があります。
今回は、クラウド上にある MongoDB データベースにアクセスする RESTful Web サービスを Node.js で開発する方法と、作成したサービスを Azure Web Sites に配置する方法について説明します。
Node.js の基本は非同期開発モデルです。つまり、すべてのメソッド呼び出しには、応答を受け取るためのコールバックが必要になります。これまでの .NET 開発者は同期方式 (要求 - 応答) の呼び出しを好む傾向がありますが、以前から Microsoft .NET Framework には非同期機能も存在していました。.NET Framework に新しい async-await プログラミング モデルが含まれるようになったため、Web やモバイルのアプリケーションでも非同期アプリケーションが標準になりました。非同期プログラミングでは、呼び出し側の関数でコールバック イベントをサブスクライブし、応答を処理するデリゲートを指定します。コールバック関数は処理完了時に呼び出されます。同期処理が電話だとすると、非同期処理は電子メールのようなものです。
次のコードは、呼び出されたときに文字列を返すシンプルな Node.js Web サーバーを示します。
var http = require("http");
http.createServer(function(request, response) {
response.writeHead(200, {"Content-Type":
"text/plain"});
response.write("Hello MSDN");
response.end();
}).listen(8080);
response 関数は、HTTP 要求イベントが発生したときに呼び出されます。require 関数はモジュールを読み込むために使用します。これは、.NET Framework でアセンブリから名前空間を読み込むのに似ています。
ASP.NET と Node.js について多くの議論が交わされていますが、ここではそのようなトピックは扱いません。常に、作業に最も適したツールを使うというのが私の流儀です。最高のパフォーマンスを引き出すには、この手法がお勧めです。
Node.js の要求処理
図 1 に示すように、Node.js エンジンは、クライアントからの同時接続を処理するためにシングル スレッドを開始します。このシングル スレッドの初期化が既に完了しているときは、要求の数が増えても処理に必要な初期化のオーバーヘッドは生じません。これは、このシングル スレッドが要求を即座にワーカー スレッドにデリゲートして非同期に処理を行うためです。
図 1 Node.js の "要求 - 応答" オーケストレーション
データベース アクセスや Web サービス呼び出しなど、実行時間がかかるタスクや I/O を集中的に行うタスクが HTTP 要求に含まれている場合、このような要求は、非ブロッキング ワーカー スレッドで非同期に処理されます。実行時間がかかるタスクが完了すると、結果が非ブロッキング ワーカー スレッドからメイン スレッドへコールバックとして返されます。続いて、その結果がメイン スレッドからクライアントに返されます。ここで理解しておくべき重要な考え方は、処理をワーカー スレッドにデリゲートすることで、要求を受信するシングル スレッドは常に要求を受け取れる状態になっていて、ビジー状態にはならないことです。
Node.js の主要コンポーネント
Node.js は以下の 2 つの主要コンポーネントで構成されます。
コア/カーネル: Node.js のカーネルは Google V8 JavaScript エンジンを基盤として C++ で作成されています。コア自体はシングル スレッドで、複数の CPU への負荷分散が可能です。Node.js はオープン ソースなので、github.com/joyent/node (英語) からソース コードを入手できます。
モジュール: モジュールは .NET Framework の NuGet パッケージと似ています。Node.js Package Manager (NPM) は、自分の開発環境で Node.js パッケージを管理するためのツールです。モジュールは、タスクの I/O 処理の頻度に応じて新しいプロセスまたはスレッドを開始します。よく使われるモジュールには HTTP、MongoDB、Express (Web テンプレート フレームワーク)、Socket.IO などがあります。このようなモジュールの一覧については、nodejsmodules.org (英語) を参照してください。
Node.js をローカルにインストールして実行する
Node.js Web サイトをクラウドで運用する前に、プラットフォームで快適に動作するのをローカルに試してみることをお勧めします。たった 3 つの手順だけで、Windows プラットフォームに Node.js をインストールして実行することができます。
- Node.js をダウンロードしてインストールする: Node.js の Windows インストーラーは、nodejs.org/#download (英語) からダウンロードしてインストールすることができます。ダウンロードしたインストーラーによって、Node.js ランタイムと NPM がインストールされます。
- 簡単なサーバーを作成する: Node.js で HTTP サーバーを作成するには、テキスト エディターを開いて 図 1 のコードをコピーしてから、そのテキスト ファイルを webserver.js という名前で保存します。前述のコードを使用すると、ポート 8080 をリッスンしてすべての要求に同じ文字列を返す、必要最小限の Web サーバーを作成できます。
- HTTP サーバーを実行する: 最後に、コマンド プロンプトを開き、webserver.js ファイルを保存したフォルダーに移動し、次のコマンドを入力してサーバーを実行します。
>“C:\Program Files\nodejs\node.exe” webserver.js - このコマンドは Web サーバーを起動します。ブラウザーで http://localhost:8080 に移動して、この Web サーバーをテストできます。このような簡単なサーバーでも、Web サイトを開発する際のオプションとして Node.js を試す十分な価値があります。
Azure Web Sites で Node.js を運用する
Node.js を初めて使用したとき、できるだけコマンドラインを使用しないようにしました。Visual Studio での開発経験があったので、IDE を使用することで得られる生産性が重要だと感じています。さいわい、マイクロソフトは、Windows で Node.js アプリケーションを開発するための強力なツールとして、WebMatrix を用意しています。また、Visual Studio チームは、Visual Studio 用の Node.js ツールをリリースしました (nodejstools.codeplex.com、英語参照)。ここからは、主要開発ツールとして WebMatrix を使用します。WebMatrix では、NPM パッケージのインストール、Azure への Web サイトの発行、およびローカルでの Web サイトの実行が可能です。WebMatrix は、IIS で Node.js アプリケーションをホストできるようにする、IIS Express 用の IISNode もインストールします。IISNode の詳細については、github.com/tjanczuk/iisnode (英語) を参照してください。
完全な RESTful Web サービスをビルドする前に、WebMatrix から Azure にシンプルな Web サイトを発行する方法について説明します。
Azure Web Sites を新規作成する:図 2 に示すように、Azure ポータルを使用して、Azure Web Sites を新しく作成することができます。
図 2 Azure Web Sites の新規作成
ポータルでは、指定した地域に一意名を付けたサイトを新しく作成することができます。Web サイトやデータベースなどのサービスを同じデータセンターに共同配置する場合、地域が重要になります。データセンターから移動するデータには課金されます。
Express Web サイトを作成する: Express は Node.js 用の Web アプリケーション フレームワークです。Express はモデル ビュー コントローラー (MVC) パターンに従うため、Node.js MVC Web サイトおよび RESTful Web サービスをビルドする場合の道筋を立てることができます。Express は expressjs.com (英語) からダウンロードできます。
Visual Studio での .NET 開発に慣れている方は、Node.js アプリケーションを開発するために WebMatrix をマスターすることをお勧めします。WebMatrix 3 には、事前にビルド済みの便利な Express テンプレートが含まれています。WebMatrix 3 を開き、[新規]、[テンプレート ギャラリー] を順にクリックします。次に、Node.js カテゴリで、[Express サイト] テンプレートを選択します (図 3 参照)。
サイト名を指定し、[次に進む] をクリックして IISNode と Express サイト テンプレートをインストールします。
図 3 Express サイト テンプレート
Azure Web Sites のインフラストラクチャでは Web サイトの運用に IIS が必要になるため、作成した Node.js サーバーをそのまま Azure Web Sites で運用することはできません。そのため、Node.js Web サイトを運用するには、IIS と IISNode が提供する Node.js との統合が必要になります。
図 4 に、Express テンプレートによって作成されるファイル構造と、server.js のソースコードを示します。
図 4 Express ファイル構造
express モジュールと routes モジュールは自動的にインポートされます。これらのモジュールを使用して REST サービスをビルドします。
Web サイトをローカルに実行する: 前述の推奨事項に従い、WebMatrix の [実行] ボタンをクリックして、ローカル コンピューターで Web サイトをテストします。インストールが正常に完了すると、Express ホームページが表示されます。
Express テンプレートは、Jade テンプレート エンジンもインストールします。Jade は HTML テンプレート エンジンで、Express フレームワークから生成されるビューをビルドするために使用します。Jade と Express の関係は、Razor と ASP.NET MVC の関係と同じです。したがって、index.html のコンテンツは、/views/index.jade と /routes/index.js からレンダリングされます。これらのルートは、server.js の 16、17、および 30 行目で設定されます (図 4 参照)。Jade テンプレート エンジンの詳細については、jade-lang.com (英語) を参照してください。
Azure に Web サイトを発行する: Express を使用して Node.js Web サイトをローカルにビルドしたので、次は Azure に発行します。WebMatrix の [発行] ボタンをクリックして、発行手順を開始します。Web サイトの発行プロファイルをインポートし、発行ウィザードに従います (図 5 参照)。
図 5 Microsoft Azure への発行
すべてうまくいくと、WebMatrix によって Internet Explorer に Web サイトが読み込まれます。
ブラウザーの URLは、先ほどの Web サイト発行先の Azure Web Sites です。ここでは、Node.js Web サイトと Node.js Web サービスを開発して Azure に簡単に配置できることをデモしました。ここでは、MongoDB について簡単に説明します。その後、Node.js に戻って Web サービスのビルドを続けます。
MongoDB の概要
MongoDB はオープン ソースのデータベースで、スケーラビリティが高く、パフォーマンスに優れたドキュメント指向のデータベースです。MongoDB には、レプリケーション、共有、インデックス、フェールオーバーといった、リレーショナル データベースの機能の大半が含まれています。また、MongoDB は自動共有を提供し、今日の多くのリレーショナル データベースでは提供されていない Map-Reduce 処理機能が組み込まれています。リレーショナル データベースは、ストレージ システムが高価だった時代に設計されました。データをリレーショナル形式で保存することで、開発者は、ストレージ容量を最適化して、迅速にデータを取得できるようになります。しかし昨今では、ストレージのコストはコンピューティング コストに比べて安価になりました。クラウドでは、ストレージ価格が下落し続けています。そのため、データをリレーショナル形式で保存して取得する方法は、クラウドに保存するよりもコストがかかるようになりました。多くのアプリケーションがデータ ストレージからリアル タイムでのデータ取得を想定するようになり、継続的なデータ配信のニーズが高まっています。MongoDB では、オブジェクトやドキュメントをリレーショナル コンポーネントに分解することなく保存できます。これにより、アプリケーションやデータベースでの処理の負荷が減少します。
ただし、MongoDB はリレーショナル データベースのようにオブジェクトやデータのリレーションシップ リンクを管理して取得するように設計されていないため、オブジェクトとの密接なリレーションシップを必要とするアプリケーションには、MongoDB をお勧めしません。アプリケーションでの取得に密接なリレーションと SQL が必要な場合は、リレーショナル データベースを使用してください。アプリケーションからのオブジェクトの保存と取得に迅速さを求められる場合は MongoDB を使用します。前述の推奨事項のように、作業に最も適したツールを使用するようにします。
Azure での MongoDB のプロビジョニング
MongoDB は、Azure ストアでアドオンとして入手でき、サンドボックス バージョンは無償でインストールできます。Azure ポータルにログインし、[新規]、[ストア] を順にクリックして表示される [サービスの選択] メニューで、MongoDB (MongoLab) をインストールします (図 6 参照)。
図 6 MongoLab の MongoDB アドオン
[個人用サービス] のページでサンドボックス バージョンを選択し、Web サイトと同じ地域に MongoDB インスタンスをインストールします (図 7 参照)。
図 7 MongoDB の構成
インストールの完了後、[アドオン] ページに移動し、インストールしたデータベースの接続文字列を保存します (図 8 参照)。Node.js Web サービスから接続するのにこの接続文字列を使用します。
図 8 インストールしたデータベースの接続文字列
これで MongoDB を Azure で実行できるようになります。ObjectLabs 社によって運営されている MongoLab には独自の管理ポータルがあり、[アドオンの管理] リンクをクリックすると表示されます。
これで、クラウドで運用する MongoDB データベースが用意され、空の Node.js テンプレートも作成されています。アプリケーションを完成するには、MongoDB データベースにデータを設定し、このデータベースからデータを取得する Web サービスを作成する必要があります。これは、クラウドにおける標準のソフトウェア開発です。
MongoDB 接続に必要な Node.js コンポーネントのインストール
JSON は MongoDB でよく使用され、Node.js を補完します。Web サービスは MongoDB に接続するため、NPM ギャラリーから MongoDB 用の最新の Node.js ドライバーをインストールする必要があります (図 9 参照)。
図 9 MongoDB 用 Node.js ドライバー
MongoDB 接続情報は構成ファイルに保存されます。nconf モジュールにより、ファイルから構成情報を読み取ることができます (図 10 参照)。
図 10 nconf モジュール
mongodb モジュールと nconf モジュールのインストールが完了すると、Node.js と MongoDB の開発環境を設定するのに必要な前提条件がすべて満たされます。
REST Web サービスのシグネチャの作成
REST Web サービスを作成するには、まず、次のように server.js で依存関係とルートを定義します。
var express = require('express')
, routes = require('./routes')
, user = require('./routes/user')
, http = require('http')
, path = require('path'),
pkgs=require('./routes/pkgs');
次に、/routes/pkgs.js ファイルで REST の関数を定義します。これは、上記のコードで pkgs モジュールに関数処理をデリゲートしているためです。routes フォルダーに、Web サービスの操作を定義する pkgs.js という名前のファイルを作成します (図 11 参照)。
図 11 REST 操作のシグネチャ
exports.findAll = function(req, res) {
res.send([{name:'app1'}, {name:'app2'}, {name:'app3'}]);
};
exports.findById = function(req, res) {
res.send({id:req.params.id,
name: "DisplayName", description: "description"});
};
exports.addPkg = function (req, res) {
res.send("Success");
};
exports.updatePkg = function (req, res) {
res.send("Success");
};
操作の基本関数をテストするには、静的データを返す関数のスケルトンを作成するだけです。データベースにアクセスするコードは後から追加します。server.js では、次に示すように、先ほど作成したモジュールのメソッドに対応するルートのメソッドを定義します。
app.get('/pkgs', pkgs.findAll);
app.get('/pkgs/:id', pkgs.findById);
app.post('/pkgs', pkgs.addPkg);
app.put('/pkgs/:id', pkgs.updatePkg);
ASP.NET Web API を使い慣れている方は、これらのルートや適切な実装クラスへのマップについてすぐに理解することができるでしょう。ルートの宣言とマッピングにより、/pkgs への要求は pkgs.js 内のいずれかの関数にルーティングされます。Web サービス操作のシグネチャと定義を用意したら、Web サイトをローカルおよび Azure で実行することによって、ルートが適切に動作するかどうかをテストできます。テストする URL は、http://[Web site URL]/pkgs、http://[Web site URL]/pkgs/remote、http://[Web site Url]/pkgs/1 です。これらの URL から想定する値が返される場合、ルートは適切に機能していることになるため、MongoDB との統合に進みます。
REST Web サービス操作の実装
ここで、MongoDB に接続してデータを取得するための Web サービス操作を実装します。この実装は以下の 4 つの手順で実行できます。
- config.json ファイルを作成し、このファイルに MongoDB 接続文字列を保存する。
- MongoDB クライアントを初期化する。
- サンプル データを MongoDB に設定する。この手順では、関数から http://storage.appsforazure.com/appsforazureobjectstest/servicepackages.json への HTTP GET 呼び出しを行い、取得したデータを MongoDB インスタンスに保存します。
- MongoDB のデータを取得および保存するデータ アクセス関数を実装する。
config.json ファイルを作成する: config.json ファイルは .NET の app.config ファイルと同様の構成情報を保存する JSON 形式のファイルです。新規作成した config.json ファイルに名前と値のペアを追加します。
{
"MONGOLAB_URI" :
"mongodb://nodeapps:xxxxxxxx.f.migd9GGB9Ck3M17jlkVCUVI-@ds027758.
mongolab.com:27758/nodeapps"
}
値は、先ほど Azure ポータルで保存した MongoDB 接続文字列です。
pkgs.js では、nconf モジュールをインポートして構成値を読み取る必要があります。
var nconf = require('nconf');
nconf.env().file({ file: 'config.json' });
var connectionString = nconf.get("MONGOLAB_URI");
これにより、関数では connectionString 変数を使用して MongoDB データベースに接続できるようになります。pkgs.js で connectionString をグローバル変数として宣言することで、すべての関数から connectionString にアクセスできるようにしています。
MongoDB クライアントを初期化する: MongoDB データベースへの接続を初期化するには、mongodb モジュールをインポートし、connect メソッドを呼び出す必要があります (図 12 参照)。
図 12 MongoDB データベースへの接続
var mongo = require('mongodb');
var MongoClient = mongo.MongoClient
MongoClient.connect(connectionString, function (err, db) {
if (err) throw err;
if (!err) {
console.log("Connected to 'pkgsdb' database");
db.collection('pkgs', { strict: true },
function (err, collection) {
if (err) {
console.log(
"The 'pkgsdb' collection doesn't exist.
Creating it with sample data...");
populateDB(db);
}
});
}
})
接続に成功したら、図 12 の db 変数にデータベース接続オブジェクトが設定されます。db.collection 関数は、pkgs という名前のコレクションへの接続を試みます。pkgs コレクションが存在しなければ、populateDB 関数を呼び出して新しい pkgs コレクションを作成します。ただし、実際のアプリケーションでは、アプリケーションを実行する前に pkgs コレクションが作成されるため、このようにする必要はありません (MongoDB のコレクションとは関連するドキュメントのグループで、リレーショナル データベース システムのデータベース テーブルのようなものです)。
サンプル データを MongoDB に設定する: 今回は、ソフトウェア パッケージのコレクションとして利用できる dynamicdeploy.com (英語) のサンプル データを使用します。populateDB 関数では、このコレクションを http://storage.appsforazure.com/appsforazureobjectstest/servicepackages.json から JSON 形式で読み込んでいます (図 13 参照)。
図 13 データベースの設定
var populateDB = function (db) {
var body = "";
var url =
"http://storage.appsforazure.com/appsforazureobjectstest/servicepackages.json";
http.get(url, function (res2) {
res2.on('data', function (chunk) {
body += chunk;
});
res2.on("end", function () {
var pkgs = JSON.parse(body)
db.collection('pkgs', function (err, collection) {
collection.insert(pkgs, { safe: true },
function (err, result) { });
});
});
res2.on("error", function (error) {
// You can log here further
})
});
JSON は Node.js の標準形式なので、JSON オブジェクトを解析するためのモジュールをインポートする必要はありません。collection.insert 関数は、JSON ドキュメント (var pkgs) 全体を MongoDB コレクションに挿入します。MongoDB は、実行時にオブジェクトのスキーマを判断し、オブジェクトを保存に必要な決定を行います。リレーショナル データベースでは、テーブルにデータを保存する前に、テーブルのスキーマを定義しなければなりません。コレクションには、JSON オブジェクトのプロパティを単純に変更するだけで実行時にスキーマを修正できる柔軟性があります。オブジェクトのプロパティが変更されていると、MongoDB はオブジェクトを保存する前にその変更を自動的にスキーマに適用します。これは、データの種類の変化に応じて動的に変化するソーシャル フィードやモノのインターネットのフィードなどのアプリケーションをビルドする場合に役立ちます。
データ アクセス関数を実装する: 最後に、先ほど宣言した HTTP GET、POST、および PUT 関数用のデータ アクセス関数を実装する必要があります。HTTP GET 関数は、Web サービスの findById 関数と findAll 関数にマップします (図 14 参照)。
図 14 Find 関数
exports.findById = function (req, res) {
var id = req.params.id;
console.log('Retrieving pkg: ' + id);
MongoClient.connect(connectionString, function (err, db) {
if (err) throw err;
if (!err) {
db.collection('pkgs', function (err, collection) {
collection.findOne({ '_id': new BSON.ObjectID(id) },
function (err, item) {
res.send(item);
});
});
}
})
};
exports.findAll = function(req, res) {
MongoClient.connect(connectionString, function(err, db) {
if(err) throw err;
if(!err) {
db.collection('pkgs', function(err, collection) {
collection.find().toArray(function(err, items) {
res.send(items);
});
});
}
})
};
findById 関数は、Id を指定してオブジェクトを取得するのに対して、findAll 関数はすべてのオブジェクトを取得します。collection.findOne 関数と collection.find 関数は、操作の結果を MongoDB からそれぞれ取得します。同様に、図 15 に、HTTP POST にマップする addPkg メソッドと、HTTP PUT にマップする updatePkg メソッドを示します。
図 15 Add 関数と Update 関数
exports.addPkg = function (req, res) {
var pkg = req.body;
console.log('Adding pkgs: ' + JSON.stringify(pkg));
MongoClient.connect(connectionString, function (err, db) {
if (err) throw err;
if (!err) {
db.collection('pkgs', function (err, collection) {
collection.insert(pkg, { safe: true }, function (err, result) {
if (err) {
res.send({ 'error': 'An error has occurred' });
} else {
console.log('Success: ' + JSON.stringify(result[0]));
res.send(result[0]);
}
});
});
}
})
};
exports.updatePkg = function (req, res) {
var id = req.params.id;
var pkg = req.body;
console.log('Updating pkgs: ' + id);
console.log(JSON.stringify(pkg));
MongoClient.connect(connectionString, function (err, db) {
if (err) throw err;
if (!err) {
db.collection('pkgs', function (err, collection) {
collection.update({ '_id': new BSON.ObjectID(id) },
pkg, { safe: true }, function (err, result) {
if (err) {
console.log('Error updating pkg: ' + err);
res.send({ 'error': 'An error has occurred' });
} else {
console.log('' + result + ' document(s) updated');
res.send(pkg);
}
});
});
}
})
};
ここまでくれば、delete 関数は自分で実装できるでしょう。これについては皆さんの課題に残しておきます。まず Web サイトを保存と実行をローカルに行った後、Azure Web Sites に発行して、各 REST 関数をテストします。REST Web サービスの完全なソース コードと Web サイトは、github.com/dynamicdeploy/appsforazure (英語) から入手できます。
エンド ツー エンドのアプリケーションを実行すると、ユーザーの負荷に応じて MongoDB インフラストラクチャ (サービス) をスケール アウトすることができます。今回のデモで示したように、Azure で大規模な Node.js や MongoDB Web サイトを配置するためのインフラストラクチャは必要ありません。付属のソース コードで提供したスケルトンを使用すると、Azure Web Sites で Node.js の Web サービスや Web サイトのビルドに着手することができます。
まとめ
今回の目的は、Azure Web Sites で Node.js を使用して Web サービスを快適にビルドできるようにすることでした。Node.js と MongoDB は互いに補完し合い、どちらもサービスとしてのプラットフォーム (PaaS) として利用できるため、インフラストラクチャに投資する必要がなく、完全な Web サイトのビルドや動的なスケーリングが可能になります。開発者は、クラウド上に Web サービスをビルドしてモバイル アプリで利用できるようにすることに専念することができます。したがって、Azure Web Sites は PaaS として正しく機能すると確信しています。
Tejaswi Redkar は、執筆者兼ソフトウェア開発者です。現在は、マイクロソフトのアプリケーション プラットフォーム戦略およびコミュニティのディレクターとして働いています。彼の著書『Windows Azure Web Sites: Building Web Apps at a Rapid Pace』(Dynamic Deploy LLC、2013 年) は、このトピックに関する最も総合的な内容の書籍としてベストセラーになっています。Redkar は、appsforazure Windows ストア アプリと dynamicdeploy.com (英語) の作成者です。この作成過程で、運用アプリをクラウドで直接実行することを経験しました。連絡先は、tejaswi_redkar@hotmail.com (英語のみ) です。Twitter は twitter.com/tejaswiredkar (英語) でフォローできます。
この記事のレビューに協力してくれた Microsoft Azure 製品管理チームの技術スタッフに心より感謝いたします。