The ideal full-stack webapp framework?

I have been exploring several web development platforms for quite a few months now. It is not that there is a shortage of great frameworks out there (I am not averse to learning a new language in order to use a good framework), and I did play around with a few really good ones, but I have a few stringent conditions that I want the framework to satisfy:

Multi-tenancy

Since my goal is to build an application that provides hosted services to multiple organizations, the framework must be one that treats multi-tenancy as a first class member in their feature list. There’s always scope for some heated debate on whether multi-tenancy is the best approach, especially when it comes to isolating data between multiple clients. One of these discussions, which I found quite informative, is this.

Multi-tenancy is definitely not the best solution for all usage scenarios; one could argue that multiple single tenant databases are easier to scale out horizontally. However, scaling out is not entirely impossible with the multi-tenant model, and it does save me certain overheads like multiple-maintenance of common configuration data.

My reasons for opting for multi-tenancy are the lowered upfront and recurring infrastructure costs compared to running single-tenant-per-db solutions, and an easier maintenance/upgrade path. However, since the job of isolating data between clients is managed exclusively at the application level, that implementation has to be absolutely water-tight.

Native Application State

‘Shared-nothing’ platforms, like PHP, do not have a built-in application state. Once again, it is ultimately a matter of opinion as to whether or not this is a good thing, but I personally prefer systems where the bootstrap process ideally takes place just once in the lifetime of the application.

Devoid of a native provision for long-lived objects, a stateless platform has to bootstrap the entire framework for every single request that it processes. This is because all objects, class definitions, and all compiled bytecode in general, are restrained to scope of the request itself. While this does make thread-safe programming a no-brainer, it incurs a severe overhead for having to rebuild the object graph and other data structures in memory for each request (even those whose data are request-independent). No wonder it performs very poorly when compared to a platform like Java, in which an object once loaded into memory (even when triggered by a request) can legitimately outlive the request itself, thus saving time while processing future requests, since they can reuse this loaded object.

The lack of an application state can be offset by using op-code caches like APC (for PHP) which can cache compiled bytecode, and even objects across multiple requests (Note that doing this essentially violates the shared-nothing principle, one of the fundamental tenets of PHP). Memcache-based solutions can also be used as an alternative to, or in conjunction with APC. However, these solutions are not built into PHP, and thus require additional modules and/or coding in order to use (this also means there is additional code to execute). Expiring externally cached objects is also a non-trivial issue, since a separate garbage collector must be designed for that. At the end of the day, nothing can beat the speed of directly accessible, in-process-memory caching (with no protocol overheads) that native application state offers. Here’s an interesting Q&A with David Strauss, creator of Pressflow (essentially Drupal on steroids). Just the following excerpt from one his answers should drive home the point:

Because the overhead is largely on the PHP side, Pressflow is exploring ways to accelerate common functions by offloading select parts of core to Java (which blows away PHP + APC on a modern Java VM) and performing expensive page assembly and caching operations with systems like Varnish’s ESI and nginx’s SSI.

No prizes for guessing what gives Java this performance edge ;-). Even a simple PHP application needs help from external caching, and other auxiliary mechanisms in order to satisfactorily serve anything more than a handful of requests per second.

Independently accessible service layer

Say we have an application up and running, and it needs to be accessible though multiple devices, and over multiple channels like HTML, REST/SOAP, RSS and what not. Most platforms come pre-packaged with a scaffolding system for building the presentation layer on HTML by default. This is not a bad thing in general, except when I’m accessing the app from something other than a web browser, such as a mobile app with (screens built in), or from another webapp. In cases like this, I would like not even the slightest overhead to be incurred in loading and building any part of any presentation layer that is not required for serving these requests.

This is possible only when the framework has been designed from ground up with ‘headless’ operation in mind. Basically this translates to a totally detachable service layer that can be invoked independently of the default presentation system.

Lightweight domain objects

I’ve come across a few excellent frameworks that do something I find really strange, and the reason for which escapes me. Their domain modelling paradigm dictates that all business logic pertaining to a specific domain model be contained in the model itself. Really??! In cases where one is building large lists of objects of a particular ‘heavyweight’ domain class, this embedded business logic is simply bloating the memory usage. Now I get the part about static methods and variables (before the slingshots come out ;-) ) which are instantiated just once per class and not per object, but static members were designed with different architectural goals in mind, and not specifically as a memory saving construct. Hence they do help reduce the overhead somewhat, but not by much (every object still needs to maintain pointers to reference the static members).

Another problem is: where do you put logic whose concern spans multiple domain classes? Or has nothing to do with domain classes? Neverending source of confusion, that.

