title: Architecture for large scale backbone applications
author: Jean Carlos Meninno & Jorge Dias
description: Managing complexity with backbone applications
date: 2013-10-11
!SLIDE
!SLIDE
- Twitter: dias_jorge
- Github: @diasjorge
- Blog: mrdias.com
!SLIDE
- Twitter: @eth0lo
- Github: @eth0lo
- Blog: meninno.com
Not really
!SLIDE
- Incompatible versions
- Global space pollution
- Javascript events in the html
!SLIDE
- Browser inconsistencies abstracted
- Lots of plugins but often incompatible
- Ad-hoc AJAX handling
- Lack of client side templating
!SLIDE
- Modular structure
- Communication through events
- Consistent interface to backend
!SLIDE
!SLIDE
!SLIDE
- Restful interface
- Data and presentation are separated
- Lifecycle events
!SLIDE
- Easy handling of dom events
- React to model/collection events
!SLIDE
- Routes handling
- Back button keeps working
- Push state (where available)
- No full page reloads
!SLIDE
- Not opinionated
- underscore integration
- jQuery integration
- Fits into existent projects
- Small footprint
!SLIDE
!SLIDE
!SLIDE
- Events
- Views
!SLIDE
- Setup your own conventions
- No clear way to structure your app
- Lacks specialized views
- Make your own framework on top
!SLIDE
- No controllers
- Mixed concerns between views and models
- Huge routers
Rewrite the whole frontend in 4 months.
Previous version was 1.5 years in development.
!SLIDE
- Don’t screw up by learning another framework
- Lots of time pressure
- 80% of team was backend
!SLIDE
- Marionette
- Chaplin
- Thorax
!SLIDE
!SLIDE
!SLIDE
!SLIDE
!SLIDE
!SLIDE
- Layouts
- Region Manager
- Collection/Composite View
- ItemView
!SLIDE
Good bye zombies
!SLIDE
- Application structuring
- Promotes modularity and encapsulation
!SLIDE
- General purpose coordinators
!SLIDE
!SLIDE
App.commands.setHandler("log:request", function(request){
console.log(request);
});
// Somewhere else
App.execute("log:request", request);
!SLIDE
App.reqres.setHandler("foo", function(bar){
return bar + "-quux";
});
App.request("foo", "baz"); // => returns "baz-quux"
!SLIDE
vent.on("foo", function(){
console.log("foo event");
});
vent.trigger("foo"); // => "foo event" appears in console
!SLIDE
- Router composition
- Router as configuration
!SLIDE
someController = {
someMethod: function(){ /*...*/ }
};
Backbone.Marionette.AppRouter.extend({
controller: someController,
appRoutes: {
"foo": "someMethod"
}
});
!SLIDE
!SLIDE
!SLIDE
!SLIDE
- User clicks on facet
- View triggers event
- Controller responds updating the search
!SLIDE
- User clicks on Profile
- View triggers event
- Controller executes command to navigate
!SLIDE
- Profiles app handles the command
- It initializes controller
- Controller requests profile model and renders the views
!SLIDE
- Models and collections contained in one place
- Events all the way
- Everything is a promise
- Only place that instantiates models/collections
!SLIDE
// Inside entities/user
App.reqres.setHandler('user:current:entity', function () {
return currentUser;
});
// Inside users/show/show_controller
// ...
currentUser = App.request('user:current:entity');
!SLIDE
// Inside entities/search
App.reqres.setHandler('search:new:entity', function () {
return new Search();
})
// Inside search/new/new_controller
var newSearch = App.request('search:new:entity');
var view = new New.SearchFormView({model: newSearch});
this.layout.mainRegion.show(view)
!SLIDE
Patterns, patterns and more patterns
!SLIDE
- Dropdowns
- Forms
- Layouts
- Modals
- Tooltips
- etc
!SLIDE
- Apps
- Restful structure
- Lib
- Entities
- Templates
Cat picture for presentation completeness