My Backbone app communicates with an API that exists on another server. Backbone.sync
will generate relative URLs by default. The simplest way to prepend the absolute server path would be something like the following:
MyApp.BASE_URL = "https://api.someOtherSite.com"
class MyApp.Model extends Backbone.Model
urlRoot: "#{MyApp.BASE_URL}/my_app_url"
However, I'd rather not do this as it isn't DRY. I thought I could try something like the following by overriding Backbone.sync
:
do (Backbone) ->
BASE_URL = 'https://api.someOtherSite.com'
baseSync = Backbone.sync
Backbone.sync = (method, model, options) ->
url = _.result(model, 'url')
options.url = "#{BASE_URL}/#{url}" if url && !options.url
baseSync method, model, options
However, this is problematic for other parts of the code as the options
object gets passed around all over the place. *(explanation for the interested at the bottom)
Is there a recommended clean and DRY way to prepend a server path to the front of all URLs generated by Backbone.sync
?
*If the model
being synced is an instance of Backbone.Collection
this options
object will get passed to the collection's model constructor. URL is one of the few properties that will get directly attached to a model if it is passed in as a part of the options
object. This breaks sync
for any models that are created in a collection as they now have a set URL attached to them instead of a url
method that generates an appropriate url by using urlRoot
or the collection's url
.
I think the best option is to create a base model that your other models will extend from:
MyApp.Model = Backbone.Model.extend({
urlRoot: function(){
return 'https://api.someOtherSite.com/' + this.get('urlFragment')
}
});
And then have your models be defined like so
MyApp.MyModel = MyApp.Model.extend({
urlFragment: "my_model_url"
})
So, in CoffeeScript:
class MyApp.Model extends Backbone.Model
urlRoot: ->
'https://api.someOtherSite.com/' + @get('urlFragment')
And
class MyApp.MyModel extends MyApp.Model
urlFragment: "my_model_url"
Now you've got your urls specified in a DRY fashion!