RESTful HTTPサービス開発を実践!ASP.NET Web API徹底解剖

この記事を読むのに必要な時間:およそ 3 分

ASP.NET 4.5で実装されたフレームワークには,RESTfulなHTTPサービスを構築できるASP.NET Web APIが含まれています。ここでは,このフレームワークの特徴を,実際のコードとともにご紹介します。

HTTPの仕様に準じたフレームワーク

ASP.NET Web APIは,Web標準――URI,HTTPに準じたHTTPサービスを構築するためのフレームワークです。公開されたAPIはHTTP通信で利用できるため,PCブラウザ(JavaScript)⁠iOS・Android・タブレット等,多種多様なクライアントとともにアプリケーションを提供することができます。

実装の中心:エンドポイントの定義

まずは,APIの実装の中心となる場所,エンドポイントをご覧ください。

ASP.NET Web APIでは,リスト1のように定義します。

リスト1 顧客APIのエンドポイント

public class CustomerController : ApiController
{
    // GET api/customer
    public IEnumerable GetAll()
    {
        // すべてのCustomerを返す処理
        throw new NotImplementedException();
    }

    // GET api/customer/5
    public Customer GetCustomerById(int id)
    {
        // Idと一致するCustomerを返す処理
        throw new NotImplementedException();
    }
        
    // POST api/customer
    public void PostCustomer(Customer newCustomer)
    {
        // 新しくCustomerを作成する処理
        throw new NotImplementedException();
    }
}

このコードは,顧客APIを提供する例になります。

「HTTPメソッド:GET,URL:~/api/customer」でアクセスされたときは,GetAllメソッドが,⁠HTTPメソッド:POST,URL:~/api/customer」でアクセスされたときは,PostCustomerメソッドが呼び出されます。

このように,ApiControllerクラスを継承したクラスに,publicメソッドを定義することでAPIのエンドポイントを定義することができます。

ここでは,このエンドポイントについて2つの特徴をご紹介します。

メソッド名

1つは,呼び出されるメソッドは,メソッド名がリクエストされたHTTPメソッドから始まる(GetやPostから始まる)ものだということです。これは,⁠規約は設定に勝る」のコンセプトによるデフォルトの動作です。

もちろん,メソッド名を任意に変更することもできます。たとえば,メソッド名をPostCustomerではなくCreateにしたい場合は,以下の様に属性を付与することで呼び出しが可能になります。

リスト2 Httpメソッド属性の付与

// POST api/customer
[HttpPost]
public void Create(Customer newCustomer)

リクエストとレスポンス

2つ目の特徴は,リクエストの値はメソッドの引数で,レスポンスの値はメソッドの戻り値として,実際のHTTP通信に依存しないオブジェクトを定義できる点です。

レスポンスから見ていきましょう。

GetAllメソッドの戻り値はIEnumerable<Customer>,PostCustomerメソッドの戻り値はvoidを定義しています。このとき,実際のHTTPレスポンスは,表1のように構築されクライアントへ返されます。

表1 実際のHTTPレスポンス

メソッドの戻り値の例HTTPレスポンス(ステータスコード Body) 
IEnumerable<Customer>, Customer200 OK戻り値の値をJsonやXml等にシリアライズされたもの
void204 No Contentなし

ですが,状況によっては,エラーを表すステータスコードや,リソースが見つからないことを表すステータスコードを返したい場合もあります。

その場合は,リスト3のように例外を吐き出すことで可能になります。

リスト3 404 NotFoundを返すコードの例

// GET api/customer/5
public Customer GetCustomerById(int id)
{
    // ...データが見つからなかった場合
    throw new HttpResponseException(HttpStatusCode.NotFound);
}

次はリクエストを見てみましょう。

GetCustomerByIdメソッドの引数はint型のid,PostCustomerメソッドの引数はCustomerオブジェクトを定義しています。

デフォルトでは,表2のようにHTTPリクエストの値が代入された状態でメソッドが呼び出されます。

表2

メソッドの引数の例代入されるHTTPリクエストの値
int,string,DateTime等のプリミティブ型QueryStringの値,URLの一部の値
例のCustomerクラスの様な複合オブジェクトBodyの値(Json,XML,URLエンコードデータ等)

もちろん,この他にも画像データやCSV,HTTPヘッダの値等,さまざまなHTTPリクエストの値を,任意のオブジェクトに代入するよう定義することができます。⁠詳細は後述の「様々なメディアタイプへの対応」をご参照ください)⁠

以上,実装の中心になるエンドポイントについてご紹介しました。

この後は,その他の特徴についていくつかご紹介します。

検証機能

リクエストの値を検証しなければならないことは少なくありません。

ASP.NET MVCから登場したモデルバインダによる検証の機能は,ASP.NET Web APIでも有効です。検証を有効にするには,DataAnnotationsの検証属性を付与することで,ModelStateオブジェクトから検証結果を参照することができます。

リスト4 検証属性を付与したCustomerクラス

public class Customer
{
    public int Id { get; set; }
        
    [Required(ErrorMessage = "{0} は必須項目です")]
    [StringLength(50, MinimumLength = 6)]
    public string Name { get; set; }

    public string Address { get; set; }

    [Range(1, 10)]
    public int Point { get; set; }
}

図1 検証結果がModelStateに格納されていることを確認

図1 検証結果がModelStateに格納されていることを確認

著者プロフィール

矢後比呂加(やごひろか)

ASP.NETをベースにした開発を行なう,Webシステム開発エンジニア。

趣味はピアノ。

コメント

コメントの記入