Prepare an absolute URL in Backbone.sync for an API on another server

The My Backbone application interacts with an API that exists on another server. Backbone.sync will generate relative URLs by default. The easiest way to add an absolute server path would be something like this:

 MyApp.BASE_URL = "https://api.someOtherSite.com" class MyApp.Model extends Backbone.Model urlRoot: "#{MyApp.BASE_URL}/my_app_url" 

However, I would prefer not to do this because it is NOT 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 a problem for other parts of the code, as the options object is passed around. * (explanation for interested below)

Is there a recommended clean and harsh way to add a server path to the beginning of all URLs created with Backbone.sync ?


* If the synchronized model is an instance of Backbone.Collection , this options object will be passed to the collection model constructor. A URL is one of the few properties that will be directly bound to the model if it is passed as part of the options object. This breaks sync into any models created in the collection, because now they have a set of URLs attached to them instead of the url method, which generates the corresponding URL using urlRoot or the url collection.

+4
source share
3 answers

I think the best option is to create a basic model from which your other models will expand:

 MyApp.Model = Backbone.Model.extend({ urlRoot: function(){ return 'https://api.someOtherSite.com/' + this.get('urlFragment') } }); 

And then your models will be defined like this

 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" 

You now have your URLs specified in a dry way!

+4
source

You must use prototypes for a universal property in all collections or models, etc.

 Backbone.Collection.prototype.absURL = 'http://example.com'; var MyCollection = Backbone.Collection.extend({ model : myModel, url: function() { return this.absURL + '/api/stuff'; } }); 
+1
source

Know that this is old, but I ran into a problem when creating a client for the api that I am developing. My solution, being dry and very simple, happens in jQuery not Backbone. This suggests that jQuery is a Backbone digression, so I consider it a reasonable approach to a typical case.

 $.ajaxPrefilter(function prependUrlPrefilter(opts) { opts.url = 'http://127.0.0.1:3000' + opts.url; }); 

One of these methods is that it globally mutates the URL of any xhr calls passing through jQuery. If you are calling web services on multiple domains or you have plugins that make and use the same jQuery, you need to add a condition here.

You will also want to separate the host part of the domain from the configuration.

More can be found on ajaxPrefilters here .

+1
source

Source: https://habr.com/ru/post/1480809/


All Articles