In general, AJAX driven applications are a huge improvement over the classic request/response paradigm where the entire page refreshes for each action. In an AJAX powered MVC framework every time the user does something, the client goes out to the server to persist state or obtain new data. In a simple app with only a handful of entities, no problem. However, for a large scale system with hundreds of tables I have a serious problem:
Excessive service calls are bad because:
A) They slow down responsiveness.
B) They introduce brittleness.
C) They promote poor service layer design.
A) Excessive calls slow the site down:
Often times I visit a site for the first time, and immediately see one or more ‘loading…’ indicators. Major products that do this include AdSense, Facebook, and the Jira dashboard. It makes me want to click away.
It is notable that GitHub and BitBucket load more or less ready to go, without excessive server calls during page load. In my philosophy, if you are already doing a round trip to the server, assemble everything the page needs and send that as one unit. Do not send an empty shell that triggers a series of additional round trips, and hope your users will “sit tight”, which they won’t.
A core value of any product should be to keep users engaged, interested, and coming back to the site time and time again. A customer’s first experience with an application has to be super fast, and the product should continue to respond adequately as they delve deeper.
When it comes to user events, like a button click, one round trip is totally fine – provided a spinner appears and there is some semblance of progress. However, if the model layer inside the UI is just as fine grained as the back end data model, and the RESTful layer mirrors the data model (which is sadly the default of most REST frameworks), the UI layer ends up having to make several calls back to back to get the page into the correct state.
B) Excessive calls introduce brittleness:
Sometimes, due to the very nature of TCP/IP, packets get lost, and asynchronous calls either won’t make it to the server, or the response won’t make it back. This kind of thing almost never happens on localhost (where 99.9% of development happens), but it does happen all the time in the real world. Think about the last time you clicked a link and it didn’t work, but clicking it again did – it does happen!
A RESTful layer should be hardened so that it cannot put the data on the backend into a corrupted or illogical state. However, if an asynchronous call fails, the UI could get into an odd state as well. A lot of exception handling and timeout code needs to be there, ready to compensate. Your application and business case might not tolerate a spinner running continuously. Even google docs just ‘temporarily lost connection to the google server’ as I was writing this, and it interrupted my train of thought. Thankfully this is just a blog post, but if I was writing something serious like a drug prescription, or a complex legal note, the situation would be different.
C) Excessive calls are just poor design:
The data model and the business logic are different layers. Unfortunately the default for many REST API frameworks is to mirror the data model one to one. Doing that is amateur and completely silly. Any non-trivial application relates many different entities at once to provide value.
Think of your REST API like a service layer not like a data layer. Design the REST API to model your business services, not your actual data model.