Modifying your urls on the fly using the request method with sync in backbone.js

by Cedric Dugas on November 14, 2011

Backbone provides one default url for all your types of request with your models. But what if you want to be able to change your url model that is synching with your api depending of the type of request? Well that’s what we are here to do.

Backbone Sync

Sync is a nice utility used by backbone when you request your server to sync your model. Each time your request a change, backbone call sync, for you it is basically an empty shell for doing operations before the request is launched.

What we will do here is create 3 urls depending if we edit, create, or delete a model. To that end we will add a new function that with handle 3 new urls in your model definition:

methodUrl:  function(method){
	if(method == "delete"){
    		return "http://www.api.com/mymodel/" + this.attributes.id+"/delete";
    	}else if(method == "update"){
                return "http://www.api.com/mymodel/" + this.attributes.id+"/update";
        }else if(method == "create"){
                return "http://www.api.com/mymodel/create";
        } 
    	return false;
}

That’s nice, but from where these methods come? Well they come from backbone, backbone tells you what type of action is happening in sync, so to that end we will have to modify sync:

sync = function(method, model, options) {
    if (model.methodUrl && model.methodUrl(method.toLowerCase())) {
      	options = options || {};
      	options.url = model.methodUrl(method.toLowerCase());
    }
   Backbone.sync(method, model, options);
}

Sync is really nice, it provides you a lot of information, here we check if our methodUrl function returns an url and override our current one, and if it does not? Well it just lets the default url alone and continues normally.

Using sync globally

You could define your sync method on each model separately but that would be a pain, instead a nice idea is to apply it to every model modifying the backbone model prototype:

    Backbone.Model.prototype.sync = function(method, model, options) {
    	if (model.methodUrl && model.methodUrl(method.toLowerCase())) {
      		options = options || {};
      		options.url = model.methodUrl(method.toLowerCase());
    	}
   		Backbone.sync(method, model, options);
  	}

And there you go!