5 ms·
> Support for HTTP PATCH requests, sending only the changed state of your model to the server, instead of the full representation. This feels a little off to m
by MatthewPhillips 14y ago
> Support for HTTP PATCH requests, sending only the changed state of your model to the server, instead of the full representation.
This feels a little off to me. The nice thing about Backbone vs. other frameworks is that it's not overly opinionated, you can structure your backend any way you want, so I'm not sure why Backbone has an opinion of what http methods save() uses. PUT as a default makes sense but it should be able to support POST, PATCH, GET, CHANGETHETHING or anything else, as browsers now support arbitrary method strings in XHR. Perhaps an override some where?
- peregrine 14y agohttp://tools.ietf.org/html/rfc5789 http://tools.ietf.org/html/rfc5789 HTTP PUT is for in place entire entity updates. HTTP PATCH is for partial updates. This isn't some opinion these guys came up with. It's HTTP standards. Also if you don't like what save does. Write your own Backbone.sync and be done with it. Still super flexible.
- MatthewPhillips 14y agoFair enough, I agree with the spec here, but we know that in the wild many companies don't conform to HTTP.
- jmorton 14y agoFor what it's worth... "PATCH is going to be the primary method for updates in Rails 4.0." http://weblog.rubyonrails.org/2012/2/25/edge-rails-patch-is-the-new-primary-http-method-for-updates/ http://weblog.rubyonrails.org/2012/2/25/edge-rails-patch-is-... That's not intended to be a counterpoint. In the wild, many companies don't use Rails. :)
- k3n 14y agoIt doesn't matter what Rails decides to do if your HTTP server doesn't support it. With that said, it looks like many do already support it (from the same article you linked): Apache, nginx, Phusion Passenger, Unicorn, Thin, and WEBrick.
- steveklabnik 14y agoAlso, Rails supports an override as well, so you can send it as a POST but specify a different verb in a header, and it will treat it as a native request with the correct verb.
- vidarh 14y agoBackbone already supports overriding this in several ways: 1. You can pass any arguments to the ajax call in the options hash passed to the various calls: Foo = Backbone.Model.extend({url: "/bar" }) f = new Foo f.fetch({type: "BLAH"}) leads to a "BLAH /bar" request instead of a GET. 2. You can override Backbone.sync to do an application-wide override. The basic implementation is fairly simple as a starting point and/or you can just wrap it. 3. You can override the sync methods of Backbone.Model or Backbone.Collection. By default these just proxy to Backbone.sync 4. You can extend either of them and derive your own models and collections from your extended version. 5. You can replace .sync for any _specific_ model or collection object if you have specific sync needs for specific subsets of your application. Given this, I really don't think cluttering the default code with more options is worthwhile - any other variations would be better provided for by providing an alternate implementation which can optionally proxy to the default/original for cases that doesn't need special handling. This is part of what I like about Backbone - it is small and focused and sufficiently decoupled that replacing parts of the guts of it is simple to do.
- jashkenas 14y ago> PUT as a default makes sense but it should be able to support > POST, PATCH, GET, CHANGETHETHING or anything else, as browsers > now support arbitrary method strings in XHR. ... it does (as mentioned by vidarh). The full suite of jQuery options are passed through transparently. What this particular feature means is that: model.save() // PUT all of the models current attributes to model.url model.save(attrs, {patch: true}) // PATCH just the `attrs` to model.url
- philfreo 14y ago// Override Backbone.sync to use the PUT HTTP method for PATCH requests // when doing Model#save({...}, { patch: true }); var originalSync = Backbone.sync; Backbone.sync = function(method, model, options) { if (method === 'patch') options.type = 'PUT'; return originalSync(method, model, options); };