6 ms·
Are you familiar with Model-View-Controller? In this case it would be moving some of the controller logic (the parts responsible for rendering views and dispat
by anextio 14y ago
Are you familiar with Model-View-Controller?
In this case it would be moving some of the controller logic (the parts responsible for rendering views and dispatching events from the UI) to the browser, and using an API to communicate with the model (and the rest of the controller).
So, if I'm going to display a page of 10 tweets, in the classic server side architecture, I load the tweets, render a view template based on a context containing those tweets, and then send the HTML to the browser.
In an API-based web application architecture like this, I _always_ send the same HTML, which is cached in memory and is almost a no-op to send to the browser, then the client side scripting looks at the URL of the page and makes a call to a JSON or XML API that will result in those 10 tweets. These tweets are then rendered on the client side by the browser.
This is beneficial in a few ways:
* You can re-use the exact same API and expose it to third parties, who can then write apps with all the functionality of your webapp, and you've one less thing to test.
* Rendering a template can be a (relatively) time-consuming operation that may require some I/O. On a single-threaded platform like Node.js, where you simply want to dispatch an event (request) as fast as possible and move on, rendering a template takes a lot of time.
* If the time is going to be spent rendering that template anyway, you may as well crowdsource it and let the browser handle it. The browser is probably only processing one page load at a time, whereas your servers could be processing thousands or millions.
The cons of using this system are related to the benefits:
* The API you use is likely to suffer from Abstraction Inversion[1], or if that's intentionally avoided, a Leaky Abstraction[2]. The reason for this is that there may be some pages to be rendered that require more complex, or less abstract, queries on the data. On the server you could easily issue a JOIN query, but it may not make sense to expose such a thing directly via a RESTful interface. Therefore your application may end up firing numerous API requests and joining the results manually in order to complete a request. If you DO expose this functionality, it will probably end up looking very out of place and very specific.
* The extra time spent by the browser may not be suitable in all cases. It poses a number of accessibility and performance problems on certain devices. I may not be able to use a certain website with a screen reader because of this, or I may not be able to view it on an ancient version of Opera running on a shitty old phone over 3G. Even on a modern smartphone, the time taken from seeing a Twitter page's header and background with the loading indicator to actually seing the content was a pain in the ass.
* Depending on your application and architecture, you may be able to deliver even better performance by caching rendered templates than by offloading it to the browser. For example, I believe Reddit pretty much prerenders and caches every single page on the site, which is why most stuff loads instantly, but at peak times it takes a while to load the message inbox, or the 80th page of posts. This might be made even worse by extra API calls and client side rendering.
[1] http://en.wikipedia.org/wiki/Abstraction_inversion http://en.wikipedia.org/wiki/Abstraction_inversion
[2] http://en.wikipedia.org/wiki/Leaky_abstraction http://en.wikipedia.org/wiki/Leaky_abstraction
- mark_story 14y agoThat was a really great explanation :D
- dansingerman 14y agoA lot of that could be described as "lessons I have learned on recent projects". I wish I had read (and grokked) this post 18 months ago.
- anextio 14y agoWell, there's no One True Way for Software Engineering, and certainly this service-based approach can and does work for many, many projects. Obviously it wasn't a complete disaster in Twitter's case. If I may, I'll employ another Anti-Pattern, Cargo Cult Programming[1]. This means that a team sees some method or 'One True Way' and starts implementing it without understanding why. It's almost guaranteed to go wrong, and it tends to apply a lot to things that are hip, like this architecture and things like NoSQL. [1] http://en.wikipedia.org/wiki/Cargo_cult_programming http://en.wikipedia.org/wiki/Cargo_cult_programming
- harichinnan 14y agoI wonder if this could be remedied by using a front end Web App Server consuming the JSON API. So you would have a JSON API server and a front end Web App say in Node using the API as a database. You would have the advantages of building a SOA architecture, letting the API server do the heavy lifting. And you could reuse a well tested API for Mobile Apps. I would think a Meteor.JS like front end would be an ideal solution for low traffic websites(Not twitter!)