I’ve been proclaiming the greatness of OpenRasta to anyone unfortunate to start talking to me about web development recently. I thought it was about time that I recorded the reasons I love it so much somewhere everyone can see.
OpenRasta is by no means a finished product but it has principles at its core that I value greatly and give it massive potential.
Unless you’ve been hiding under a rock for the past few years you’ll know how important I and many others think testability. If you don’t know why it’s important I suggest you go and check out Scott Bellware’s blog. He has written a series of post recently about how accountability and constant verification are vital in the search for productivity.
OpenRasta has been built with tests from the ground up and this fact shines through throughout the code base. I’ve never seen a code base like it; it’s beautiful. The entire framework is a testament to SOLID design principles which means extending it is childs play. When you’ve been used to frameworks like ASP.NET MVC where you will end up coding yourself into a sealed or extremely hard to test corner; OpenRasta is like a typhoon of fresh air.
Building upon a testable framework makes your code easier to test. For example, how many magically bound properties do you think your handlers (the equivalent of controllers) have? Zero. Zilch. They don’t even have an interface, never mind a base class. I’ll let you digest that one for a moment. No base class, no monolithic controller context, no magically appearing model state.
So what happens when you want to look at the details of a request or any of the state that OpenRasta has created as part of your request? OpenRasta, to enable it’s testability, revolves around a dependency resolver. All the details of the request are registered to this dependency resolver so all you need to do is take the relevant interface (yes I did say interface, not class, welcome to a world where everything you wish had an interface does) as a dependency to your handler. It really is that simple.
From the testablity you get a great deal of extensibility. There are several ways to jump in at various points of the request in order to manipulate it. The main ones are pipeline contributors and operation interceptors which I’ve shown how to implement before. OpenRasta comes with a default set of contributors and interceptors but gives you the ability to remove or replace any of them. Sure you can get yourself in a real mess if you don’t know what you’re doing but I like my tools sharp, powerful and dangerous. Especially something as pivotal as the framework I’m building upon.
You can of course implement your own binders, URI resolvers, etc. if you so wish. You could alter OpenRasta to work just like ASP.NET MVC if you desired. Though I wouldn’t recommend it!
As part of extensibility you can’t overlook the fact that this is true open source. Wish there was an enhancement to the core of OpenRasta or an extra method on an interface? Discuss it on the mailing list, code it (with tests of course) and submit a patch.
What I want from to see from a web framework is a deep understanding of web standards and the HTTP protocol. You will not find many people who know more about RFCs and HTTP than Sebastien Lambla, it’s actually quite disturbing how much he knows about them.
OpenRasta revolves around resources not controllers, generating URIs from types and individual objects rather than strings or at best lambda expressions. This takes a little time to get used to but it’s more powerful and easier to test. Why is it easier to test? You probably saw this coming but URI resolution is of course done behind an interface. Ahhhhh. So much easier than mocking a controller context.
OpenRasta also ships with content type negotiation. Your handler operations (akin to controller actions) return straight resources or operation results with a response resource attached. How this resource is returned to the client is a entirely separate function. Want to get a response in JSON instead of XHTML? Add .AsJsonDataContract() to your resource registration and just ask for it with the relevant Accept header. OpenRasta will transcode your resource to JSON for you and return it to the client.
There’s a growing following for OpenRasta, it’s being presented by Kyle Baley at MIX10 and this has caused the lovers of OpenRasta to pull together. We’re intending to improve the documentation giving more example of it’s use and generally helping Seb knock the edges off what is a great framework.
The OpenRasta mailing list is very active with people providing very rapid responses to any questions. If you uncover a bug Seb will often have a fix committed the very same day, with regression tests of course.
In the near future I’m going to churn out a series of blog posts or perhaps screen casts showing how I leveraged vanilla OpenRasta to create a simple wiki. Hopefully, this will help more people get started with OpenRasta.
If there’s anything in particular you’d like me to cover leave a comment below.
I’ve been looking into rails recently, partly to learn rails itself, partly to try and gain inspiration for the direction to take both the framework we use at work and Jamaica. It’s triggered me to question a lot of things that I’m doing in .NET so I’m going to attempt to record my thoughts.
Having testing and persistence baked in
One thing that has struck me is that I’m watching railscasts from years ago and they are demonstrating solutions to problems ASP.NET MVC is struggling with now. It really does have testing baked in but often not through the use of abstractions, instead they have made integration tests easy to write. It appears the entire request can be processed in memory without having to fire up a server all the way through to rendering the view. This is something OpenRasta is capable of and one of the reasons I get so excited about it.
Another benefit rails has is that it comes with a “model” baked in. This is something that is sorely lacking from ASP.NET MVC. Whereas the .NET world (particularly the ALT.NET sphere) favours NHibernate for persistence, they instead use a simple but well implemented active record implementation. Why have they chosen this? Partially because it works so well with a dynamic language, everything is DRY as code can be generated from the database at runtime. It’s also damn quick, something that has always bugged me about NHibernate is the 10-20 seconds it takes to create the session factory before you can get started.
Because NHibernate is so powerful and configurable it can quite frankly be bloody confusing for most developers, I get asked to help with problems almost daily. With active record everything is kept simple, this object is a row in that table. There aren’t often complex mapping files, it just works. Rails’ active record implementation has a layer of syntactic sugar based around pattern matching on missing methods which looks nice and works well. However, in .NET we have LINQ which is statically typed, very powerful and can serve the same purpose.
Why do we chose NHibernate?
The reasons given for choosing NHibernate are persistence ignorance, reducing the impedance mismatch, amongst others. Why do we insist on ignoring the fact that our applications are running on top of a relational database? What ever happened to embracing the technologies we are using to get the best out of them?
NHibernate lets you persist your domain models directly. So what? Who’s domain models are that much beyond dumb data stores in reality? I’d bargain it’s a hell of a lot less than those that claim to be doing domain driven design. Also, why does your domain have to be persisted directly? Why couldn’t you provide an empty domain object with a few active record objects and have it process them and spit other active record objects out the other side? Something CQRS-ish. Then your domain would contain nothing but business logic.
What does this mean?
I’m looking away from NHibernate, no tool should be chosen without question, even the great NHibernate. I just don’t think it is serving my needs as well as it could so I’m going to look for alternatives. Subsonic is top of my list, followed by revisiting LINQ to SQL, hell I might even take a look at the Entity Framework.
While we’re at it, why do we chose relational databases without question? I’ve been working with Lucene.NET a lot recently, it’s really easy to use and you get full-text indexing for free if you were to use it as a data store. Only want to deal with aggregate roots? Store all the data of that aggregate root in a single document, it can easily emulate nested structures.
Random deviation onto REST
I’m also being influenced by how REST appeals to me. It seems like a simple yet powerful way of dealing with the web. If we consider everything we work with as a resource, a representation of an idea, why can’t that representation be stored as an active record? The transition of an idea between resources could actually be a record transferring between tables. The old representation could even hold a reference to what the idea became, allowing you to redirect to the current representation. Hell, wasn’t the web made for storing and linking documents before it got bastardised into the beautiful beast we have today? Perhaps a document database would be ideally suited!
Pain points of ASP.NET MVC
Talking of REST brings me back to another problem I have with ASP.NET MVC. The routing revolves around controllers and actions rather than the resources and HTTP methods. In order to generate URIs, you will at some point end up having to manipulate strings or create anonymous objects. How do rails and OpenRasta deal with this? By using resources and their types to determine the URIs. This is so much more powerful and dare I say easier to use and understand. I can see it empowering the use of generics within .NET and it cuts out a hell of a lot of crap around URI generation.
Ah, cutting out the crap. ASP.NET MVC is testable, until you want to test something that isn’t a just a controller action. Like a HTML helper, URI generation or store the IP address of the request. Most of these things are kind of testable, but you have to mock out a complex object graph like HttpContextBase or ControllerContext. “We got rid of HttpContext.Current and replaced it with something slightly less monolithic and slight less sealed, go us!”. Know how OpenRasta deals with this? It has dependency injection at it’s core and there’s an interface that lets you retrieve everything you need, either separately or together. There’s everything from IRequest to ICommunicationContext (the equivalent of ControllerContext) and everything in between. You need it, you can retrieve it and it’s bloody easy to test.
There’s a lot of random ideas here, I can’t say which I’ll end up using. Perhaps none of them, perhaps an unforeseen combination. If nothing else writing this down has helped me distil a few of them into clearer thoughts.
Here’s to questioning everything you believe to be true.