Hacker News new | past | comments | ask | show | jobs | submit login
Rendr - Use Backbone on both the server and client (github.com/airbnb)
141 points by jlogsdon on April 2, 2013 | hide | past | favorite | 33 comments



My brother released a very similar project about 8 months ago.[1] He never did properly announce or document it so it's no surprise that nobody else is using it.

Of course, it's not like rendr has any real documentation, either.

However it has been working very well for us, so it is validation of the rendr approach.

A quick glance at their documentation indicates a very similar design, comparing the two projects should be instructive.

1: https://github.com/wvl/highbrow


I looked a little bit more at the rendr source, and one thing that immediately jumps out at me is the code BaseView#getTemplateData[1] which very tightly couples the model & views together. You should totally steal highbrow's ViewModel code, which is very sweet. (But you might want to come up with a better name). Rather than passing @model.toJSON() as template data, highbrow creates a ViewModel from the model or collection or out of thin air, and passes that in as template data.

Here's a typical ViewModel definition (in JS):

    foo.vm.Resource = highbrow.ViewModel.extend({
      lastUpdated: function() {
        return moment(this.model.get('modifiedAt')).fromNow();
      }
    });
    foo.vm.Resource.attrs(['name', 'content']);
This shows the main two features of ViewModel's: a whitelist of attrs that the template can access directly, and a set of functions that would otherwise end up polluting your model with view side code.

This decoupling dramatically improves the structure of our applications, without introducing Rails style controllers which are also totally misnamed in my opinion. Rails controllers are essentially two things: routers and MV-shims. Splitting the two makes for much improved program structure.

1: https://github.com/airbnb/rendr/blob/master/shared/base/view...

2: https://github.com/wvl/highbrow/blob/master/src/view-model.c...


Cool, I like that ViewModel pattern. You could certainly use that with Rendr.


I think this design goal:

    * Minimize if (server) {...} else {…}
was unfortunate. A grep of the highbrow source code indicates about 10 instances of that pattern, so I don't think there's a need for a separate base/server/client directory structure like rendr has, I think that creates artificial distinctions. It may be because I'm used to reading the highbrow source (because that's the only documentation :), but I find those if/else blocks to be very illuminating.


This is really nice, thanks for sharing. When this thread hit the front page last night I was very surprised that no one had done this before with Backbone--as it turns out, a few people have!



More background and discussion about Rendr and how it fits into the stack of the nodejs app AirBnB built: http://nerds.airbnb.com/weve-launched-our-first-nodejs-app-t...


I have gone through the blog post and bit of code but I am a bit stomped. Can anyone tell what is the flow here?

If I go directly to /search/q=hello, the request will go to server, it will render the HTML on server and send it to client. What happens next? Do they send all the Javascript + client-side templates alongside as well so that further requests are catered on client?

Think I should fiddle around with the sample app.


Do they send all the Javascript + client-side templates alongside as well so that further requests are catered on client?

Yes.