I would rather go for a design which treats domain objects as simple data beans, with no more than the simplest validation rules built in. The heavy lifting of business logic should be borne by a dedicated service layer. This approach also simplifies the implementation of independently accessible service methods that I outlined in the previous section.

Pluggable storage backend

This is a short one. Most frameworks support interchanging one RDBMS with another fairly smoothly. I want to throw NoSQL stores into the mix. I want to be able to plug in MongoDB or Couchbase, for instance, to supplement the RDBMS with certain functions that NoSQL DBs excel at, but I don’t want to change the way I use the persistence layer. Whatever the technology I use for abstracting the storage functionality in the application, its API must let me work seamlessly with non-relational data stores as well.

Summary

That more or less covers my wishlist of things I’m looking for, in a web framework. In order to keep the title short, I didn’t mention it has to be open source as well (yes it does :-) ). I think I might have found one that manages to check all boxes on the list, but I’m open to suggestions.

  1. #1 by Swaraj Yadav on January 23, 2013 - 10:00 pm

    Very thoughtful post and about time when I was also planning to document my wish list and common abstract from various web development projects I have done. …keep me posted.

  2. #2 by anjan bacchu on January 31, 2013 - 10:57 am

    HI there,

    I look forward to hearing more about the framework that checks all the options.

    BR,
    ~A

  3. #4 by Frisian on January 31, 2013 - 1:11 pm

    A rich domain object model should reside behind a business layer. Ideally, the presentation layer makes one call per UI function to the business layer, which in turn loads the necessary domain object(s) from database and invokes the appropriate methods on them. A transaction should be started before the call and it should be committed or rolled back depending on the outcome after the call.
    There will always be operations, which don’t fit in the domain model as such, e.g. “Delete all orders prior to a particular date”. They should be put into stateless service classes, that should be only invoked by the business layer, too.
    Even though DDD (http://en.wikipedia.org/wiki/Domain-driven_design) is meant for the business layer, some stuff can be used in the presentation layer as well: Value objects like Percentage, PostCode, or CustomerNo should always be in a valid state. Obviously, that means they should be validated at construction time. With some presentation frameworks you can reuse this validation logic to do field validation in forms.
    The next step would be to use Data Transfer Objects for communication with the business layer. These DTOs can contain the validation logic for mandatory, optional or dependent fields. Once again, with meaningful exceptions, you can use the outcome in the presentation layer.
    Doing most of the validation inside Value Objects and DTOs has implications for the business layer, too: It becomes a kind of Green Zone, where not much validation is needed anymore. The domain objects should effectively become lighter and shorter.
    BTW, DTOs come in really handy if you need an audit trail. Save them to the database after a successful business layer call and you know what was done when and by whom in your application.

    • #5 by Aditya Mukhopadhyay on February 13, 2013 - 8:16 pm

      Hi Frisian,
      Thanks for the analysis. You have really provided quite a good deal of detail and insight into the matter. I particularly liked the idea about using DTOs for an audit trail. This, I must confess, was new to me.

      Sorry for the late response, but I hope to see more inputs from you on this blog.

  4. #6 by Christian on January 31, 2013 - 10:07 pm

    I suggest to look at http://www.playframework.org/ You can choose Hibernate to have multi-tenancy, it is stateless but the application keeps running between requests, it has a great template engine and many other nice things. And the best is, that it supports hot-reloading during development.

    • #7 by Aditya Mukhopadhyay on February 13, 2013 - 8:24 pm

      Hi Christian,
      Thanks for the info. (And sorry for being late as hell in replying.) I just had one question – from your personal experience, how easy or difficult is it to learn and work with Scala? I’ve seen some people on the forums describe it as too esoteric and austere for most web developers, leaving it suitable only for academia. I would like to know your thoughts on this. I think the play framework will let a developer work directly with Java as well, but I’m also sure the developer would like to leverage the higher level constructs that Scala no doubt provides, in order to get cleaner, maintainable and readable code. What do you think?

  5. #8 by Subodh Nijsure on November 2, 2013 - 12:14 am

    Hello Aditya,

    You mention in above blog that ” I think I might have found one that manages to check all boxes on the list, but I’m open to suggestions.” so what was the framework you liked that met your criteria?

    • #9 by Aditya Mukhopadhyay on November 6, 2013 - 1:54 pm

      @Subodh

      Spring Roo is pretty good if you’re working on a Java-based environment. Also have a look at the up and coming Vaadin framework, which boasts built-in GWT integration.

      On Node.js, you would find Mojito (by Yahoo!) to be a good pick.

      None of the above frameworks are inherently multi-tenant, btw.

      If your product is centred around providing ERP or Ecommerce functionality, then definitely give Apache OFBiz (again Java) a try. It comes with multi-tenant support out of the box.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 386 other followers

%d bloggers like this: