Posted on by & filed under Content - Highlights and Reviews, Programming & Development.

A guest post by Tim Ruffles, a Ruby & JavaScript developer based in London who teaches and mentors developers, and works on SidekickJS, a code-quality tracker for teams. Previously he was a front-end tech-lead for Skimlinks and Picklive; he talks about Javascript at conferences and events and can be reached at @timruffles.

In a previous post titled Decoupling Backbone.js Applications with pub/sub we looked at how pub/sub makes it easier to change, test and reuse your Backbone.js code by reducing coupling. Follow along in this post for details on how to split your model from persistence in Backbone.js to bring the same advantages as splitting models from views.

Backbone.js is an MVC library, but since there’s no place in the acronym for persistence, it’s a common anti-pattern to see persistence and model being entirely confused.

Your Backbone model should be designed around your domain – these are the things your users care about and you could discuss with them. Whether modeling a user’s friends, their finances or freakish monsters in a game, it’s clear that none of these concepts have anything to do with HTTP, IndexedDB, localStorage, or any other persistence concern.

Backbone doesn’t help here. Model.parse and Model.url are both very tightly coupled to the concept of a request/response API.

You should prevent persistence confusing your model. What’s wrong below?

The answer is the snake case property. JavaScript is camelCase – seeing snake_case is normally a sure sign that your persistence layer is starting to dictate things. Keep it consistent – your model is the boss here! Names should be dictated by your domain, not your data-source. Snake vs camel case is a very visible indicator, but the real problem is coupling to your data-source. Don’t accept the names in your API if they don’t match your models. Sort them out before your model even knows about them!

Rules for Keeping Persistence in Check

These rules are not supposed to be cast iron. They’re just a set of baselines that are worth understanding. If you do the opposite it’s worth understanding why. Having your models deal with both persistence and your domain is asking for complex, bloated objects.

  1. When you notice repetition in your parse() methods, make a new custom Backbone.sync that cleans up your data-source.
  2. If your URLs are more than a line, or involve any complex logic, pull that process into a new Backbone.sync.
  3. Dictate naming from the model. Change any names in the API that conflict.
  4. Design from your client outwards, then find out how to use your API to persist it. If that means having completely different names and structures to the API, go for it!

It’s worth considering what happens if you break these rules and change your API. Where would the changes in your application be? What if you had two data-sources for your model? Moving everything around persistence into a Backbone.sync compatible method makes both of these cases simple, and slims down your models.

Let’s Look at an Example

As an example, let’s say we’re using a Rails API with responses in this format:

We have two things to do before this data is useful – snake_case, and removing the model name from the top level. We’ll need to fix the model name since fetch() expects to be able to set() the response directly, so it needs to be attributes at the top level.

We could write this in parse(), but we’d duplicate it in each model. It is far better to create a sync function that cleans this out before parse() even sees it.

So we’ll first create a function that wraps a current implementation of sync in some additional processing – you could do this multiple times if you liked:

Then we just need to write a function that cleans up a Rails response. Our final function, railsSyncForModelName, takes a model name and returns a sync replacement that does all of our clean-up work.

We only have to set the model’s sync, and it’ll work as expected, with all attributes present and in camelCase:

To see this example run, check out this JSBin.

It’s also good to parse dates (and certainly numbers, but hopefully your API responses are good enough to make that unnecessary) and custom data types into Models or values.

Keep Your Model Persistence Free

Splitting your model from persistence brings the same simplicity advantages as splitting models from views. Give it a try, I hope your Backbone code feels cleaner as a result!

Be sure to look at the Backbone.js resources that you can find in Safari Books Online.

Not a subscriber? Sign up for a free trial.

Safari Books Online has the content you need

Developing a Backbone.js Edge incorporates the best practices and the techniques from the combined authors’ experience of developing many Backbone.js applications. In this book you get a complete guide to Backbone.js and equip you to start using the library straight away. While writing this book the authors developed an example app, called Hubbub, to illustrate the various features of the library.
Developing Backbone.js Applications shows you how to get the job done with Backbone.js. You’ll learn how to create structured JavaScript applications, using Backbone’s own flavor of model-view-controller (MVC) architecture.
Backbone.js Cookbook contains a series of recipes that provide practical, step-by-step solutions to the problems that may occur during frontend application development using an MVC pattern. You will learn how to build Backbone.js applications using the power of popular Backbone extensions and integrating your app with different third party libraries.

About the author

timruffles Tim Ruffles is a Ruby & JavaScript developer based in London. He teaches and mentors developers, and works on SidekickJS, a code-quality tracker for teams. Previously he was a front-end tech-lead for Skimlinks and Picklive. He talks about Javascript at conferences and events and can be reached at @timruffles.

Tags: Backbone, Backbone.js, model view, MVC library, persistence,

Comments are closed.