We used a similar approach with Bones (https://github.com/developmentseed/bones) for a while and ended up dropping it for a more decoupled architecture (API on side and static client on the other).

I remember chatting with Spike about this at a Backbone.js meetup at Airbnb's office last year, I think they were aware of the limitations similar frameworks were running into.

I'd be interested in seeing how this play outside of Airbnb's use case, but from experience I think sharing backbone.js on both client and server, while neat, end up being pretty constraining.


This looks fantastic. Anyone know how well something like this deprecates? My dream is to have a mobile site that is all Backbone-y on iPhone/Android but falls back to server-based rendering when loaded through a Blackberry or similar.


The goal is to render everything server-side; you'll need to handle POSTs and whatnots separately (since rendr is effectively middleware, so you can do what you like and redirect back to a GET route to display data.) In theory, it deprecates perfectly.


We @sc5io decided to release our own research regarding this very same issue.

I love the Rendr approach, yet we feel that our backbone-serverside framework provides an even more flexible way to tackle the same issue.

Read more at SC5 blog (http://blog.sc5.fi/2013/04/serving-backbone-for-robots-legac...) or at the Mozilla Hacks article: https://hacks.mozilla.org/2013/04/serving-backbone-for-robot...


I'm using http://phantomjs.org/ to render my EmberJS app's pages and serve those to crawlers. I hope to write a blog post about it soon. It has the benefit of working with any software stack, not just Node.js.

Rendr looks like a much more robust solution, however. I'll have to see if I can incorporate some of it's techniques, specifically serving HTML on page load.


Cool I'd be interested in reading about that.


This is pretty cool. I've been playing around with a variety of JS frameworks recently and code sharing is probably my 2nd favorite thing about meteor. Anybody know if these guys are hiring? My school's big interview day is on Thursday and airbnb's front-end stack looks appealing.


We are absolutely hiring! airbnb.com/jobs


I remember reading their blog post about their "Holy Grail" framework, but I couldn't really understand what made it so cool. Can someone explain to a noob like me why someone would consider Rendr the Holy Grail of frameworks?


MVC is being used for web development. The M part, model, handles the rules for inputs. This would trigger validation errors. In a typical stack, we code the server-side model in, say, Ruby on Rails, and duplicate the same model in client-side model in JavaScript so it can detect things like minimum password lengths without sending data back to the server. The holy grail is to have both server-side and client-side in JavaScript and also sharing the models as well, with that we reduce amount of things we have to code.


This approach doesn't help. With highbrow and presumably rendr, you still have 'client side' & 'server side' components to your project. The 'server side' is typically just a JSON REST API. In our case, it uses mongoose to talk to mongodb. The 'client side' talks to the API and renders HTML; on first load it actually runs on the server. The client side uses Backbone.js models.

So you still need both backbone & mongoose/whatever validations if you want them both on the client & server side. In practice, the system is fast enough that server side validations may be sufficient.


IIRC, it bridges single page web apps and standard websites. I.e. on the initial request, the page is rendered server-side, similarly as it would say with Rails and will work even if the client has JS disabled. If the client has JS enabled, it will work as a SPA.


More important than the JS-disabled case is the speed of the first page.

Given my experience with the very similar highbrow, I expect that rendr can return a fully functional page in 10-20 ms. In a typical client-side JS framework, the first page takes 300-3000 ms to render. Subsequent pages are lightning quick, but in many cases it's the first page that's the important one.


These types of frameworks also offer better SEO, because despite popular claims about Google crawlers rendering Javascript, "single page apps/blogs/whatever" get a lot less Google-juice than sites rendered on the server.


Wow, their samples sure look like Batman.js. Also, I'm a fan of them for going with CoffeeScript, they have taste.

But seriously, looks very much like Shopify's batman.js http://batmanjs.org


They're both written in coffeescript, and they're both written about the same time so have very similar influences.

I think most of the similarities you see stem from those two points.

But there are some massive differences:

- batman.js is Rails-style MVC, rendr is based on Backbone so you must supply your own controllers. A good argument can be made that Rails is not truely MVC, but it at least attempts to do so. rendr is MV.

- RENDR runs and renders on the server. batman.js relies on a Rails or REST app on the server.

- rendr is based on Backbone.js and Express, batman.js isn't


I wasn't pointing out on those portions, I was merely just reflecting over the API design :) keywords and etc


This is really fantastic - thanks to Spike and the rest of the Airbnb guys for releasing it to the world.

My interpretation of the key benefits: large speed increases for users, and vastly improved SEO.


I've been waiting for YUI team to fit the YUI App Framework(the equivalent of BackBone) into Mojito. But seems like you've beaten them to it. :)

Great job!


The Holy Grail!


I don't like the idea of rendering client code in the server.


Don't think of it as client or server code. Think of it as presentation code. And it happens to run on both the server and browser.

Though, don't write your business code in javascript. Hell to maintain.


If you can do it without code duplication, why not just consider it a kind of caching? That's how it seems to be used here: as an optimization.

If your definition of the JSON to HTML transformation is declarative, it makes sense to allow the server to do it for the data that's available to it.

The web has a semi-long history of "dumb clients," and that means the server has to be able to do the rendering. There are some pretty good reasons for this, and projects like Rendr try to make it as easy as possible. Seems good to me!


> Library, not a framework

> Talk to RESTful API

> Simple Express middleware

Hard times for Meteor




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: