miso_soup3 Blog

主に ASP.NET 関連について書いています。

ASP.NET Web API 2 で追加された機能について

この記事は、One ASP.NET Advent Calendar 2013 の 6 日目の記事です。
前回は、jsakamoto さんの ASP.NET の Minify & Bundle 機能と HTML5オフラインキャッシュ です。
次回は、Kiyokura narami さんの Glimpseのポリシーをコードで制御する です。

10/17 頃に Visual Studio 2013 と共に提供が開始された ASP.NET Web API 2 の新機能について、何にも気にせず語ろうと思います。

ASP.NET Web API 2

番号

ASP.NET Web API 2 は「2」という数字がついていますが、NuGetパッケージのバージョンや、元締めソースのバージョンの数字は「2」ではありません。ASP.NET Web API(無印)も含めて、それぞれのバージョン番号は以下の通りです。

4.0 と 5.0 あたりが本当のバージョン番号っぽいですね。ややこしいー!

.NET Framework 対応バージョン

ASP.NET Web API (無印)は、.NET 4.0 以上、
ASP.NET Web API 2 は、.NET 4.5 以上が必要です。

プロジェクトの始め方

ASP.NET Web API 2 は、Visual Studio 2012、2013 の両方でプロジェクトを作成できます。
Visual Studio 2012 で始める場合は、ASP.NET and Web Tools 2013.1 for Visual Studio 2012 をインストする必要があります。

ASP.NET Web API 2 新機能

ASP.NET Web API 2 で追加された新機能は以下の通りです。

  • Attribute Routing
  • OAuth 2.0 の対応
  • OData 対応の追加
  • Request Batching
  • Portable ASP.NET Web API Client
  • Improved Testability
  • IHttpActionResult
  • HttpRequestContext
  • CORS
  • Authentication Filters
  • Filter Overrides
  • OWIN Integration

わーこんなにあったんですねー!
それぞれの機能については、英語でしたらASP.NET Web API 2 is out! Overview of features に説明があります。リリース当日に公開され、今でもリツイートされ続ける凄い記事。ASP.NET Web API の最先端をいっています。

私も習ってそれぞれの機能について説明を試みようと思います。

Attribute Routing

ASP.NET MVC 5 にも追加された項目です。
こんな風に属性でルーティングを設定できるようになりました。

[Route("api/customers/{customerId}/orders/{orderId}")]
public Order GetOrderByCustomer(int customerId, int orderId);

公式サイト:Attribute Routing in Web API 2
以前ブログに書きました。:ASP.NET Web API 2 Attribute Routing

ASP.NET Web API 2 のプロジェクトを作ると、既に WebApiConfig.cs に config.MapHttpAttributeRoutes(); が記述され、属性ルーティングが有効になっています。
注意したいのは、AttributeRoutingとは違うライブラリで、ASP.NET Web API 2 本体に組み込まれていることです。

OAuth2.0 の対応

Google や Twitter 等の SNS 認証、Azure のActive Directoryを使った認証を、Web API を通じて行うことができます。
また、独自のデータベースにユーザー情報を格納していても、ASP.NET Idnetity を利用して Barerトークンによる OAuth 認証を行うことができます。

この独自データベースでも OAuth 認証ができる、って一大ニュースな気がします。詳しくはIndividual Accounts in ASP.NET Web API に記載されています。
VS2013では、プロジェクトテンプレートで「個人ユーザーアカウント」を選択することで直ぐ始められるのも大変便利。

仕組みは凄く大雑把に言うと、

  • ~/api/account/register でアカウント新規登録
  • ~/token で grant_type=password&username=Alice&password=password123 でユーザー名&パスワードを POST で送信し、認証トークンを取得
  • 後はヘッダーに「Authorization: Barer [認証トークン]」と設定すれば、保護されたリソースへアクセスできます。

もちろん[Authorize] 属性も効きますし、認証トークンの有効期限管理も行っています。
SPA のテンプレートでも利用されています。

OData 対応の追加

OData周りは、全然調べてません…。

Request Batching

以前ブログに書きました。 ASP.NET Web API 2 Request Batching
1つの HTTP リクエストの中に複数の HTTP リクエストを含む multipart/mixed に対応しました。
1つの HTTP リクエストで、複数の API コントローラのメソッドをループしてくれるのがナイスです。

Portable ASP.NET Web API Client

Windows Store App や Windows Phone のポータブルクラスライブラリで、ASP.NET Web API の Client ライブラリ― HttpClient が使えるようになりました。
System.Net.Http.Formatting ライブラリも使えます。つまり、(HttpResponseMessage).Content.ReadAsAsync<T> が使えます!!
(拡張メソッドなので、using System.Net.Http.Formatting と書かないと、ReadAsAsync メソッドがインテリセンスに出てくれません。)

