A NancyFx Content-Negotiation Extension

March 2nd, 2012

You have probably already heard about Nancy, the web framework created by Elegant Code’s own Andreas Håkansson. Andreas and Steven Robbins, custodians of the Super-Duper-Happy-Path, have coordinated the evolution of the framework that I have come to very-much appreciate.

My coworkers and I have been working on a new API for our products, and Nancy has been our framework of choice. One thing we know we will need for the consumers of the API is content-negotiation. Currently, Nancy does not have content-negotiation built in to the framework; although, it is planned for a future release.

Content-Negotiation is the process in which a User-Agent and Server determine which, if any, of a weighted list of preferred representations is returned in response to a URL request. The representations are often based on MIME type, but can be based on language or encoding. In the case of our API, we are concerned with MIME type; specifically, JSON vs. XML.

Even though Nancy does not have content-negotiation yet, the Nancy team has been prepping for the feature by adding support for weighted Accept headers. This makes it fairly trivial to add content-negotiation on a per-route basis.

After some experimentation (including creating a pipeline handler, though it was admittedly ugly), plus a couple of conversations in the NancyFx Jabbr room, I came up with the following extension method:

Did I mention how easy it is to extend the functionality of Nancy? I am sold on the Super-Duper-Happy-Path!

imageDon’t forget to attend Boise Code Camp on March 24, 2012!

Amidst all of the awesome sessions submitted by the community, I have submitted a session on getting started with the Nancy framework.

  • http://www.grumpydev.com/ Steven Robbins

    Nice one :-) I’m not 100% sold on the syntax, but it certainly does the job.

    It might be nice to shove it up as an “unofficial” nuget (like the Cassette support is) so people can just Install-Package Nancy.Conneg and get access to the extension method.

    • http://codeprogression.myopenid.com/ Guest

      I’m not 100% sold on the syntax either.  I like the default response as a delegate, but I need the content type to compare with the accept type. I blame Andreas for putting the Func in my head. :)

      • http://twitter.com/TheCodeJunkie TheCodeJunkie

        The Func suggestion was to avoid invoking the IViewFactory (note that’s not the same as actually rendering the view) when your execution path did not result in the defaultResponse from being passed back.

        The IViewFactory will go out and find the view to render, what engine to use and to prepare the model, then setup a delegate around the engine to do the rendering if it’s invoked.

        While it’s probably not too performance heavy, it makes sure non of that is ever invoked unless absolutely needed.

  • http://twitter.com/TheCodeJunkie TheCodeJunkie

    Cool that you got it working =)

  • http://lopezunwired.com Paul Lopez

    I had a lot of people re-tweet and favorite this link. Good stuff on Nancy! 

    • http://elegantcode.com Richard Cirerol

      That’s awesome! Thanks for the support!