In our last post (http://mercenarytech.com/2013/07/why-django-framework/) we covered Django framework. Django is a fine choice, with module and configuration organization as its biggest strength. If it fits your requirements then it is a safe choice; it’s certainly popular. But, my experience has been that in practice it doesn’t actually offer much benefit. When given a choice (and based on project requirements) I push customers towards Tornado Framework. In this post I will talk about the reasons.
A Little Strategy
When I evaluate application frameworks technically, I’m generally looking for:
1) Features that will buy time or at least not cost. Sometimes simplicity is better than sophistication.
2) Assumption on the part of the framework architect that do not fit my roadmap. These become the corners we paint ourselves into.
3) Deployment or user experience compromises. Are there any the framework is asking me to make? Again, see point #2.
Thus, when I’m thinking about the future technical direction of an application, features like automatically generating template code, say for a Controller class, are interesting, but that is something I can automate from an IDE. It may not buy me much as a part of an application framework. Sure, if I can save 30 seconds by generating boilerplate code, especially if I will potentially write that same boilerplate code 1000 times in the life of that project is useful, but in part I judge a framework on not having to write that boilerplate at all.
Simplicity counts for a lot in my book. Take Controllers again. A Java framework like Spring contains many types of Controllers, where you have to learn something about each kind in order to subclass the right one. Tornado contains two – one for http, one for websockets. The User model in Django is another example of this. Depending on your version of Django, the process for extending the User model is different and requires understanding the internals of Django to correctly modify. With Tornado, there is a get_current_user(), you simply override it with whatever representation of user you wish – could be as simple as a cookie.
Where Django and Flask don’t make sense to me is they seem to assume I’m building a web application that will serve up html pages, and in the case of Django, have a significant administrative component. There’s a further assumption that my application will be monolithic in nature and that I need an MVC framework tightly coupled to a persistence layer. This is not how applications are being constructed today. Applications have moved on from that model, with real-time push technology (like websockets) becoming commonplace, and ever more functionality pushed to the client side. Thus web applications that a generation ago would have rendered pages from the server are instead feeding json from the server to a user experience rendered entirely in the browser, which in turn is more commonly a mobile device. Django and Flask are not offering anything unique to this style of application apart from a convenient way to organize your source code.
The Io loop / event model in Tornado is sadly overlooked. Tornado’s detractors would claim the moment you have to do something concurrent (fetching from a database is often used as an example), you lose the benefit. This is a false assumption though, for three reasons:
1) There are asynchronous drivers available for many databases and queues.
2) This assumes a monolithic stack, where the app needs to make a direct connection to the database (likely false as you scale)
3) This ignores real data (google it) that Tornado is significantly more performant than Apache with wsgi (for example).
On the last point, I’d challenge that setting up apache with wsgi is not difficult, but is more effort than Nginx with Tornado, for lesser performance. So why choose Django or Flask when that’s the standard deployment practice?
Tornado provides a basic template system, internationalization, simple organization, and python itself gives you parsing (json, XML,etc) and logging, no framework needed. SQLAlchemy is at least as full-featured as Django ORM and integrates well. On top of this you get a high performance http server and mature websockets support. Thrown in a built-in asynchronous http client and you have a framework that doesn’t get in your way but does give you the pieces to build functionality quickly. Thus for me, the power of Tornado over other frameworks is that it offers just enough and does not make any assumptions about the kind of applications I can build.