例えば、クライアント側とサーバー側で同じクラス<T>を参照し、サーバー側(ASP.NET Web API)では return T; を書き、クライアント側(HttpClient)では、HttpResponseMessage).Content.ReadAsAsync<T> とかいて、クラス<T>を受け取ることができます。

Improved Testability

テスタビリティが向上しているらしい。UrlHelper推しらしい。

IHttpActionResult

以前ブログに書きました。 ASP.NET Web API 2 - IHttpActionResult
アクション・メソッドの戻り値に、IHttpActionResultインターフェイスを指定できるようになりました。
ApiController にヘルパーメソッドが大量に追加されており、アクションメソッドにて以下のようなコードが書けます。

return BadRequest();
return Conflict();
return Content(…);
return InternalServerError();
return Json();
return NotFound();
return Ok();
return Redirect(url);
return StatusCode(statusCode); 

カプセル化できるし、重複なくなるし、テスタビリティも向上しましたし良いことだらけです。

・・・・が、個人的には残念なことが・・・、

ASP.NET Web API は、戻り値に string とか Person とか IEnumerable<T> とか、好きなオブジェクトを指定できるのが好きでした。
何故なら ASP.NET MVC では、Ajax を使用する際は、戻り値に「JsonResult」ばっかり定義していたからです。JsonResult も ActionResult もしつこい!! たまには ViewResult 書こうかなーと思ったら Redirect に変更になって戻り値修正しなきゃですし。 一方、ASP.NET Web API は、戻り値に string とか Person とか IEnumerable<T> とか、好きなオブジェクトを指定できます(二度目)。


が、IHttpActionResult が登場してからです。
ある日、新しい ASP.NET Web API 2 を試してみようと思って、スキャフォールディングしてみました。


f:id:miso_soup3:20131206224120p:plain


.: : : : : : : : :: :::: :: :: : :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    . . : : : :: : : :: : ::: :: : :::: :: ::: ::: :::::::::::::::::::::::::::::::::::::
   . . .... ..: : :: :: ::: :::::: :::::::::::: : :::::::::::::::::::::::::::::::::::::::::::::
        Λ_Λ . . . .: : : ::: : :: ::::::::: ::::::::::::::::::::::::::::
       /:彡ミ゛ヽ;)ー、 . . .: : : :::::: ::::::::::::::::::::::::::::::::
      / :::/:: ヽ、ヽ、 ::i . .:: :.: ::: . ::::::::::::::::::::::::::::::::::::::
      / :::/;;:   ヽ ヽ ::l . :. :. .:: : :: :: :::::::: : ::::::::::::::::
 ̄ ̄ ̄(_,ノ  ̄ ̄ ̄ヽ、_ノ

メソッドについてる属性クラス [ResponseType(typeof(Person))] って何ですか?
こんなコード書くくらいなら、戻り値に Person って書けばいいじゃないですか。
戻り値を Person にしても、でも throw で違う種類のレスポンスを返せるところがステキだったじゃないですか。
しかもこの属性、 System.Web.Http.Description 名前空間 で、ヘルプページ用の属性クラスですし!!
MVC の JsonResult と変わらないじゃないですか!!(Jsonシリアライザ違いますけど)


  <⌒/ヽ-、___
/<_/____/
ふて寝ふて寝

HttpRequestContext

HttpRequestContext クラス を利用できます。ApiControllerクラスのプロパティにあります。コードを見ると分かりますが、インスタンスを簡単に生成できるのでテストがしやすくなっていっます。

CORS

以前ブログに書きました。 ASP.NET Web API 2 CORS サポートについて
CORS とはクロスドメイン通信の仕様です。サーバー側の振る舞いが可能になりました。
属性により、アクセス許可等を適切なレベルで設定できます。
IE8, 9 あたりが無くなれば、CORS し放題でしょうか?

Authentication Filters

ASP.NET MVC 5 にも追加された項目です。
フィルターのインターフェイス、IAuthenticationFilter が追加されました。認証ロジックを、グローバル・コントローラ毎・メソッド毎に設定することができます。

Filter Overrides

ASP.NET MVC 5 にも追加された項目です。
今ままでは、例えばコントローラーにとあるフィルタを設定した場合、コントローラーのこのメソッドだけは違う設定のフィルタを適用させたい、といったことができませんでした。それが可能になりました。

OWIN Integration

OWIN に対応しました。app.UseWebApi(config); で OWIN パイプラインに参加できます。
ASP.NET Web API(無印)の時から System.Web.Http に依存しないでセルフホストできていましたが、OWINに向かってたんですね。


ASP.NET Web API 2 の新機能は以上です。
次のバージョンアップでは、Global Error Handling と Logger あたりが追加されるみたいです。楽しみ!