Skip to content

Instantly share code, notes, and snippets.

@rbtnn
Created July 10, 2013 08:38
Show Gist options
  • Save rbtnn/5964513 to your computer and use it in GitHub Desktop.
Save rbtnn/5964513 to your computer and use it in GitHub Desktop.
https://github.com/NancyFx/Nancy/wiki ここの重要そうな部分を適当に翻訳したやつ。

Nancy

最初のNancyアプリケーション

ここではあなたはNugetをインストールしており、Visual Studio 2010を使って いることを前提として話を進めています。 しかしこれと同等なことをMono(Version 2.10.2以降)とMonoDevelopを使っても できます。 NancyとNancyのASP.NET Hostingを使った"hello world"アプリケーション作成に 至るまでの過程を以下に示します。

  1. 新しい"ASP.NET Empty Web Application"を作成

  2. NancyのためのASP.NET Hostをインストール

Install-package Nancy.Hosting.Aspnet

(これはNuGetでNancyをインストールし、Nancyがどんなリクエストにも 対応できるようにweb.configを更新します。)

  1. Nancyモジュールを加える。これは標準のC#クラスであり、Webアプリケーション のルートURLのルートハンドラを定義する。

  2. コンパイルと実行

     // Nancyモジュール
     public class HelloModule : NancyModule
     {
         public HelloModule()
         {
             // ルートURLのルートハンドラを定義する。
             Get["/"] = parameters => "Hello World";
         }
     }
    

Self Hosting Nancy

あなたはコンソールアプリケーションをNancyのホストとすることもできます。 Nancy.Hosting.SelfパッケージをNuGetでインストールし、以下のコードを使えば 実現できます。

    using System;
    using Nancy.Hosting.Self;

    public class SelfHostingNancySample
    {
        public static void Main()
        {
            // ルートURLを引数にしてNancyHostインスタンスを作成する。
            var nancyHost = new NancyHost(
                new Uri("http://localhost:2000")
            );

            // ホストを起動する。
            nancyHost.Start();

            // ホストを停止させないように入力待ち状態にする。
            Console.ReadLine();

            // ホストを停止する。
            nancyHost.Stop();
        }
    }

管理者権限なしで起動する

Windowsにおいて、"Access Denied"というメッセージのHttpListenerException を投げてくるかもしれません。これを解決するにはそのURLをACLに加える必要が あります。

netsh http add urlacl url=http://+:2000/ user=DOMAIN\username

DOMAIN\usernameの部分は各自の「コンピュータ名+''+ユーザー名」に 置き換えてください。

この操作を取り消すには以下のコマンドを実行します。

netsh http delete urlacl url=http://+:2000/

また、このURLをほかのコンピュータからアクセスできるようにするには そのポートを解放する必要があります。

モジュール

モジュールはあなたがアプリケーションの振る舞いを定義することを 許可することのほかにもより多くのことをします。 モジュールは現在のリクエスト、そのリクエストが処理されているコンテキスト、 レスポンスに対するヘルパー、ビューのレンダリング、などの情報へのアクセスを あなたに提供します。 モジュールはNancyModuleクラスを継承することによって生成されます。 モジュールは実行時のアプリケーションドメイン内ならどこにでも宣言することができます。 これはたとえば外部(external)アセンブリ内に定義されたモジュールも含まれることを意味します。

モジュールパス

モジュールの特徴の1つはモジュールパスを定義することである。 Nancyは共通となる下位のルートパスをうまくグルーピングすることが できる。

    public class ResourceModule : NancyModule
    {
        public ResourceModule() : base("/products")
        {
            // Getリクエストの/products/listへのルートをキャプチャする
            Get["/list"] = parameters => {
                return "The list of products";
            };
        }
    }

ルート

ルートはモジュールのコンストラクタに定義されます。 Nancyでルートを定義するには、あなたはMethod+Pattern+ Action+(optional)Conditionと記述する必要があります。

    public class ProductsModule : NancyModule
    {
        public ProductsModule
        {
            //`Method`+`Pattern`+`Action`
            Get["/products/{id}"] = _ =>
            {
                // do something
            };
        }
    }

メソッド

メソッドはリソースにアクセスするために使われるHTTPメソッドです。 NancyはDELETE, GET, HEAD, OPTIONS, POST, PUT, PATCH のメソッドをサポートしています。 HEADリクエストはGETリクエストが宣言されたすべてのルートのために 自動的に使われます。

