A few months ago I put up a site http://hypermediaapi.com with the intention of using it as place to aggregate links to all things hypermedia related. I built the site using Web API because a) I know how to use it, and b) I wanted to prove a point that a Web Site is really just a special type of Web API.
Anyhoo… I ran into an issue because I needed to use the server that was hosting the site for another site that was going to be hosted in IIS. To my great disappointment I discovered that the two don’t play nicely together. Apparently when WCF creates a service on a port, it thinks it owns the port. Stupid really, because it uses HTTPListener under the covers which is quite capable of playing nicely beside IIS.
So, to cut a long story down to a medium length story, I went searching for alternatives. I have built a server based on HttpListener before and although it’s not hard to get something that works, getting something that is robust and works well is a whole lot more work and requires more talent/knowledge than I have time to acquire.
I have tried playing around with Katana a couple of times before and failed. It’s been a moving target for a while with the Owin spec only recently hitting a 1.0 release. I noticed a couple of days ago whilst browsing through some Katana source code a project called OwinHttpListener. I didn’t have time to look at it them, but today I decided to have another look. I went hunting for nugets and came up with nothing that worked, so I decided to seek help.
I read Filip’s post here http://www.strathweb.com/2012/12/running-aspnet-web-api-with-owin-and-katana/ which has some great information but it shows how to run the server from the katana.exe or using a System.Web host. I wanted to be able to create my own console app and then my own Windows Service.
Turns out there is a Jabbr room for Owin and GrumpyDev was there and was kind enough to show me how they are using Owin in Nancy. It turns out, once you get the right Nugets installed, and know the simple incantations, it is dead easy to get a self-hosted console based Web API running on Katana.
The trick is to pull in these two packages.
http://nuget.org/packages/Microsoft.Owin.Hosting aka Katana
http://nuget.org/packages/Microsoft.Owin.Host.HttpListener
There is no explicit dependency between the two, presumably because you can use Owin/Katana with servers other than HttpListener, however, by default Katana tries to use the OwinHttpListener as the default server.
Once you have those packages referenced, there is a class called WebApplication that has a static Start method that will get the server going. The code (which is almost identical to what Grumpydev showed me) looks like,
class Program
{
static void Main(string[] args)
{
var baseAddress = (args.Length == 0) ? "http://hypermediaapi.com" : args[0];
using (WebApplication.Start(baseAddress))
{
Console.WriteLine("Server running on {0}", baseAddress);
Console.ReadLine();
}
}
}
public class Startup
{
public void Configuration(IAppBuilder app)
{
var config = new HttpConfiguration();
HypermediaApiConfiguration.ConfigureSite(config);
app.UseHttpServer(new HttpServer(config));
}
}
The only difference between my code and the code to run a Nancy app is that I have app.UseHttpServer(…) and Nancy has app.UseNancy(). Because I had already built my site to be independent of whether it was Self-hosted or run under Web Host, moving it over to Owin required no code changes at all to my site.
So, http://hypermediaapi.com is now running. It doesn’t have much content on it yet, but I am experimenting with a variety of Web API techniques. For example, if you go do
GET http://hypermediaapi.com/Learning
Accept: text/plain
you will get a textual representation of the content. If you go to http://hypermediaapi.com/Learning.atom you will get an atom representation. Most of the pages are served up using Razor templates based on the RazorEngine library. However, I’m also starting to experiment with the Parrot templating engine. The general theming of the site is provided by Twitter Bootstrap which I serve up out of resources embedded in the site assembly.
This is an ongoing experiment to see where self-host Web API falls short when trying to deliver a standard web experience. I’ll keep you posted.