Most of you might have heard of these greatest and latest Javascript frameworks such as Backbone.JS, Angular.Js, Ember.Js, and many others. Their goal is to help you build Rich Interactive Applications, and each of them has a different way of doing things. However, they all have one thing in common. They can only run inside a web browser.
What's so bad about running inside a web browser?
1. Search engines cannot crawl your app. Therefore you can forget about SEO.
2. Latency issue. It will take a couple of seconds for the browser to download the Javascript framework, and your application code. Then call some REST api to fetch the data before it can render something to the screen. During this time, your user will be either be staring at a blank screen or a loading screen.
Well, you can get around these two issues by having your backend code render the landing page with all the HTML code ready to go, as well as bootstrapping your javascript application.
Consider a simple Todo list app, that lets you list all your todos, enter a new todo, view details of a todo.
Since this is a Javascript application, it can do all of that from the browser and call the appropriate REST api to query or persist the todos. It can also use HTML5 pushState to update the browser's URL based on what your user is doing. Which will allow the user to get back to the exact page that she was on if she were to reload the browser or copy and paste that URL to share with her friends.
In order to support pushState, your backend server needs to know how to render these three URLs as well.
/todos - list all the todos
/todos/new - render the new form to enter a todo.
/todos/123 - show details of a todo.
As you see, the javascript code already knows how to render these three URLs in the browser. Now you have to repeat the same work on the server side. More work and more bugs for you to deal with, along with trying to keep these pages consistent between the two rendering engines over time.
Most of us, when asked what is a client, we will point to the browser because that is what we have been dealing with for the last 15+ years. But this is now. Can we redefine what a client mean? Can it be the browser combined with Node.js?
Extend the client definition to include Node.js. Apply the same set of rules that we have applied to the browser. Such as, no access to the file system, no access to the database. Sandbox it. Querying and modifying data must be done via some REST api. The javascript application that we wrote should be able to run in both the browser and Node.js. It should not discriminate between the two run times. Let's start calling the browser and Node.js our new client, and let they work together to take care of the presentation layer as a single unit. Never again do we have to worry about code duplication!
Mean while, our backend server only need to handle REST requests. It should not worry about the presentation layer anymore. We can still implement it using Ruby/Rails, Python/Django, or whatever our favorite language/framework is.
Also, we can allow other clients such as iOS, or Android apps reusing the same backend code too! One server, multiple clients!
Wouldn't it be great to have a javascript framework that can render any landing page. Then package itself up and ship itself to the browser. So any subsequence rendering will be done from the browser.
Anyway, there are two open sourced projects that try to tackle these two problems.
The first one is called DerbyJS. However, it's trying to do too much. It baked in real time communication(websocket), and integrated the database layer(MongoDB). Forcing you to use NodeJS as your backend. (I'm a strong believer of keeping the client code and the server code separated!)
The second one is called Yahoo Mojito. It takes a lighter approach. There is no database integration. It encourages you to use web services to exchange data. Check out its value proposition video. http://www. youtube.com/watch?v= TtfjgBD3AIc
To sum up, the Ultimate Javascript Application Framework needs to address SEO, and latency issues. It can do only do so by transparently running the same code in Node.JS and in the browser.