パターン

ルートには常にアプリケーションの相対URLを含むパターンが必要です。 パターンのシンタックスはカスタマイズ可能だが、Nancyは以下のような 組み合わせをキャプチャするデフォルトの実装がある。

  1. Literal segments -(10,000)- /some/literal/segments:
  2. Capture segments -(1,000)- /{name}:
  3. Capture segments (optional) -(1,000)- /{name?}:
  4. Capture segments (optional/default) -(1,000)- /{name?unnamed}/:
  5. RegEx segment -(1,000)- /(?<age>[\d]{1,2}):
  6. Greedy segment -(0)- /{name*}:
  7. Greedy RegEx segment -(100)- ^(?<name>[a-z]{3,10}(?:/{1})(?<action>[a-z]{5,10}))$:

-(...)-内の数値はスコアです。 このスコアは以下のような複数のパターンにマッチしたときに使われます。

    public class HomeModule : NancyModule
    {
      public HomeModule()
      {
        Get["/{category}"] = _ =>
        {
          return "My category is " + _.category;
        }
        
        Get["/sayhello"] = _ =>
        {
          return "Hello from Nancy";
        }
      }
    }

最初のルートは2.Capture Segments、そして2つ目のルートは1.Literal Segment。 この場合、スコアの高いほうが優先されます。よって2つ目のルートが選ばれます。

アクション

アクションはルートにマッチしたリクエストが発行(実施)されたときの振る舞いです。 それはFunc<dynamic, dynamic>型のラムダ式によって表現されます。 そのdynamicな入力値(第1引数にあたる)はDynamicDictionaryという型である。 この型はNancyの中に定義されています。

The response can be any model and the final result will be determined by Content Negotiation. However, if it is of the type Response then content negotiation will be ignored and the response will be sent straight back to the host.

Responseオブジェクトはいろんなimplicit cast operatorを宣言しています。 それはアクションになることが可能であり、Responseオブジェクトの代わりに なります。代わりになりえる型は以下のうちのどれかです。

  • int: レスポンスのHTTPステータスコードとして扱われます。
  • HttpStatusCode: HTTPステータスコードの列挙型。
  • string: レスポンスのbodyとして扱われます。
  • Action<Stream>: レスポンスのストリームに書き込む関数オブジェクト。

コンディション

https://github.com/NancyFx/Nancy/wiki/Defining-routes

public class SampleModule : NancyModule { public SampleModule() { Get["/"] = parameters => { return View["wwwroot/products.html"]; }; Post["/login", (ctx) => ctx.Request.Form.remember] = _ => { return "Handling code when remember is true!"; };

    Post["/login", (ctx) => !ctx.Request.Form.remember] = _ => 
    {
        return "Handling code when remember is false!";
    };
}

}




    using System;
    using Nancy;
    using Nancy.Hosting.Self;

    public class A
    {
        public static void Main()
        {
            var nancyHost = new NancyHost(new Uri("http://localhost:2000"));

            nancyHost.Start();

            Console.ReadLine();

            nancyHost.Stop();
        }
    }

    public class SampleModule : NancyModule
    {
        public SampleModule()
        {
            Get["/hello"] = parameters => {
                return "Hello!";
            };
        }
    }

var a = View["wwwroot/products.html", this]; // Nancy.Responses.Negotiation.Negotiator return a.GetType().ToString();

// Nancy.NancyModule+ViewRenderer return View.GetType().ToString();

    /// <summary>
    /// Renders a view from inside a route handler.
    /// </summary>
    /// <value>A <see cref="ViewRenderer"/> instance that is used to determin which view that should be rendered.</value>
    public ViewRenderer View
    {
        get { return new ViewRenderer(this); }
    }

Nancyはlightweight、low-ceremony、 .NetとMono上のサービスがもととなるHTTPで作られた フレームワークです。

ベースとなるルートを設定することも可能。

//Getリクエストの'/products/list'にあたる。 public ResourceModule() : base("/products"){ Get["/list"] = ... }

ルートはモジュールのコンストラクタ内に定義されます。 In order to define a route in Nancy, you need to specify a Method + Pattern + Action + (optional) Condition.

Nancy

public class DynamicDictionary : DynamicObject, IEquatable, IHideObjectMembers, IEnumerable, IDictionary<string, object>

Nancy.Hosting.Self

[Serializable] public class NancyHost : IDisposable

Allows to host Nancy server inside any application - console or windows service.

NancyHostは内部でSystem.Net.HttpListenerを使用している。 要するに、実行させるためには.Net 4.0 Profileをフルに必要とする(Client Profileではなく)。 Startはリクエストを受け付けるためのスレッドを起動させ、そして、それらのリクエストを処理するだろう。 すべてのプロセスはシングルスレッド内で処理される。セルフホスティングはプロダクトのために作られているわけではない。 むしろ、開発サーバー向きである。 NancyHost needs SerializableAttribute in order to be used from another appdomain under mono. Working with AppDomains is necessary if you want to unload the dependencies that come with NancyHost.

public NancyHost(params Uri[] baseUris)

指定されたbaseUrisのためのNancyHostクラスの新しいインスタンスを初期化する。 デフォルトの設定を使用する。

`baseUris`: The `Uri`s that the host will listen to.

public NancyHost(HostConfiguration configuration, params Uri[] baseUris)

指定されたbaseUrisのためのNancyHostクラスの新しいインスタンスを初期化する。 指定されたconfigurationの設定を使用する。

`baseUris`: The `Uri`s that the host will listen to.
`configuration`: Configuration to use

public NancyHost(INancyBootstrapper bootstrapper, params Uri[] baseUris)

指定されたbaseUrisのためのNancyHostクラスの新しいインスタンスを初期化する。 using the provided bootstrapper. デフォルトの設定を使用する。

`bootstrapper`: The bootstrapper that should be used to handle the request.
`baseUris`: The `Uri`s that the host will listen to.

public NancyHost(INancyBootstrapper bootstrapper, HostConfiguration configuration, params Uri[] baseUris)

指定されたbaseUrisのためのNancyHostクラスの新しいインスタンスを初期化する。 using the provided bootstrapper. 指定されたconfigurationの設定を使用する。

`bootstrapper`:The bootstrapper that should be used to handle the request.
`configuration`: Configuration to use
`baseUris`: The `Uri`s that the host will listen to.

public NancyHost(Uri baseUri, INancyBootstrapper bootstrapper)

指定されたbaseUrisのためのNancyHostクラスの新しいインスタンスを初期化する。 using the provided bootstrapper. デフォルトの設定を使用する。

`baseUri`:The `Uri` that the host will listen to.
`bootstrapper`:The bootstrapper that should be used to handle the request.

public NancyHost(Uri baseUri, INancyBootstrapper bootstrapper, HostConfiguration configuration)

指定されたbaseUriのためのNancyHostクラスの新しいインスタンスを初期化する。 using the provided bootstrapper. 指定されたconfigurationの設定を使用する。

`baseUri`: The `Uri` that the host will listen to.
`bootstrapper`: The bootstrapper that should be used to handle the request.
`configuration`: Configuration to use

public void Dispose()

もし、ホストが実行中なら停止する。

public void Start()

与えられた設定(HostConfiguration)でリクエストの受け付けを開始する。

public void Stop()

リクエストの受け付けを止める。

public sealed class HostConfiguration

Host configuration for the self host

public bool RewriteLocalhost { get; set; }

Gets or sets a property that determines if localhost uris are rewritten to htp://+:port/ style uris to allow for listening on all ports, but requiring either a url reservation, or admin access Defaults to true.

public UrlReservations UrlReservations { get; set; }

Configuration around automatically creating url reservations

public bool AllowChunkedEncoding { get; set; }

Gets or sets a property that determines if Transfer-Encoding: Chunked is allowed for the response instead of Content-Length (default: true).

public Action UnhandledExceptionCallback { get; set; }

Gets or sets a property that provides a callback to be called if there's an unhandled exception in the self host. Note: this will not be called for normal nancy Exceptions that are handled by the Nancy handlers. Defaults to writing to debug out.

public bool EnableClientCertificates { get; set; }

Gets or sets a property that determines whether client certificates are enabled or not. When set to true the self host will request a client certificate if the request is running over SSL. Defaults to false.

public HostConfiguration()

    {
        this.UrlReservations = new UrlReservations();
        this.UnhandledExceptionCallback = e =>
            {
                var message = string.Format("---\n{0}\n---\n", e);
                Debug.Write(message);
            };
    }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment