Understand Backbone.js REST calls

59,993

Solution 1

If you don't mind, I'm going to start with clearing up some wording. REST is not a protocol in itself, it's simply a way of using the HTTP protocol. The REST style is especially useful for APIs, as I hope you'll see. When an API conforms to that style, it is said to be "RESTful". If the API you're working with isn't RESTful, you'll have to make a lot of changes to Backbone.sync in order to get it to work. So hopefully it is! :)

The HTTP Protocol

I like examples, so here is an HTTP request to get the HTML for this page:

GET /questions/18504235/understand-backbone-js-rest-calls HTTP/1.1
Host: stackoverflow.com

[Optional] If you have ever played with command line or terminal, try running the command telnet stackoverflow.com 80 and pasting in the above, followed by pressing enter a couple of times. Voila! HTML in all of it's glory.

In this example...

  • GET is the method.
  • /questions/18504235/understand-backbone-js-rest-calls is the path.
  • HTTP/1.1 is the protocol.
  • Host: stackoverflow.com is an example of a header.

Your browser does approximately the same, just with more headers, in order to get the HTML for this page. Cool, huh?

Since you work in front end, you've probably seen the form tag many times. Here's an example of one:

<form action="/login" method="post">
    <input type="text" name="username" />
    <input type="password" name="password" />
    <input type="submit" name="submit" value="Log In" />
</form>

When you submit this form along with appropriate data, your browser sends a request that looks something like this:

POST /login HTTP/1.1
Host: stackoverflow.com

username=testndtv&password=zachrabbitisawesome123&submit=Log%20In

There are three differences between the previous example and this one.

  1. The method is now POST.
  2. The path is now /login.
  3. There is an extra line, called the body.

While there are a bunch of other methods, the ones used in RESTful applications are POST, GET, PUT, and DELETE. This tells the server what type of action it's supposed to take with the data, without having to have different paths for everything.

Back to Backbone

So hopefully now you understand a bit more about how HTTP works. But how does this relate to Backbone? Let's find out!

Here's a small chunk of code you might find in a Backbone application.

var BookModel = Backbone.Model.extend({
    urlRoot: '/books'
});
var BookCollection = Backbone.Collection.extend({
    model: BookModel
    , url: '/books'
});

Create (POST)

Since we're using a RESTful API, that's all the information Backbone needs to be able to create, read, update, and delete all of our book information! Let's start by making a new book. The following code should suffice:

var brandNewBook = new BookModel({ title: '1984', author: 'George Orwel' });
brandNewBook.save();

Backbone realizes you're trying to create a new book, and knows from the information it's been given to make the following request:

POST /books HTTP/1.1
Host: example.com

{"title":"1984","author":"George Orwel"}

Read (GET)

See how easy that was? But we want to get that information back at some point. Let's say we ran new BookCollection().fetch(). Backbone would understand that you're trying to read a collection of books, and it would make the following request:

GET /books HTTP/1.1
Host: example.com

BAM. That easy. But say we only wanted the information for one book. Let's say book #42. Say we ran new BookModel({ id: 42 }).fetch(). Backbone sees you're trying to read a single book:

GET /books/42 HTTP/1.1
Host: example.com

Update (PUT)

Oh darn, I just realized I spelled Mr. Orwell's name wrong. Easy to fix!

brandNewBook.set('author', 'George Orwell');
brandNewBook.save();

Backbone is smart enough to know that despite being called brandNewBook, it's already been saved. So it updates the book:

PUT /books/84 HTTP/1.1
Host: example.com

{"title":"1984","author":"George Orwell"}

Delete (DELETE)

Finally, you realize that the government is tracking your every move, and you need to bury the fact that you have read 1984. It's probably too late, but it never hurts to try. So you run brandNewBook.destroy(), and Backbone becomes sentient and realizes your danger deletes the book with the following request:

DELETE /books/84 HTTP/1.1
Host: example.com

And it's gone.

Other Useful Tidbits

While we've talked a lot about what we're sending TO the server, we should probably also take a look at what we're getting back. Let's return to our collection of books. If you remember, we made a GET request to /books. In theory, we should get back something like this:

[
    {"id":42,"author":"Douglas Adams","title":"The Hitchhiker's Guide to the Galaxy"}
    , {"id":3,"author":"J. R. R. Tolkien","title":"The Lord of the Rings: The Fellowship of the Ring"}
]

Nothing too scary. And even better, Backbone knows how to handle this out of the box. But what if we changed it a bit? Instead of id being the identifying field, it was bookId?

[
    {"bookId":42,"author":"Douglas Adams","title":"The Hitchhiker's Guide to the Galaxy"}
    , {"bookId":3,"author":"J. R. R. Tolkien","title":"The Lord of the Rings: The Fellowship of the Ring"}
]

Backbone gets that every API is a bit different, and it's okay with that. All you have to do is let it know the idAttribute, like so:

var BookModel = Backbone.Model.extend({
    urlRoot: '/books'
    , idAttribute: 'bookId'
});

