NancyFxチュートリアル「3.1. モジュール(コントローラ)を作成する (ルーティング編)」

この記事は、Nancy Advent Calendar 2013の8日目の記事です。

書けない日の分を書き続けるのもアレですので、かけていない日の分を空けます(^^;

前回は、プロジェクトの細かい設定と、モデルの作成をしました。

今回からモジュール(コントローラ)を作成していこうと思います。モジュールについては少し細かく書いていこうと思います。

もくじ

  • ルーティングの構文
  • HTTPメソッド
  • パターン
  • 複数のパターンが重複した場合
  • アクション

ルーティングの構文

ドキュメントは以下です。

Defining routes · NancyFx/Nancy Wiki · GitHub

ルーティングについては、AC2日目の記事で動作確認をした際に、簡単にご紹介しました。

public class HomeModule : NancyModule
{
    public HomeModule()
    {
        // GET "/"
        Get["/"] = parameter => {
            return "Hello NancyFx !!";
        };
    }
}

このように、ルーティングをはモジュールクラスのコンストラクタで指定します。指定する構文は、HTTPメソッド[パターン] = Func<dynamic, dynamic>です。

それぞれの項目に指定できる値をみてみます。

HTTPメソッド

HTTPメソッドには、GET POST PUT DELETE と、OPTIONS HEAD PATCHが指定できます。HEAD以外はそれぞれの名前のインデクサーが定義されています。HEADについては、GETのインデクサーに定義したものが使われるようです。

パターン

パターンは、ルートからの相対URLを指定します。パターン構文はNancyFxである程度用意されており、それで十分こと足りると思いますが、独自に定義することも可能です。

また、パターンにはスコアによる優先順位があります。同じようなルーティングが定義されている場合は、カッコ内の数値が高い順に優先されます。

NancyFxで用意されているルーティングは以下のとおりです。

  • リテラル (10,000) - /some/literal/segument のように、URLに完全一致する場合に指定します。一番優先順位が高いです。

  • キャプチャー (1,000) - /{name} のように、変数にキャプチャーできるパターンです。/blog/{date}/comments/{id}のように、リテラルと組み合わせて使用します。

  • キャプチャー(Optional) (1,000) - /{name?}のように、キャプチャー名に?をつけることで、そのURLを省略可能にできます。

  • キャプチャー(Optional + デフォルト値) (1,000) - /{name?unnamed}のように、省略可能なキャプチャー変数にデフォルト値を設定することができます。あまり使い道が浮かばない・・・。

  • 正規表現 (1,000) - /(?<age>[\d]{1,2})のように、正規表現を利用して値をキャプチャーします。

  • 可変長キャプチャ (0) - /{name*}のように、キャプチャー変数名に*をつけることで、スラッシュ以降のセグメントを可変長引数のようにキャプチャーします。

  • 可変長正規表現キャプチャ (100) - ^(?<name>[a-z]{3,10}(?:/{1})(?<action>[a-z]{5,10}))$のように、スラッシュ以降のパスを全て正規表現でキャプチャーします。難しい・・・。

  • マルチキャプチャー (100) - /{file}.{extension}/{file}.xmlのように、キャプチャーとリテラルを組み合わせる方法です。jsonやxmlのように拡張子を指定したREST APIなどを実装する際に使えます。

複数のパターンが重複した場合

さきほど説明したとおり、複数のパターンが重複した場合はスコアによる順位付けがなされます。たとえば、以下のようなルーティングを定義したとします。

Get["/{category}"] = _ => {
    return "My category is " + _.category;
};

Get["/sayhello"] = _ => {
    return "Hello from Nancy";
};

/{category}/sayhelloのルーティングを定義しましたが、ブラウザから/sayhelloとアクセスした場合に重複してますね。このようにルーティングが重複した場合はスコアの大きいほうが優先されますので、スコア10,000の/sayhelloが適用されます。結果は実際にブラウザからアクセスして試してみてください。

アクション

ルーティングアクションには、リクエストが指定したルーティングに一致した場合に呼び出される動作を指定します。

引数にはdynamic型インスタンスが渡され、URLでキャプチャした値を取得することができます。

リクエストを処理するために必要な値などについては、引数以外にRequestContextなどのプロパティが定義されています。

レスポンスを返すためにはResponseというプロパティを使いレスポンスを生成するか、Viewプロパティを使いView経由で返す、あるいな独自のレスポンスを定義することもできます。

また、ViewBagを利用することもできます。利用方法はASP.NET MVCと同じです。

まとめ

今回は、コントローラと同じ働きをするモジュールについて、ルーティングを定義する方法を中心にまとめました。基本的なルーティングの定義については、ここでまとめた内容でまかなえると思います。

これ以外にも、条件付きルーティングや、非同期処理などの機能もあります。非同期処理についてはどこかでまとえるかもしれませんが、それ以外についてはドキュメントを参照してみてください。

次回は、NancyFxで定義されているレスポンスを作成する方法についてまとめ、実際の処理を記述していこうと思います。