スマホ×Windows Azure開発講座(Windows Phone編)

第3回Windows Azure上にRESTサービスの構築

はじめに

今回から数回にわたって合わせて1つのスマホ×Azureなアプリケーションになるような簡単なサンプルアプリケーションを構築していきます。連載第3回の今回はWindows AzureでRESTアクセス可能なWebサービスを構築していきたいと思います。

プロジェクトの作成

それではWindows Azureアプリケーションの開発の基となる「プロジェクト」を作成していきます。Visual Studioを起動し、スタートページが表示されている状態で、ファイル>新規作成>プロジェクトを選択します。⁠新しいプロジェクト」ダイアログが表示されるので、テンプレートとしてCloudカテゴリーを開き、⁠Windows Azure Project」を選択します。

次に、プロジェクトの名前(と必要であれば場所)を指定します。ここでは下記の名前にしています図1⁠。

  • プロジェクト名:GihyoAzureSampleGame01
図1 プロジェクトの作成
図1 プロジェクトの作成

OKボタンをクリックすると、⁠New Windows Azure Project」ダイアログが開きます。今回はWebロールのアプリケーションを構築するので下記設定のプロジェクトを追加することにします図2、図3⁠。

  • プロジェクトのタイプ:ASP.NET Web Role
  • プロジェクトの名前:GameWebRole

左のペインでASP.NET Web Roleを選んで「>」ボタンをクリック後、右ペインでプロジェクト名を編集することができるようになるので、編集しておきます。

図2 ASP.NET Web Roleというプロジェクトタイプを選択
図2 ASP.NET Web Roleというプロジェクトタイプを選択
図3 GameWebRoleという名前で作成
図3 GameWebRoleという名前で作成

2つのプロジェクトを作成しましたが、最初のWindows Azure Projectを作成した際に、同名の「ソリューション」も作成されます。これはプロジェクトの入れ物で、後で追加したWebロールのプロジェクトと併せては2つのプロジェクトでソリューションが構成されることになります。

RESTサービスの作成

次に、RESTサービスの実装を行っていきます。今回は下記シナリオを実現するWebサービスを作成します。

  • カードを引く
  • カードの一覧を取得する

今回は上記を簡略化して、1から10までの乱数を引く、その乱数の一覧を取得するWebサービスを作成します。また、実装に関しては作成された2つのプロジェクトのうちのGameWebRoleプロジェクトに対して行っていきます。

参照の追加まずは開発に必要なアセンブリ(コードライブラリ)への参照を追加していきます。「参照設定」を右クリックし、「参照の追加」をクリックします。そこで下記4つの参照を追加します図4)。
  • System.Runtime.Serialization
  • System.ServiceModel
  • System.ServiceModel.Activation
  • System.ServiceModel.Web
図4 参照の追加
図4 参照の追加

System.ServiceModel名前空間のクラスはWebサービスを開発する際に必要なライブラリです。

エンティティクラスの作成

次に、Webサービスの通信インターフェースであるエンティティクラスを作成します。DTO(Data Transfer Object)とも呼ばれるクラスになります。2つのクラスを作成します。それぞれ一覧取得処理のインターフェースとして利用します。一覧取得時にリクエストパラメータがないのでリクエストDTOの中身は空、レスポンスDTOはカードの一覧(今回は乱数の一覧)を保持するリストを持っているものとします。また、クラスはGameWebRoleプロジェクト直下に「Model」フォルダを作成して、その下に作るものとします。Modelフォルダを右クリックし、追加>クラスで作成していってください。

GameServiceRequest.cs
using System.Runtime.Serialization;
namespace GameWebRole.Model
{
    [DataContract]
    public class GameServiceRequest
    {
    }
}
GameServiceResponse.cs
using System.Collections.Generic;
using System.Runtime.Serialization;
 
namespace GameWebRole.Model
{
    [DataContract]
    public class GameServiceResponse
    {
        [DataMember(Name = "cardList")]
        public List CardList { get; set; }
    }
}

ポイントは[DataContract]属性をクラスに付加している部分です。これを付けておくと、通信時に適切にXMLやJSONフォーマットにデータが変換されるようになります。同様に[DataMember]属性は指定したプロパティがXMLやJSONに変換されるべきで、その際に指定した名前で変換するように指定しています。

サービスインターフェースの作成

次にサービスインターフェースを作成します。GameWebRoleプロジェクト直下にServiceフォルダを作成してその下に作成します。

IGameService.cs
using System.ServiceModel;
using System.ServiceModel.Web;
using GameWebRole.Model;
 
namespace GameWebRole.Service
{
    [ServiceContract]
    public interface IGameService
    {
        [OperationContract]
        [WebGet(ResponseFormat = WebMessageFormat.Json, UriTemplate = "getcard")]
        int GetCard();
 
        [OperationContract]
        [WebInvoke(Method = "POST", 
            RequestFormat = WebMessageFormat.Json, 
            ResponseFormat = WebMessageFormat.Json, 
            UriTemplate = "getcardlist")]
        GameServiceResponse GetCardList(GameServiceRequest request);
    }
}

