Running Nancy on Azure Web Sites
I’m a huge fan of finding cleaner ways to build web applications. Simplicity is a really good thing. Nancy is a simple little web framework inspired by Ruby’s Sinatra. Nancy is open source, hosted on GitHub.com, and distributed like any other awesome .NET open source library – via NuGet packages. When a coding challenge landed on my desk this week that I’ll be responsible for prototyping, Nancy seemed like a good option, so I’ve taken the time to tinker with it a little. I’ll spare you the details of the coding assignment for this post. Instead, I’ll focus on the process of getting Nancy working in your own Azure Web Site.
To start with, I’ve created an empty web site using the Azure portal. This site won’t use a database, so I just logged into the portal and selected New –> Web Site –> Quick Create and gave it a pretty logical name.
Once the site was finished cooking, I grab the publish profile settings from the site’s dashboard.
Getting Started with Nancy
First, I create an empty ASP.NET web application. To make sure everything’s as clean as it could be, I remove a good portion of the files and folders from the site. Since I’ll be creating the most basic level functionality in this example, I don’t need a whole lot of extraneous resources and functionality in the site. The project below shows what I have left over once I ransacked the project’s structure. Take note of the Uninstall-Package command I made in the Package Manager Console. I ran similar commands until I had as bare-bones a project structure as possible. Then I removed some stuff from the Web.config until it literally was quite minimalistic.
To run Nancy on Azure Web Sites, I’ll need to install 2 packages from NuGet. The first of these is the Nancy core package. The second package I’ll need is the package that enables Nancy hosting on ASP.NET.
In my web project I create a new folder called NancyStuff and add a new class called HelloWorldModule.
This class is a very basic Nancy Module, and I learned how to create it by perusing the Nancy project’s GitHub.com Wiki. I basically want to have a route that, when called, will just say hello to the user. You don’t get much simpler than this for assigning functionality to a given route. When the user requests the /hello route using an HTTP GET request, the message Hello World is rendered to the response stream. The HelloWorldModuleclass will extend NancyModule.In Nancy, routes are handled by classes which inherit from NancyModule.According to the Nancy documentation, Modules are the lynchpin of any given Nancy application.
At this point, everything should work, so I’ll go ahead and deploy the web site up to Azure. To do this, I select the Publishcontext menu item from within Visual Studio 2012.
Then, I import the publish settings file using the Importfeature on the publishing dialog.
Once I find the .publishsettingsfile I downloaded from the Azure portal and import it, I’m ready to publish. Clicking the publish button in the dialog at this point will result in the site being deployed up to my Azure Web Site.
The site will open once the deployment has completed and will probablypresent me with a 404 error, indicating there’s no route configured to answer requests to the root of the site. Changing the URL to hit /hello will result with the module answering the request and doing what I expected it to do:
Enabling Static File Browsing
With this first module functioning properly I want to create a static file from which the Nancy module could be called using jQuery on the client. The idea is, now that I have this Nancy module working, I might want to make calls to it using some AJAX method to display the message it returns to the user. So I add a new static HTML page to my solution.
The problem here is that, since Nancy’s handing requests to my site and using the modules I create to respond to those requests, the ability to browse to static files is… well… sort of turned off.So attempts to hit a seemingly innocent-enough page results with a heinous – yet adorable in a self-loathing sort of way - response.
Thanks to the Nancy documentation, it was pretty easy to find a solution to this behavior. See, Nancy basically starts intercepting requests to my site, and it takes precedence over the default behavior of “serving up static files when they’re requested.” Nancy’s routing engine listens for requests and if one’s made to the site for which no module has been created and routed, the site has no idea how to handle the request.
To solve this problem, I need to create another class that extends the DefaultNancyBootstrapperclass. This class, explained pretty thoroughly in the GitHub.com Nancy Wiki’s article on managing static content, is what I’ll need to use to instruct Nancy on how to route to individual static files. For now I’m only in need of a class to handle this one particular static file, but setting up a bootstrapper to allow static browsing in a directory is possible. Other options exist too, such as routes that use regular expressions, but that’s something I’ll look at in a later episode of this series. For now, I just want to tell Nancy to serve up the page Default.htmlwhenever a request is made to /Default.html. I’m also enabling static file browsing out of the /scriptsfolder of the site. The main thing to look at here is the call to the StaticContentsConventions.Add method, into which I pass the name of the file and the route on which it should be served up.
Now, I’ll add some jQuery code to the static page that calls the HelloWorldModule and displays whatever it responds with in an HTML element on the page.
When the static file loads up in the browser, the jQuery code makes an AJAX request back to the server to the /hello route, and then drops the response right into the page. When I deploy the site again to Azure Web Sites and hit the Default.html file, the behavior is just what I’d expected it would be; the page loads, then the message is obtained via AJAX and displayed.
Hopefully this introduction has demonstrated the support Azure Web Sites has for Nancy. Since Nancy can be hosted under ASP.NET, and since Azure Web Sites support the ASP.NET pipeline, everything works. I’ll continue to tinker with Nancy from here as I work on the coding project for which I chose it to be a puzzle piece. Hopefully during that development work I’ll learn more about Nancy, have the time to demonstrate what I learn, and ease someone’s day when they decide to move their Nancy site over to Azure Web Sites.