2009-05-24 12 views
21
new_story GET  /story/new(.:format) {:action=>"new", :controller=>"stories"} 
edit_story GET  /story/edit(.:format) {:action=>"edit", :controller=>"stories"} 
    story GET  /story(.:format)  {:action=>"show", :controller=>"stories"} 
      PUT  /story(.:format)  {:action=>"update", :controller=>"stories"} 
      DELETE /story(.:format)  {:action=>"destroy", :controller=>"stories"} 
      POST /story(.:format)  {:action=>"create", :controller=>"stories"} 

En el trabajo web que he hecho con otras tecnologías, solo he usado métodos GET y POST. Pero con las rutas RESTful en Rails, de forma predeterminada los métodos PUT y DELETE se utilizan para la actualización y destruyen las acciones. ¿Cuál es la ventaja o necesidad de usar PUT y DELETE? Supongo que estos métodos son solo otra forma de hacer POST, pero ¿por qué no seguir con POST?¿Por qué usar HTTP PUT y DELETE métodos en lugar de POST?

Respuesta

45

La ventaja es en su mayoría semántica, y también puede simplificar las URL en cierta medida. Los diferentes métodos HTTP se correlacionan con diferentes acciones:

POST => create a new object 
DELETE => delete an object 
PUT => modify an object 
GET => view an object 

Entonces, en teoría, puede utilizar la dirección URL misma, sino que interactúan con él utilizando diferentes métodos; el método utilizado para acceder al recurso define el tipo real de operación.

En la práctica, sin embargo, la mayoría de los navegadores solo son compatibles con HTTP GET y POST. Rails utiliza algunos "trucos" en los formularios HTML para actuar como si se hubiera enviado una solicitud PUT o DELETE, aunque Rails todavía está usando GET o POST para estos métodos. (Esto explica por qué es posible que no haya utilizado DELETE o PUT en otras plataformas.)

+0

buena explicación. Sin entrar en demasiados detalles, ¿de qué tipo de "engaño" estamos hablando? –

+11

Es bastante simple, en realidad. Al utilizar los métodos de Rails para generar formularios, si especifica PUT o DELETE, Rails realmente PUBLICARÁ el formulario, pero incluye un campo oculto en el formulario que especifica el método HTTP deseado. Luego, al procesar el formulario, Rails busca ese campo oculto y, si existe, informa (a través del objeto de solicitud) que el formulario se envió utilizando DELETE o PUT, aunque realmente se envió mediante POST. Así que, básicamente, si especifica DELETE, request.method returns: delete, aunque el formulario fue POSTed. Todo esto sucede automágicamente. – mipadi

+0

Eso es simple. Gracias. –

6

Eso sería como preguntar por qué "eliminar" un archivo cuando podría simplemente establecer su contenido en cero bytes y el sistema de archivos solo trátelo como una eliminación. HTTP ha admitido verbos que no sean GET/POST para siempre, pero la forma en que evolucionó SOAP algo retorció el significado original de esos verbos. REST es un enfoque más sencillo, de vuelta a lo básico, que usa los verbos tal como fueron concebidos en lugar de inventar algún nuevo concepto de verbo dentro de la carga útil.

8

Aquí está el "methods" section of the HTTP 1.1 spec; define muchos métodos, y todos tienen diferentes beneficios y compensaciones. POST es el más flexible, pero las compensaciones son numerosas: no es almacenable en caché (por lo que el resto de Internet no puede ayudarlo a escalar), no es seguro ni idempotente, por lo que el cliente no puede volver a enviarlo, se equivoca, y ya no está claro exactamente lo que estás tratando de lograr (porque es muy flexible). Estoy seguro de que hay otros pero eso debería ser suficiente. Dado todo eso, si la especificación HTTP define un método que hace exactamente lo que quiere que haga su solicitud, no hay razón para enviar un POST en su lugar.

El motivo POST es tan común que, al menos históricamente, los navegadores web solo son compatibles con GET y POST. Como el GET se define como seguro e idempotente (aunque muchas aplicaciones no se adhieren a eso), la única forma segura de modificar datos era enviar un POST. Con el aumento de clientes AJAX y no navegadores, ya no es así.

