javascript - Comprender las llamadas REST de Backbone.js
jquery ajax (2)
Intento entender el método de sincronización Backbone.js y estaba revisando la documentación en http://backbonejs.org/#Sync
Dice
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
Ahora que siempre he estado en desarrollo front-end y nuevo en Backbone, encuentro que lo anterior es difícil de entender ... Nunca he usado REST ni ningún otro protocolo del lado del servidor ...
¿Podrías explicar lo mismo en términos simples (como cómo se resuelven los mapas REST cuando utilizamos Backbone.sync)? Cualquier ejemplo muy simple sería muy útil ...
Asumiendo que entiendes las llamadas ajax (POST, GET, etc a ''/ collection'', etc.).
El backbone usa la sincronización para enrutar algunos modelos y métodos de colecciones a las llamadas REST.
model/collection.fetch() => GET
model.save() => POST (isNew())
model.save() => PUT (!isNew())
model.destroy() => DELETE
collection.create()
llama a model.save() (isNew()) => POST
Si pasa la url (/ colección) que desea utilizar a un modelo / colección, Backbone se encargará de las llamadas.
Si no te importa, voy a comenzar con aclarar algunas palabras. REST no es un protocolo en sí mismo, es simplemente una forma de utilizar el protocolo HTTP. El estilo REST es especialmente útil para las API, como espero que veas. Cuando una API se ajusta a ese estilo, se dice que es "RESTful". Si la API con la que está trabajando no es RESTful, tendrá que realizar muchos cambios en Backbone.sync para que funcione. ¡Así que con suerte lo es! :)
El protocolo HTTP
Me gustan los ejemplos, así que aquí hay una solicitud HTTP para obtener el HTML de esta página:
GET /questions/18504235/understand-backbone-js-rest-calls HTTP/1.1
Host: .com
[Opcional] Si alguna vez jugaste con la línea de comando o terminal, intenta ejecutar el comando telnet .com 80
y pegar en el cuadro anterior, y luego presionar Enter un par de veces. Voila! HTML en todo su esplendor
En este ejemplo...
-
GET
es el método . -
/questions/18504235/understand-backbone-js-rest-calls
es la ruta . -
HTTP/1.1
es el protocolo . -
Host: .com
es un ejemplo de un encabezado .
Su navegador hace aproximadamente lo mismo, solo con más encabezados, para obtener el HTML de esta página. Genial, ¿eh?
Como trabajas en el frente, probablemente hayas visto la etiqueta del formulario muchas veces. Aquí hay un ejemplo de uno:
<form action="/login" method="post">
<input type="text" name="username" />
<input type="password" name="password" />
<input type="submit" name="submit" value="Log In" />
</form>
Cuando envía este formulario junto con los datos apropiados, su navegador envía una solicitud que se ve así:
POST /login HTTP/1.1
Host: .com
username=testndtv&password=zachrabbitisawesome123&submit=Log%20In
Hay tres diferencias entre el ejemplo anterior y este.
- El método ahora es
POST
. - La ruta ahora es
/login
. - Hay una línea adicional, llamada cuerpo .
Si bien hay muchos otros métodos, los que se usan en las aplicaciones RESTful son POST
, GET
, PUT
y DELETE
. Esto le dice al servidor qué tipo de acción se supone que debe tomar con los datos, sin tener que tener diferentes rutas para todo.
Volver a Backbone
Así que espero que ahora entiendas un poco más sobre cómo funciona HTTP. ¿Pero cómo se relaciona esto con Backbone? ¡Vamos a averiguar!
Aquí hay una pequeña porción de código que puede encontrar en una aplicación Backbone.
var BookModel = Backbone.Model.extend({
urlRoot: ''/books''
});
var BookCollection = Backbone.Collection.extend({
model: BookModel
, url: ''/books''
});
Crear (POST)
Ya que estamos usando una API RESTful, ¡esa es toda la información que Backbone necesita para poder crear, leer, actualizar y eliminar toda la información de nuestro libro! Comencemos haciendo un nuevo libro. El siguiente código debería ser suficiente:
var brandNewBook = new BookModel({ title: ''1984'', author: ''George Orwel'' });
brandNewBook.save();
Backbone se da cuenta de que está tratando de crear un nuevo libro, y sabe por la información que se le ha dado que realiza la siguiente solicitud:
POST /books HTTP/1.1
Host: example.com
{"title":"1984","author":"George Orwel"}
Leer (GET)
¿Ves que fácil fue eso? Pero queremos recuperar esa información en algún momento. Digamos que new BookCollection().fetch()
. Backbone entendería que estás tratando de leer una colección de libros, y haría la siguiente solicitud:
GET /books HTTP/1.1
Host: example.com
BAM. Así de fácil. Pero digamos que solo queríamos la información para un libro. Digamos el libro # 42. Supongamos que new BookModel({ id: 42 }).fetch()
. Backbone ve que estás tratando de leer un solo libro:
GET /books/42 HTTP/1.1
Host: example.com
Actualización (PUT)
Oh, maldición, me acabo de dar cuenta de que deletreé mal el nombre del señor Orwell. ¡Fácil de arreglar!
brandNewBook.set(''author'', ''George Orwell'');
brandNewBook.save();
Backbone es lo suficientemente inteligente como para saber que a pesar de ser llamado brandNewBook
, ya se ha guardado. Entonces actualiza el libro:
PUT /books/84 HTTP/1.1
Host: example.com
{"title":"1984","author":"George Orwell"}
Eliminar (ELIMINAR)
Finalmente, se da cuenta de que el gobierno está rastreando cada uno de sus movimientos, y necesita enterrar el hecho de que ha leído 1984. Es probable que sea demasiado tarde, pero nunca está de más intentarlo. Entonces ejecuta brandNewBook.destroy()
, y Backbone se vuelve sensible y se da cuenta de que su peligro elimina el libro con la siguiente solicitud:
DELETE /books/84 HTTP/1.1
Host: example.com
Y se ha ido.
Otros Tidbits útiles
Si bien hemos hablado mucho sobre lo que estamos enviando al servidor, probablemente deberíamos echar un vistazo a lo que estamos recibiendo. Volvamos a nuestra colección de libros. Si lo recuerdas, hicimos una solicitud GET
a /books
. En teoría, deberíamos obtener algo como esto:
[
{"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"}
]
Nada demasiado aterrador. Y aún mejor, Backbone sabe cómo manejar esto de la caja. Pero ¿y si lo cambiamos un poco? En lugar de que id
sea el campo de identificación, ¿fue 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"}
]
El backbone dice que cada API es un poco diferente, y está bien con eso. Todo lo que tienes que hacer es dejarle saber el idAttribute
, así:
var BookModel = Backbone.Model.extend({
urlRoot: ''/books''
, idAttribute: ''bookId''
});
Solo debe agregar esa información al modelo, ya que la colección verifica el modelo de todos modos. ¡Así que solo así, Backbone entiende tu API! Incluso si yo no ...
La desventaja de esto es que debe recordar usar bookId
en ciertos casos. Por ejemplo, cuando utilizamos previamente el new BookModel({ id: 42 }).fetch()
para cargar los datos sobre un solo libro, ahora tendríamos que usar el new BookModel({ bookId: 42 }).fetch()
.
Espero que hayas encontrado esta respuesta informativa, y no demasiado insoportablemente aburrida. Me doy cuenta de que, para muchos, el protocolo HTTP y la arquitectura RESTful no son los temas más estimulantes, así que traté de darle más sabor. Puede que me arrepienta cuando vuelva a leer todo esto en un momento posterior, pero son las 2 de la mañana aquí, así que voy a seguir adelante y enviar esto de todos modos.