【ASP.NET】APIのルーティングを設定する2つの方法【WebAPI】

このエントリーをはてなブックマークに追加

ASP.NET Web APIでルーティングを行う方法は大きく分けて以下の2つです。
(私が知る限りでは)

  1. WebApiConfigで一括定義する
  2. Attributeを付与して個別定義する

今回はその2つの方法について解説していきます。

そもそもルーティングとは

ASP.NET Web APIは、その名の通りAPIを提供するためのフレームワークです。
実装としては、Controllerクラスを作り、その中にメソッドを定義します。
基本的にはメソッド1つに対してAPI1本が対応します。

ルーティングとは、あるURLにリクエストが来たときにどのAPIを呼び出すか、すなわち、リクエストURLと、呼び出すメソッドを結びつけることです。

方法1: WebApiConfigで一括定義する

ASP.NET Web APIのプロジェクトを新規作成した場合、このルーティング方法がデフォルトで採用されていると思います。

WebApiConfig.csで以下のように定義します。

1
2
3
4
5
6
7
8
9
10
11
public static class WebApiConfig
{
  public static void Register(HttpConfiguration config)
  {
      config.Routes.MapHttpRoute(
          name: "DefaultApi",
          routeTemplate: "api/{controller}/{action}/{id}",
          defaults: new { id = RouteParameter.Optional }
      );
  }
}

Registerというメソッド内でconfigにルーティングを追加します。
例えば上記の例だと、http://sample.jp/api/profile/get/5というURLをコールすると、ProfileControllerGetメソッドが呼び出されます。
{controller}の部分がコントローラ名、{action}の部分がメソッド名に対応するわけです。
ちなみにconfig.Routes.MapHttpRouteを複数回呼び出すことで規則を複数定義することができます。その場合、先に定義した規則が優先して適用されます。

メソッドの実装はこちら。

1
2
3
4
5
6
7
8
public class ProfileController : ApiController
{
 [HttpGet]
  public HttpResponseMessage Get(int id)
  {
      ...
  }
}

ルーティング設定に含まれているidは何かというと、メソッドに渡すパラメータです。
メソッドで上記のようにパラメータを受け取るように定義しておけば、URLの{id}の部分に指定した値を受け取ることができます。

ルーティング設定の中の

1
defaults: new { id = RouteParameter.Optional }

は、ルーティング時のデフォルト値の設定になります。
RouteParameter.Optionalは「このパラメータは省略可能である」ことを意味します。
つまり{id}はあってもなくてもいいという意味です。

ちなみにデフォルトとして以下のように設定することもできます。

1
defaults: new { controller = "profile", action = "get", id = RouteParameter.Optional }

このように設定すると、{controller}{action}を省略することが可能になります。
つまりhttp://sample.jp/api/というURLでアクセスすると勝手にProfileControllerのGetメソッドが呼ばれるわけです。

アクション名を指定する

例えば、「メソッド名は具体的に記述する」というチームルールがあったとします。
しかし、例えば以下のようなメソッドがあったとします。

1
2
3
4
5
6
7
8
public class ProfileController : ApiController
{
 [HttpGet]
  public HttpResponseMessage FindProfileByConsumerId(int id)
  {
      ...
  }
}

このとき、APIのURLはhttp://sample.jp/api/profile/findProfileByConsumerId/5となってしまいます。長い…

これを回避するために、ルーティングする文字列を別に指定することができます。
以下のようにActionName属性をメソッドに付与します。

1
2
3
4
5
6
[HttpGet]
[ActionName("get")]
public HttpResponseMessage FindProfileByConsumerId(int id)
{
  ...
}

こうするとhttp://sample.jp/api/profile/get/5というURLで、
FindProfileByConsumerIdメソッドを呼び出すことができます。

方法2: Attributeを付与して個別定義する

この方法は全てのメソッドにルーティング方法を明記する方法です。

まずWebApiConfig.csで以下のように宣言します。

1
2
3
4
5
6
7
public static class WebApiConfig
{
  public static void Register(HttpConfiguration config)
  {
      config.MapHttpAttributeRoutes();
  }
}

次にメソッドにRoute属性を付与します。

1
2
3
4
5
6
7
8
9
public class ProfileController : ApiController
{
 [HttpGet]
 [Route("api/profile/{id}")]
  public HttpResponseMessage FindProfileByConsumerId(int id)
  {
      ...
  }
}

このように定義すると、http://sample.jp/api/profile/5に対してこのメソッドが呼ばれるようになります。

APIを複数実装(メソッドを追加)する場合は必ずRoute属性を付与します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class ProfileController : ApiController
{
 [HttpGet]
 [Route("api/profile/{id}")]
  public HttpResponseMessage FindProfileByConsumerId(int id)
  {
      ...
  }

 [HttpPost]
 [Route("api/profile/update")]
  public void UpdateConsumerProfile(Profile profile)
  {
      ...
  }
}

ただ、上のように毎回api/profile/の部分を書いていくのは面倒だしメンテナンスしづらい。
そういった場合はRoutePrefix属性で共通化します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[RoutePrefix("api/profile")]
public class ProfileController : ApiController
{
 [HttpGet]
 [Route("{id}")]
  public HttpResponseMessage FindProfileByConsumerId(int id)
  {
      ...
  }

 [HttpPost]
 [Route("update")]
  public void UpdateConsumerProfile(Profile profile)
  {
      ...
  }
}

まとめ

ルーティングする際には基本的には上で説明した2パターンのどちらかを採用するのがいいかなー、と思います。

ちなみに上記2パターンを併用することもできます。そこはお好みで。

Comments