Premiers pas avec Nancy

LogoNancy est une stack open source alternative à la stack web Microsift : ASP.NET. C’est un portage vers le monde .NET du projet Ruby Sinatra. L’objectif est de pouvoir exposer des pages et des services web et les mots d’ordre de Nancy sont: simplicité et modularité. C’est parti.

Installation et premier module

La première chose à faire est de télécharger les templates de projet Nancy :

image

Une fois que c’est fait, nous avons accès au types de projet suivants :

image

Comme on peut le voir, pas d’assistant de création de projet, comme pour les versions récentes d’ASP.NET. Il faudra donc choisir :

  • entre une application pré-créée et une application vide
  • le type d’hébergement : IIS (ASP.NET) ou OWIN (Self-hosting)
  • le moteur de rendu : Razor ou le moteur maison, le Super Simple View Engine

A noter qu’il est parfaitement possible d’opter vers un autre moteur de rendu, voire d’écrire le votre. De même pour l’hébergement. Les solutions proposées par les templates ne servent qu’à accélérer les premiers développements. Ensuite, c’est comme bon vous semble.

Nous allons commencer par choisir le template Nancy Empty Application with ASP.NET hosting and Razor, ce qui créé la structure suivante :

image

On a donc bien un projet vide. La seule chose que nous a fait le template est d’ajouter les références aux assemblies Nancy et System.Web et de générer un fichier de configuration suivant :

<?xml version="1.0" encoding="utf-8"?>
<!--
 For more information on how to configure your ASP.NET application, please visit
 http://go.microsoft.com/fwlink/?LinkId=169433
 -->
<configuration>
 <configSections>
   <sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
     <section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
   </sectionGroup>
 </configSections>
 <system.web>
   <compilation debug="true" targetFramework="4.0">
     <buildProviders>
       <add extension=".cshtml" type="Nancy.ViewEngines.Razor.BuildProviders.NancyCSharpRazorBuildProvider, Nancy.ViewEngines.Razor.BuildProviders" />
       <add extension=".vbhtml" type="Nancy.ViewEngines.Razor.BuildProviders.NancyVisualBasicRazorBuildProvider, Nancy.ViewEngines.Razor.BuildProviders" />
     </buildProviders>
   </compilation>
   <httpHandlers>
     <add verb="*" type="Nancy.Hosting.Aspnet.NancyHttpRequestHandler" path="*" />
   </httpHandlers>
 </system.web>
 <system.webServer>
   <validation validateIntegratedModeConfiguration="false" />
   <handlers>
     <add name="Nancy" verb="*" type="Nancy.Hosting.Aspnet.NancyHttpRequestHandler" path="*" />
   </handlers>
 </system.webServer>
 <appSettings>
   <add key="webPages:Enabled" value="false" />
 </appSettings>
 <system.web.webPages.razor>
   <pages pageBaseType="Nancy.ViewEngines.Razor.NancyRazorViewBase">
     <namespaces>
       <add namespace="Nancy.ViewEngines.Razor" />
     </namespaces>
   </pages>
 </system.web.webPages.razor>
</configuration>

Le plus important ici est l’ajout du handler NancyHttpRequestHandler pour l’ensemble des requêtes adressées à ce site. Le reste sert à câbler Razor. Nous voilà parés au décollage. Mais il faut maintenant que notre site fasse des choses. Nous allons commencer par implémenter le premier exemple donné sur la page d’accueil du projet Nancy et créer notre premier module. Nous reviendrons plus tard sur cette notion de module.

Un module Nancy est simplement une classe qui hérite de NancyModule. Le notre ne fera pas grand chose dans un premier temps :

namespace NancyDemo
{
   public class SampleModule : Nancy.NancyModule
   {
      public SampleModule()
      {
         Get["/"] = _ => "Hello World!";
      }
   }
}

Voilà, c’est tout. F5, et allons voir le résultat :

image

Notre module écoute les requêtes Http de type Get sur la route “/” qui est donc la racine de notre application, et leur répond “Hello World”. L’URL de notre application, quant à elle, est simplement dictée par la configuration de notre projet ASP.NET :

image

Qu’est-ce qu’un module ?

Le module est le point d’entrée d’une application Nancy : il indique au moteur Nancy comment se comporter à l’exécution. C’est donc dans un module que l’on définit le comportement de cette application. Comme vu dans l’exemple ci-dessus, un module est simplement une classe, héritant de NancyModule. Le moteur Nancy se charge de découvrir par réflexion l’ensemble des modules de l’application disponibles au démarrage de l’application (et donc une seule et unique fois).

Chaque module peut définir des routes. La notion de route est la même que pour ASP.NET; elle décrit simplement un mapping entre le couple {méthode Http, URL} et le code à exécuter. Une application Nancy minimale est donc composée d’un module, qui définit une route.

Les modules permettent de découper l’application en sous-ensembles cohérents. Chaque module peut donc avoir un chemin par défaut. Par exemple, nous pourrions imaginer un module Administration, qui gère toutes les URL de type http://localhost:7844/admin/ :

public class AdministrationModule : NancyModule
{
    public AdministrationModule() : base("/admin")
    {
        Get["/users"] = parameters => {
            return "La liste des utilisateurs";
        };
    }
}