You only have to add that information to the model, since the collection checks the model anyway. So just like that, Backbone understands your API! Even if I don't...

The downside of this is that you have to remember to use bookId in certain cases. For example, where we previously used new BookModel({ id: 42 }).fetch() to load the data about a single book, we would now have to use new BookModel({ bookId: 42 }).fetch().


Hopefully you've found this response informative, and not too unbearably dull. I realize that for many, HTTP protocol and RESTful architecture aren't the most exhilarating subjects, so I tried to spice it up a bit. I may regret that when I read all of this back at a later point, but it's 2AM here, so I'm gonna go ahead and submit this anyway.

Solution 2

Assuming you understand ajax calls (POST, GET, etc to '/collection', etc).

Backbone uses sync to route some Models and Collections methods to REST calls.

model/collection.fetch() => GET
model.save() => POST (isNew())
model.save() => PUT (!isNew())
model.destroy() => DELETE

collection.create() calls model.save() (isNew()) => POST

If you pass the url (/collection) you want to use to a model/collection, Backbone will take care of the calls.

Share:
59,993

Related videos on Youtube

copenndthagen
Author by

copenndthagen

Buy some cool JavaScript related merchandise from; https://teespring.com/stores/technical-guru-2

Updated on July 05, 2022

Comments

  • copenndthagen
    copenndthagen almost 2 years

    I am trying to understand the Backbone.js sync method and was going through the documentation on http://backbonejs.org/#Sync

    It says

    The default sync handler maps CRUD to REST like so:
    
    create → POST   /collection
    read → GET   /collection[/id]
    update → PUT   /collection/id
    delete → DELETE   /collection/id
    

    Now since I have always been in front-end development and new to Backbone, I find the above hard to understand...I have never used REST or any other server-side protocols...

    Could you please explain the same in simple terms (like how the REST maps when we use Backbone.sync) Any very simple example would be highly useful...

    • evanmcdonnal
      evanmcdonnal over 8 years
      Backbone is such a horribly designed framework. Yes, lets create a proprietary term that has a 1-to-1 mapping to a meaningful HTTP verb. That will improve developer experience! Also, make the verbs use completely inflexible because clearly, every RESTful service ever made has used the best practices regarding HTTP verbs and object CRUD.
  • nikoshr
    nikoshr over 10 years
    Nice read. There's also a PATCH verb supported by Backbone backbonejs.org/#Model-save but that's probably not that useful in a REST overview
  • nikoshr
    nikoshr over 10 years
    And, by default, the POST/PUT methods send their payloads as JSON, not as form encoded parameters
  • ZachRabbit
    ZachRabbit over 10 years
    @SixteenStudio Glad I could help!
  • ZachRabbit
    ZachRabbit over 10 years
    @nikoshr I'd forgotten about that! I agree it might be a bit much for an overview, but thanks for bringing it up. And darn, I couldn't remember which it was, and I guess my gut was wrong. I'll change it over now.
  • copenndthagen
    copenndthagen over 10 years
    @Zach Rabbit : First of all, I must say that you very "CLEARLY" understood my question and specifically understood my background in front-end dev and hence started from a very RIGHT place...also your examples have been very perfect...U beat the Backbone documentation, which by the way I never understand....I just have 1 follow-up question as below....
  • copenndthagen
    copenndthagen over 10 years
    Basically the difference between using Create (POST) Vs Update (PUT)....Is that a fixed thing OR we can alter it based on our requirements....if you could just explain the above with id, idAttribute, etc that would be great....But once again, I must thank you for being absolutely perfect in understanding my question....
  • ZachRabbit
    ZachRabbit over 10 years
    @testndtv You are able to edit the Create/POST VS Update/PUT behavior. You would probably have to override the Backbone.sync behavior. But IMHO, it's best to keep it as Create/POST for new items, and Update/PUT for existing items. As for information on idAttribute, I've added a portion to my answer above. Hopefully that answers your questions. :)
  • copenndthagen
    copenndthagen over 10 years
    You are again Bang ON....I think you have now answered the question MUCH MORE than what was expected...So it is only fair that I accept it now...If I could, I would have given the answer a 1000 upvotes :) Thanks a lot...
  • Larry Gerndt
    Larry Gerndt over 10 years
    Thanks for sharing your knowledge in such a clear way. Couldn't help but read the whole thing.
  • Handsome Nerd
    Handsome Nerd over 10 years
    What about POST/PUT/DELETE server response?
  • SpringLearner
    SpringLearner about 10 years
    Good explanation,Nicely explained everything,+1
  • James Sefton
    James Sefton about 10 years
    What a fantastic answer!
  • goodpixels
    goodpixels about 9 years
    This is amazing. Much, much better than the official documentation!
  • Gilbert Nwaiwu
    Gilbert Nwaiwu over 7 years
    Super helpful mate
  • Jnewbie
    Jnewbie about 7 years
    and this post is still ... i would say usefull but its more than that.. in 2017