Don't Choose Your Middleware Language or Architecture: they are consequences

I'm writing web applications and need to decide on every piece of technology involved. What are a logical set of choices?

I want the client-side barrier to be as low as possible. By default this means the client-side will be HTML, CSS and JavaScript. I won't be using Flash or Java Applets.

On the server-side, I want the data stored in a proven reliable system. There are many technologies on the rise (e.g. CouchDB) but right now it seems that a relational database management system (RDMS) like PostgreSQL is the solid choice. Data storage is not where I want to be on the cutting edge.

So what do the above choices this mean for my server-side middleware language and architecture?

Don't repeat yourself (DRY) is an good programming practice. If the same logic must be shared on the client and the server then how will that be done in a DRY manner? If the middleware language is not JavaScript then the code could be written in the middleware language and compiled to JavaScript. This is a debugging nightmare since the client-side involves many different implementations each with many different bugs. Debugging compiled code and finding the error in the source code in different languages is not a welcome thought. Another option is to write an interpreter in JavaScript for the middleware language and then run that interpreter in the browser. Client-side performance would be very poor. With either of these options there is a whole lot of code that must be written (i.e. compiler or interpreter) before I can start programming my business concerns.

DRY is about more than just sharing source code. Needing to switch between two languages all day long means repeating the process of becoming an expert in two languages. Knowing multiple languages is a very good thing and I've studied several at least at an introductory level; however, becoming a true expert in a language takes years. One day I might be an expert in just one language. It makes sense to me to get the most return on my invested time and learn one language well and program production code better on both the client and server sides rather then splitting my time between two languages and writing mediocre code everywhere.

So my server-side language will be JavaScript which, though not my first choice, just so happens to be a fine language.

Persisting data in the database is a fundamental activity of a web application. The object-relational impedance mismatch is well known and a result of choosing an RDMS for its strengths but still wanting an object-oriented programming paradigm. An object-relational model (ORM) is used to bridge this gap. Since the gap is reasonably wide, the ORM is a substantial piece of software. This is another big piece of software that needs to be written before business logic can be expressed. There are many ORMs available but whenever the object model doesn't quite match a normalized database schema for some complex data the whole deal seems to fall apart and it is a great struggle to wrestle the ORM into submission.

There are many examples of data sets which we manipulate daily without an ORM. For example, the UNIX operating system provides all sorts of tools for you to create, read, edit, move and delete the files on your hard disk. When you are at the terminal command line and use ls -l you receive rows of data you then loop over or pipe to grep. This is not object-oriented and it works well. In our server-side programming of a web application, why don't we just build tools (i.e. functions) which abstract database access and operate on sets?

So I won't be using an ORM. I'll embrace the idea of sets.

My choices of client-side and data storage technologies have driven the resulting middleware language and architecture. It is more common that developers do it the other way around. For example, they first decided to program the server-side in Java or Ruby with a very object-oriented style because they like that language and style of programming. Then to indulge this whim they must develop thick adapter layers on either side of this middleware to interface with the database and client. Witness Hibernate and GWT in Java or ActiveRecord, RJS and HotRuby in Ruby. Something is wrong with the order of decisions being made if they results in a need for such large adapters layers to apparently "make things easier." It seems to me better to go with the flow of constraints outside the middleware layer will result in a much thinner middle layer.

Maybe JavaScript is not my favorite language but as consolation at least it has lambdas. Dealing with sets may sometimes be a bit more work or sometimes less than dealing with objects. Most importantly the other options for middleware language and architecture involve far more work, software and bugs.

(No need to bother with the "What about the libraries?" issue. I know the Perl folks are dedicated to CPAN and dying to bring this up whenever they can. If I wasn't writing for the web then JavaScript wouldn't be the default language. I'd probably be using C or Scheme (but I certainly wouldn't be using Perl!) Anyway, wrapping jars for Rhino is a snap so the point is relatively moot.)


Have something to write? Comment on this article.