A couple of months ago, I was innocently asked by co-worker, author, F# MVP and all-around-nice-guy, Jamie Dixon if I wanted to participate in a work-based hackathon for the weekend. I naively said “sure!” Well, we ended up winning 1st place and part of first place was that you then had to bring that idea to production. We just did one of our final drops to production, for a bigger roll-out later in the month – and I thought I’d write down what I learned.
Hackathon vs Rapid Application Development:
The first thing I realized, which causes some problems, is that the motivations and incentives are different, when you are just trying to “crank out an app” in a very short period of time for a hackathon, versus doing legitimate development for a real app.
Now, you might say: “what do you mean by that, isn’t all of your code production quality? You don’t have two ways of writing an app, do you?”
Let me clarify. I do definitely try to always write production code. However, in the example of a hackathon, where you literally have hours or minutes left – there will be many more shortcuts taken, versus what would be tolerable in a production environment. But wait, that wasn’t even our problem. Me and Jamie both believe in writing good-quality code and trying to keep the codebase as clean as we can, regardless. The problem was that in a Hackathon, you want the most bang for your buck.
So, we used some previously unproven technologies to try to be as innovative as possible. This is great for a hackathon; and horrible for a production app!
This ended up being one of the main problems. I’d done Hello, World! functionality with these technologies before, but haven’t taken an app to production with them before, and not together.
Put another way, if you are starting a new app, you want to embrace some innovation, integrate some new technologies, but if the WHOLE APP is nothing but cutting edge stuff, you are setting yourself up for a world of hurt! This is bad because newer technologies aren’t going have as good documentation, and there isn’t going to be nearly as much on StackOverflow.
This is the crux of the problem. You take one approach for a hackathon, and you take a different approach for a production app. Because we wrote this as a hackathon app, this really killed later on!
So – if you are coding a hackathon, then use all cutting-edge stuff if you want! But if you are writing a brand new app, use mostly-known technologies and leverage one, maybe two new things, to keep your sanity. In our case, we shot ourselves in the foot because we used all innovative things (to us), but then had to suffer the learning curve of quickly bringing them to production!
The Architecture of the app:
This was an app around people self-reporting campaign contributions. This means that we needed:
- Web front-end
- A database
- A rules engine
So, what we used was:
- Authentication – used SiteMinder, because OAuth would’ve taken too much work
- Authorization – used Web API custom attributes. There will be a future blog post on that – lots of lessons learned.
- Look/feel – bootstrap, because that’s my go to technology for that
- UI Data binding/UI logic – AngularJS v1.x
- REST API – ASP.NET Web API
- Database access – Code-First Entity Framework with the Repository Pattern
- Database – SQL Server (code-first, push changes when the app runs, and re-seed known values)
- Rules engine – very small amount of curt, complexticated F# code. I don’t really understand it, so you’d need to talk to Jamie about that one – or maybe he’ll be doing a blog post on it?
One of the biggest unknowns was the viability of using AngularJS for a tediousness of a production app. It’s great for simple stuff, but what about when things start getting nasty and you need all sorts of special cases, like you do in real code. How well does it scale?
In this case, we did build this as an AngularJS single page application (SPA), which uses AngularJS client-side routing – which has some pros and cons.
However, it’s not as simple as that. A big benefit of object oriented programming is that you can easily manage and abstract dependencies – via interfaces. A big benefit of functional programming is you can do the same, but with function pointers. With these professional-level languages, you can purposely create a well-managed codebase.
The good things:
Some things which I think work really well in this stack that we used:
- Entity Framework – we came up with some good, creative ways to deal with .Include(“..”) statements to make sure you’re bringing back the smallest graph of data possible, for each call.
- Repository Pattern – I still remain convinced this is the most-ideal way to abstract-away Entity Framework. For God-knows what reason, there is still no IDbContext or IDbSet so you can’t effectively mock any away your database. It’s crazy, but to get around that, having a simple repository interface makes everything downstream, completely testable!
- Web API – the patterns for Web API are pretty good – and the built-in support for giving back standard error codes was helpful too. We came up with some great, small, succinct code for our REST API.
- Bootstrap + Font Awesome – both of these made it very easy to lay out professional-looking, consistent pages, with appropriate icons. No complaints, here!
- AngularJS – this framework does the routing of the requests and the data-binding. On both fronts, it does this well, generally. There are some notable exceptions though, listed below.
Overall though, this collection of technologies worked very well together and development went VERY fast, despite the learning curve.
The bad things:
If the app was built pretty quickly, where did all of the time go? Well, it was troubleshooting problems. Looking back, here are the biggest problems I’ve had:
- AngularJS – maintaining state (at the site level) – although you can use $rootScope to keep track of the current user, we never came up with good techniques for figuring out when the user is logged-in, when we got their user info back from the REST call, and detecting if there was any change in that. In other words, sometimes the site is awkward when it first loads and it takes 4 seconds for the user information to populate.
- AngularJS – maintaining state (at the page level) – this isn’t so much difficult, but it just got to be unwieldy. Since your $scope object for that page is available to everything, it basically acts like a global variable. Global variables are inherently difficult to keep contained, and other actors can unexpectedly change a value.
- AngularJS – dealing with a DatePicker ending up being a 2 day ordeal. Despite there being AngularUI and countless implementations, I didn’t find any that worked correctly AND which worked on all browsers. I ended up using a raw jQuery UI data picker, and $watch-ing some events. It does technically work, but it’s a mess, every place I need to have a date field.
- Performance when developing locally – I still have no idea why, but locally, all of my REST calls took just about 5 seconds. On the server, it would be sub-second. So, this made local development slow and annoying. The workstation I worked on was an i7 with 16GB of RAM and an SSD – it wasn’t a simple resource problem.
So although development did move quickly, there were some significantly frustrating problems that came about too.
The other thing is: should you use single page applications with AngularJS routing? Well, again, for a simple app – I think it’s kind of ideal to do it that way, because it can be executed pretty nicely. However, for a medium to large app, I think the way to do would be to use something like ASP.NET MVC to provide the structure of the site and initial HTML – and then use AngularJS on those specific pages, to make each one of those views dynamic, by using data binding and REST services.
Having done web development for 20+ years, I will say that the current state of the art is the best it’s ever been. The developer can be so productive, with so little code, in comparison with yesteryear. So, although I found some limitations with AngularJS – I still think it’s a pretty great framework.