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
我喜欢示例,因此下面是一个HTTP请求,用于获取此页面的HTML:
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
是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
上一个例子和这个例子有三个不同之处.
- method现在是
POST
.
- path现在是
/login
.
- 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.
回到主干
因此,希望您现在对HTTP的工作原理有了更多的了解.但是这和脊椎有什么关系呢?让我们来看看吧!
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'
});
创建(发布)
由于我们使用的是RESTful API,这就是能够创建、读取、更新和删除所有图书信息所需的全部信息!让我们从写一本新书开始.以下代码应足够:
var brandNewBook = new BookModel({ title: '1984', author: 'George Orwel' });
brandNewBook.save();
主干网意识到您正在try 阅读一本新书,并从提供的信息中了解到您需要提出以下请求:
POST /books HTTP/1.1
Host: example.com
{"title":"1984","author":"George Orwel"}
读取(获取)
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
巴姆.就这么简单.但是假设我们只需要一本书的信息.我们就说42号书吧.比方说我们跑了new BookModel({ id: 42 }).fetch()
分.主干看到你在试着写一本single的书:
GET /books/42 HTTP/1.1
Host: example.com
更新(PUT)
该死,我才意识到我把奥威尔先生的名字拼错了.很容易修复!
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)
最后,你意识到政府正在跟踪你的一举一动,你需要掩盖你读过1984年的事实.可能已经太晚了,但try 从来都没有坏处.所以你跑brandNewBook.destroy()
,主干变得有知觉,意识到你的危险deletes通过以下请求阅读这本书:
DELETE /books/84 HTTP/1.1
Host: example.com
然后它就不见了.
其他有用的花絮
虽然我们已经讨论了很多关于我们发送到服务器的内容,但是我们可能也应该看看我们得到了什么.让我们回到我们的藏书上go 吧.如果你还记得的话,我们提出了GET
到/books
的要求.理论上,我们应该拿回这样的东西:
[
{"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知道每个API都有一点不同,这是可以接受的.你要做的就是让它知道idAttribute
,就像这样:
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...
这样做的缺点是,在某些情况下,您必须记住使用bookId
.例如,以前我们使用new BookModel({ id: 42 }).fetch()
来加载关于一本书的数据,现在我们必须使用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.