I believe the fundamental problem centers around state. At Atomic Object, we tend to have an allergy to state, and for good reason: as you keep more state, the complexity of your logic increases, the testability of your code decreases, and unforeseen interactions become more likely. Without keeping some state, however, it becomes harder or impossible to do practical things.
The problem with the CGI way is that the state of your application is bifurcated between client and server and exists in different places at different times. The server is responsible for building most or all of the interface, but must start fresh with each request using only persisted and request data. Objects are required to be short-lived to the point where it becomes a handicap. For a good example, think about the subtle problems with multiple ActiveRecord objects representing the same row in a table, or where inserting
my_record.reload was the fix for a problem.
On the other side, the client takes its turn keeping track of the information required to make requests back to the server. A significant effort goes into passing this data back and forth, and as applications become more dynamic on the client side, so does the need to re-architect models for the client side. This duplication isn’t ideal and can be very frustrating.
A trend has been slowly emerging where newer frameworks such as Cappuccino and Ember.js are beginning to address this problem. Moving more responsibilities to the client and reducing the server to an API is an excellent idea, as it consolidates state on the client side and helps force your server API to be well-defined. I’m excited to see how this trend continues and what new frameworks appear in the future.