Last Updated: March 07, 2016
·
11.79K
· smallhadroncollider

Using custom headers with Backbone.sync

Using a similar technique to that discussed in Add a root URL to all Backbone API request it is very easy to add a custom header to Backbone.sync requests without having to repeat it in every fetch/save.

For example, the API of a project I was working on recently needed an Authorization header, containing the OAuth access token, sent with every sync request. It would have been reasonably trivial to rewrite a Backbone.sync replacement that handled this, but why write extra code when Backbone.sync works so well?

/*
 * Using AMD/RequireJS
 *
 * The `auth` module handles OAuth and stores the
 * access token that needs to be sent in a header
 */
define(['api/auth'], function (auth) {
    'use strict';

    /*
     * Store a version of Backbone.sync to call from the
     * modified version we create
     */
    var backboneSync = Backbone.sync;

    Backbone.sync = function (method, model, options) {
        /*
         * The jQuery `ajax` method includes a 'headers' option
         * which lets you set any headers you like
         */
        options.headers = {
            /* 
             * Set the 'Authorization' header and get the access
             * token from the `auth` module
             */
            'Authorization': 'Bearer ' + auth.getAccessToken()
        };

        /*
         * Call the stored original Backbone.sync method with
         * extra headers argument added
         */
        backboneSync(method, model, options);
    };
});

7 Responses
Add your response

Thanks. This is great. Quick question: How does the collection fetch / save know to use this overloaded function rather than the original?

(And do you have the auth.js? Ta).

Thanks.

over 1 year ago ·

The example above is assuming that you're using the non-AMD version of Backbone, so Backbone.sync is in the global scope. When you assign the new function to Backbone.sync it will therefore over-write the original - just like reassigning any variable.

If you were using the AMD version of Backbone it would be a little trickier. You'd need to setup a file where you import in the AMD Backbone object, then override the Backbone.sync method, and then return the new version. From then on you'd use that newly created file as your Backbone definition (so you'd only require the original Backbone file once at the top of that file).

over 1 year ago ·

The auth.js module is just a short file that I wrote - it's quite specific to the project.

over 1 year ago ·

Thanks for the reply. Really appreciate it.

I am using Require with Backbone, so am a little unsure of where the new sync code should sit to overload the original. (Certainly where I've put it, it doesn't seem to work! ;) )

Cheers,
Ben

over 1 year ago ·

So you'd need to setup an empty file in your project called backbone.js and then put the Backbone.sync code in it. The only difference is that at the top you'd need to require the original Backbone file (e.g. ../vendor/backbone/backbone.min.js) with a Backbone argument name. Then put return Backbone; at the end. Anywhere else in your project where you need Backbone require your new backbone.js file (or, even better, set that up to be backbone in your RequireJS config).

over 1 year ago ·

Aha. Yes. Now you've put it like that, it's obvious - overide the whole file.
Thanks again for the help.

over 1 year ago ·

nice one, not exactly what I was looking for but pretty damn close and its nice to know that backbones pretty flexible when it comes to this sort of thing.

over 1 year ago ·