今回はGETリクエストでGetCardメソッドを、POSTリクエストでGetCardListメソッドを実装する事にします。クラスには[ServiceContract]属性を、各サービスメソッドに対しては[OperationContract]属性を指定して、Webサービスとして呼び出せますよという事を宣言しています。それぞれのメソッドではWebGet属性、WebInvoke属性を指定する事によって、RESTプログラミングモデルに従ったサービスオペレーションである事を宣言しています。引数としてリクエスト、レスポンスのフォーマットをJSONとし、クライアントから呼び出される際のURLのフォーマットも同時に定義しています。GetCardListメソッドに関してはリクエストとレスポンスのインターフェースとして先ほど作成したDTOを利用しています。

サービスの実装

サービスの実装は以下のようになります。

GameService.cs
using System.Collections.Generic;
using System.ServiceModel.Activation;
using GameWebRole.Data;
using GameWebRole.Model;
 
namespace GameWebRole.Service
{
    [AspNetCompatibilityRequirements(RequirementsMode = 
AspNetCompatibilityRequirementsMode.Required)]
    public class GameService:IGameService
    {
        public int GetCard()
        {
            int newCardNumber = DataHelper.GetCard(); 
            DataHelper.SaveCard(newCardNumber);
 
            return newCardNumber;
        }
 
        public GameServiceResponse GetCardList(GameServiceRequest request)
        {
            GameServiceResponse response = new GameServiceResponse(); 
            List cardList = DataHelper.SelectCard();
            response.CardList = cardList; 
            return response;
        }
    }
}

クラス宣言に付加されているAspNetCompatibilityRequirements属性はASP.NET互換性を宣言するものです。後述のASP.NETの機能を利用するために必要になります。実装はDataHelperクラスを介してカード(乱数)の取得、カード(乱数)の保存、カード一覧(乱数一覧)の取得を行っています。

データ処理周りは今回はDataHelperクラスにまとめてあります。DataHelperクラスはDataフォルダを作り、その直下に作成します。コードは下記のようになります。

DataHelper.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
 
namespace GameWebRole.Data
{
    public class DataHelper
    {
        private static List CardList;
 
        public static int GetCard()
        {
            Random random = new Random(); 
            int newCardNumber = random.Next(1, 10); 
            return newCardNumber;
        }
 
        public static void SaveCard(int newCardNumber)
        {
            if (CardList == null)
            {
                CardList = new List();
            }
 
            CardList.Add(newCardNumber);
        }
        
        public static List SelectCard()
        {
            List returnValue = new List();
 
            if (CardList != null)
            {
                var orderdCardList = from card in CardList
                                     orderby card ascending
                                     select card;
 
                returnValue = orderdCardList.ToList();
            }
 
            return returnValue;
        }
    }
}

今回はデータベース(KVSであるTableやRDBであるSQL Azure)を利用しないので、メモリ内で引いたカード(乱数)を保持する形にします。カード一覧を取得するSelectCardメソッドではLINQを用いてデータをソートしています。

設定

最後に作成したWebサービスをhttp://xxx.xxx.xxx/GameServiceというURLでアクセスできるように設定しておきます。Global.aspxファイルを開き、Application_Startメソッド内に下記コードを記述します。

Global.aspx.cs
        void Application_Start(object sender, EventArgs e)
        {
            ServiceRoute gameServiceRoute = new ServiceRoute("GameService", 
new WebServiceHostFactory(), typeof(GameService));
            RouteTable.Routes.Add(gameServiceRoute);
        }

ローカルでの実行

実装が終わったら、F5キーでデバッグ実行します。Windows Azure Compute Emulatorが起動し、作成したGihyoAzureSampleGame01のGameWebRoleがデプロイされ、アプリケーションが実行されます。また、ブラウザが起動し、ホームページが表示されます図5⁠。

図5 デバッグ実行
図5 デバッグ実行

今回作成したのはRESTアクセスが可能なWebサービスなので、ブラウザでGETリクエスト可能な処理の方を呼び出してみます。ブラウザでhttp://127.0.0.1:81/GameService/getcardにアクセスすると画面に数字が表示されます。再読み込みのたびに数字が変更されます。その都度サーバのメモリ上で乱数が保存されています。

POSTアクセスが必要なgetcardlistメソッドのテストに関しては、次回のWindows Phoneクライアント実装編で取り上げることにします。

今回紹介したサンプルコードはこちらからダウンロードできます。

最後に

今回はシンプルなWebサービスをWindows AzureのWebロール上に構築してみました。次回は今回作成したアプリケーションをAzureにデプロイ(アップロード)してみたいと思います。

※毎度のお勧め情報になりますが、Windows Azureプラットフォームは無料で試すことが可能です。また、MSDNサブスクリプション会員であれば、かなりの枠を無料で利用可能です。これを機に試してみてはいかがでしょうか。

おすすめ記事

記事・ニュース一覧