It's been a while since I visited this subject (at least in my blog) and I've still to record a lot of screencasts around Nancy. Anyway I thought I'd give a quick mention to Anna that has just come up on my radar. Now the project is still in the very early stages but it's possibly one of the best uses of Rx and worth a quick look. Now I am a bit rusty in the old Rx stuff so sorry if I say something stupid.
Getting Started - Hello World
Anna aims to be an asynchronous event-driven HTTP server in a similar vein to node.js. At it's core is the HttpServer
object that allows us to wire up routes.
There is no configuration required - just install Anna from the Nuget Package Console via Install-Package Anna
and you are good to go. Just create a console application with the infamous Program.cs
and a few lines of code gives you the Hello World
solution,
using (var server = new HttpServer("http://localhost:1234/"))
{
server.GET("/").Subscribe(context =>
context.Respond("Hello World"));
Console.ReadLine();
}
I added the Console.ReadLine()
to stop the console app exiting and cleaning things up. Running the app and going to http://localhost:1234
gives you the result. The HttpServer
object has a number of methods for the various HTTP verbs and these methods all return instances of IObservable
which means you can subscribe to them and apply all those filters, transforms etc. the Rx offers.
Other Anna Features
As I said Anna is still in the early stages so once you grab a route there isn't a MASSIVE amount you can do with but respond. Responses however are chainable so you can create an almost middleware like stack for requests e.g.
var route = server.GET("/");
route.Subscribe(context => context.Respond("Hello "));
route.Subscribe(context => context.Respond("World"));
This gives you the same output as the original Hello World sample.
But from what I can see thats about as far as you can get. In node.js there is a framework called Connect now I'm not sure if Anna is intending to go in this sort of direction but I think it could be moulded into something like this with a bit of TLC. The problem is at the minute I don't see any sort of object passed along the subscription chain e.g. a dynamic
bag or something. I don't even know how to easily manage response headers.
Routes and Route Fragments
Anna supports creating different routes including routes with dynamic sections /name/{name}
that are used to populated a UriFragments
property,
server.GET("/hello/{name}").Subscribe(context => context.Respond(
string.Format("Hello {0}", context.Request.UriArguments.name)));
Conditional Routes
Thanks to the power of Rx and Linq it is possible to create conditional routes an create chains that have pre-response checks. For example we can have a route that only triggers a response if the QueryString has a secret parameter.
var route = server.GET("/");
route.Subscribe(context => context.Respond("<h1>Hello World</h1>"));
route.Where(ctx => ctx.Request.QueryString.secret == "letmein")
.Subscribe(ctx => ctx.Respond("<h2>Secret Message</h2>"));
So if you hit http://localhost:1234/
you get Hello World. Hit that again with the param ?/secret=letmein
and you get the super secret message.
Conclusion
Thats about it for now but I think I'll be keeping an eye on this project and see were it goes. Even though it's still early days I like the concept behind the library and the fresh approach it's taking. I'll push some of my sample code up to Github and update this post in the next few days. In the meantime Jose the creator of Anna has some nice examples of Rx based HttpServer stuff on his blog featuring a long polling example.