Por cierto, la asignación @mipadi dio es la asignación estándar, pero no es la única válida. Amazon S3, por ejemplo, usa PUT para crear recursos. La única razón para usar POST es si el cliente no tiene los conocimientos suficientes para crear el recurso, por ejemplo, respalda sus recursos con una base de datos relacional y utiliza claves artificiales sustitutivas.

+0

Gracias. No sabía sobre idempotent. Característica interesante Sin embargo, no puedo pensar para qué lo utilizarías. –

+2

Reintentar ante una falla; si no obtienes un 'acuse de recibo', puedes volver a enviarlo; se garantiza que no será diferente de si el primero funcionó. –

0

Solo quería agregar algo a la respuesta aceptada porque es demasiado amplia y una respuesta muy antigua.

voy a destacar algunas de las partes importantes en el RFC 2616 by W3

Voy a comenzar con PUT porque en mi opinión tiene la mayor confusión en torno a ella.

  • PUT is used for both create/update PUT updates by completely replacing the resource on the server with the resource sent in the request

Por ejemplo

a tomar esta llamada a mi api

PUT  /api/person 
{ 
    Name: John, 
    email: [email protected] 
} 

mi servidor tiene esta viviendo en el servidor de recursos

{ 
    Name: Jane, 
    email: [email protected] 
} 

Ahora mi recurso existente se reemplaza completamente por lo que enviaste y esto es lo que tengo en mi servidor.

{ 
    Name: John, 
    email: [email protected] 
} 

Así que si PUT y sólo enviar un correo electrónico en el cuerpo

PUT  /api/person 
{ 
    email: [email protected] 
} 

Mi servidor reemplazará completamente la entidad

{ 
    Name: Jane, 
    email: [email protected] 
} 

Con

{ 
    email: [email protected] 
} 

y nombre será g uno. Las actualizaciones parciales son para PATCH pero uso POST para eso de todos modos.

  • One of the main reasons why we create/update with put is because it is idempotent.

Es sólo un término de lujo y la definición básica de la misma es varias solicitudes idénticas son los mismos para una sola petición.

Ejemplo

Supongamos que PUT un archivo a api/file si el servidor de origen no encuentra ese archivo se creará uno. Si encuentra un archivo, reemplazará completamente el archivo anterior con el que envié. Esto asegura que un archivo se crea y actualiza alguna vez. Si no existe ningún archivo y llama al PUT 5 veces, la primera vez que crea un archivo, las otras 4 veces reemplaza el archivo con lo que envía. Si llama al POST 5 veces para crear, creará 5 archivos.

  • You PUT to that exact URI. If you don't you have to send a 301 (Moved Permanently) to the user and allow then make a choice whether or not to redirect the request. Most times the server you PUT to usually hosts the resource and takes care of updating it

Esos son los puntos más importantes de cuándo utilizar PUT

En lo que se refiere POST

  • You can also create/update and then some...

Como mencioné anteriormente, hay algunas diferencias clave.

  • Mensaje es más General. ¿De qué maneras?algunos otros ejemplos incluyen una puerta de enlace a otros protocolos, podría tomar la respuesta y enviarla a algún manejador de datos a mediados de ese año, o puede extender algún tipo de funcionalidad.
  • La publicación no tiene la restricción de "Para el URI exacto o notifiy", por ejemplo, POST puede agregar un recurso a una colección existente y decidir dónde se almacena.

Ahora qué pasa con Delete ¿Por qué no acabo de POST?

Cuando DELETE, el servidor NO DEBE responden con éxito a menos que elimine el recurso o la traslade a un lugar inaccesible en el momento de la respuesta se envía.

¿Por qué es eso importante? ¿Qué sucede si llama al DELETE pero el recurso debe pasar por "APROBACIÓN" antes de eliminarse? Si se puede rechazar la eliminación, no se puede enviar un código de error exitoso y si se siguen las especificaciones básicas de esto, es confuso para la persona que llama. Solo un ejemplo, estoy seguro de que puedes pensar en muchos otros.

acabo de relieve algunos de los principales puntos sobre cuándo usar el común Http verbs

Cuestiones relacionadas