CHAPTER 3
As you can see by now, Nancy has two primary use cases that define its existence.
The first of these is to use the framework as a general purpose, REST-based framework in place of toolkits such as ASP.NET Web API or REST.
By default, Nancy provides first-class routing and content negotiation facilities, which you'll learn more about in the coming chapters. It’s not just about providing rest end points, however; a big part of the equation is the ease with which it allows you to support them.
Many toolkits claim to implement REST, when in reality they don't (at least not by the official W3C standard). While this is not a problem that prevents REST from being used as an architectural pattern, it does nevertheless detract somewhat from what it means to implement REST in a manner that satisfies the W3C standards.
For instance, given a URI pointing to a collection, like http://example.com/people/, many toolkits will implement a Get request to obtain the collection, and Post for anything that constitutes an action that potentially modifies data behind the scenes. Nothing more than Get and Post verbs are generally implemented, and even if other verbs are permitted, there's usually so many hoops that have to be jumped through to make it happen that it's often not worth the effort required to do so.
Tip: If you need to catch up on the basics of HTTP and how it works, there's another Succinctly series book available on the subject: HTTP Succinctly, by Scott Allen, is well worth a read.
Nancy flips this notion on its head and makes it easy to implement any verb you want by specifying it in your code. Later, I'll provide some full examples on routing. For now, however, the following code happily implements a REST-based interface to manage a collection that follows the W3C specification correctly:
Code Listing 1
public MP3Player() : base("mp3player") { Get["/genres/"] = _ => { // Implement code here to retrieve all genres from the database return HttpStatusCode.OK; }; Put["/genres/"] = _ => { // Implement code here to store all genres to the database return HttpStatusCode.OK; }; Post["/genres/"] = _ => { // Implement code here to add a new genre in the database return HttpStatusCode.OK; }; Delete["/genres/"] = _ => { // Implement code here to delete all genres from the database return HttpStatusCode.OK; }; } |
The clarity with which routes are defined is quite startling when you're used to working with other toolkits that hide action methods behind obfuscated function names and depend on complex setup procedures to find where everything is.
The definitions are typically so clear and easy-to-see that you can almost read down a class implementing a set of routes and see at-a-glance exactly what responds to what, and how.
Nancy implements ALL the standard HTTP verbs in this manner, not just the four in the previous code listing. It implements, but is not restricted to, the following (which many other toolkits do not on the grounds of security):
Given what you have learned already, it should also come as no surprise that it's a simple matter of adding a custom class that overrides one or more of Nancy's standard interfaces to easily implement your own verbs, making it even easier to implement custom functionality. In fact, one of Nancy’s major strengths is its ability to define DSLs (domain-specific languages) using simple REST-based concepts and clearly written code.
As a REST toolkit, Nancy excels at letting you get on and implement what you need without ceremony or fuss.
Don't get me wrong—it's not all smooth sailing. There are one or two scenarios where you do have to do some extra work. Under IIS, for example, I am led to believe that IIS6 and earlier don't actually implement some of the verbs available, so if you’re hosting using ASP.NET, you may not actually get the verb passed on to you. I am also led to believe that when hosting under IIS, you may experience conflicts with WebDAV where the only resolution is to either not use the conflicting verbs, or to disable WebDAV on the machine where the conflict arises.
In both of these cases, however, third-party conditions prevent Nancy from performing as intended; where no problems of the aforementioned types exist, implementing the exact interface you need is not a problem.
One of my own NancyFX projects does just this to drive a GPS module connected to a RaspberryPI single-board Linux computer.
I use the setup to get an accurate atomic clock using the GPS satellite network, from a GPS receiver attached to the roof of my house. My custom Nancy-based server implements the custom verbs Time and Drift, which I use to get the current time and time drift distance, respectively.
Nancy does everything it can to make implementing a sensible REST-based language as easy as possible, which means in the age of the "semantic web," you can now make HTTP endpoints that genuinely describe their own meaning, and it can be as easy or as difficult as you need it to be.
Should you immediately go out and replace your existing REST framework with Nancy? Well, that depends entirely what your objective is.
Because Nancy plays amazingly well alongside most (if not all) of the other REST frameworks available, you'll likely find that you can easily continue to use your existing technology while introducing Nancy-based technologies seamlessly.
I have upgraded projects using Nancy where the users of the associated interfaces had absolutely no idea that their interface had changed for the better. I achieved this by building out all new functionality from a defined point onwards using Nancy. As this was completed, new versions of the original functionality were also built using Nancy, but with slightly different URIs.
At a predefined low-use time, the new URIs were renamed to map to the old URIs, and the entire project deployed and activated in a very short space of time, resulting in identical functionality, but with much-improved performance.
In this chapter, you saw some of the ways Nancy works amazingly well as a replacement or supplemental addition to your current REST framework. In the next chapter, we will continue this exploration and see how Nancy makes an equally good addition to a general-purpose web framework.