Pregunta PUT vs. POST en RESTO


De acuerdo con la especificación HTTP / 1.1:

los POST método se utiliza para solicitar que el servidor de origen acepte la entidad incluida en la solicitud como un nuevo subordinado del recurso identificado por el Request-URI en el Request-Line

En otras palabras, POST se usa para crear.

los PUT método solicita que la entidad adjunta se almacene bajo el Request-URI. Si el Request-URI se refiere a un recurso ya existente, la entidad adjunta DEBERÍA considerarse como una versión modificada de la que reside en el servidor de origen. Si el Request-URI no apunta a un recurso existente, y ese URI puede ser definido como un nuevo recurso por el agente de usuario solicitante, el servidor de origen puede crear el recurso con ese URI ".

Es decir, PUT se usa para crear o actualizar.

Entonces, ¿cuál debería usarse para crear un recurso? O uno necesita para apoyar ambos?


4456
2018-03-10 14:25


origen


Respuestas:


En general: 

Tanto PUT como POST se pueden usar para crear.

Tienes que preguntar "¿a qué estás llevando a cabo la acción?" para distinguir lo que deberías estar usando Supongamos que estás diseñando una API para hacer preguntas. Si quiere usar POST, entonces haría eso en una lista de preguntas. Si quieres usar PUT, lo harías con una pregunta en particular.

Se pueden usar ambos, así que ¿cuál debería usar en mi diseño RESTful?

No es necesario que admita tanto PUT como POST.

Lo que se usa depende de ti. Pero recuerde usar la correcta dependiendo de a qué objeto se refiera en la solicitud.

Algunas consideraciones:

  • ¿Nombra los objetos URL que crea explícitamente, o deja que el servidor decida? Si los nombra, entonces use PUT. Si deja que el servidor decida, use POST.
  • PUT es idempotente, por lo que si PONE un objeto dos veces, no tiene ningún efecto. Esta es una propiedad agradable, así que usaría PUT cuando sea posible.
  • Puede actualizar o crear un recurso con PUT con la misma URL objeto
  • Con POST puede tener 2 solicitudes entrando al mismo tiempo haciendo modificaciones a una URL, y pueden actualizar diferentes partes del objeto.

Un ejemplo:

Escribí lo siguiente como parte de otra respuesta sobre SO con respecto a esto:

ENVIAR:

Usado para modificar y actualizar un recurso

POST /questions/<existing_question> HTTP/1.1
Host: www.example.com/

Tenga en cuenta que el siguiente es un error:

POST /questions/<new_question> HTTP/1.1
Host: www.example.com/

Si la URL aún no se ha creado,   no debería estar usando POST para crearlo   mientras especifica el nombre. Esto debería   provocar un error de 'recurso no encontrado'   porque <new_question> no existe   todavía. Deberías PONER el <new_question>   recurso en el servidor primero.

Aunque podrías hacer algo como   esto para crear recursos usando POST:

POST /questions HTTP/1.1
Host: www.example.com/

Tenga en cuenta que en este caso el recurso   nombre no se especifica, los nuevos objetos   La ruta URL se le devolverá.

PONER: 

Se usa para crear un recurso, o   sobrescribirlo. Mientras especificas el   recursos nueva URL.

Para un nuevo recurso:

PUT /questions/<new_question> HTTP/1.1
Host: www.example.com/

Para sobrescribir un recurso existente:

PUT /questions/<existing_question> HTTP/1.1
Host: www.example.com/

3480
2018-03-10 14:29



Puede encontrar afirmaciones en la web que dicen

Ninguno de los dos está en lo cierto.


Mejor es elegir entre PUT y POST basado en idempotencia de la acción

PONER implica poner un recurso, reemplazando completamente lo que está disponible en la URL dada por algo diferente. Por definición, un PUT es idempotente. Hazlo tantas veces como quieras, y el resultado es el mismo. x=5 es idempotente. Puede PONER un recurso ya sea que exista o no (por ejemplo, Crear o Actualizar).

ENVIAR actualiza un recurso, agrega un recurso secundario o causa un cambio. Un POST no es idempotente, en la forma en que x++ no es idempotente


Con este argumento, PUT es para crear cuando conoces la URL de lo que vas a crear. POST se puede usar para crear cuando conoce la URL de la "fábrica" ​​o gerente para la categoría de cosas que desea crear.

asi que:

POST /expense-report

o:

PUT  /expense-report/10929

1878
2018-04-22 14:55



  • ENVIAR a una URL crea un recurso infantil en un servidor definido URL.
  • PONER a una URL crea / reemplaza el recurso en su totalidad en el cliente definido URL.
  • PARCHE a una URL actualizaciones parte del recurso en esa URL definida por el cliente.

La especificación relevante para PUT y POST es RFC 2616 §9.5ff.

POST crea un recurso hijo, entonces POST para /items crea un recurso que vive bajo el /items recurso. P.ej. /items/1. Enviar el mismo paquete de correos dos veces creará dos recursos.

PONER es para crear o reemplazar un recurso en un URL conocida por el cliente.

Por lo tanto: PONER es solo un candidato para CREAR donde el cliente ya conoce la url antes de que se cree el recurso. P.ej. /blogs/nigel/entry/when_to_use_post_vs_put como el título se usa como la clave de recursos

PONER reemplaza el recurso en la url conocida si ya existe, por lo que enviar la misma solicitud dos veces no tiene ningún efecto. En otras palabras, las llamadas a PUT son idempotentes.

El RFC se lee así:

La diferencia fundamental entre las solicitudes POST y PUT se refleja en el significado diferente de Request-URI. El URI en una solicitud POST identifica el recurso que manejará la entidad adjunta. Ese recurso puede ser un proceso de aceptación de datos, una puerta de enlace a algún otro protocolo o una entidad separada que acepta anotaciones. Por el contrario, el URI en una solicitud PUT identifica la entidad adjunta a la solicitud: el agente de usuario sabe qué URI está destinado y el servidor NO DEBE intentar aplicar la solicitud a algún otro recurso. Si el servidor desea que la solicitud se aplique a un URI diferente,

Nota: PUT se ha utilizado principalmente para actualizar los recursos (reemplazándolos en su totalidad), pero recientemente se está avanzando hacia el uso de PATCH para actualizar los recursos existentes, ya que PUT especifica que reemplaza todo el recurso. RFC 5789.


562
2018-04-07 05:52



Resumen:

Crear:

Se puede realizar con PUT o POST de la siguiente manera:

PONER

Crea EL nuevo recurso con newResourceId como identificador, en / URI de recursos, o colección.

PUT /resources/<newResourceId> HTTP/1.1 

ENVIAR

Crea UN nuevo recurso bajo / URI de recursos, o colección. Por lo general, el servidor devuelve el identificador.

POST /resources HTTP/1.1

Actualizar:

Poder solamente se realizará con PUT de la siguiente manera:

PONER

Actualiza el recurso con existingResourceId como identificador, en / URI de recursos, o colección.

PUT /resources/<existingResourceId> HTTP/1.1

Explicación:

Cuando se trata de REST y URI como general, tiene genérico sobre el izquierda y específico sobre el derecho. los genéricos usualmente se llaman colecciones y más específico los artículos se pueden llamar recurso. Tenga en cuenta que recurso puede contener un colección.

Ejemplos:

<- genérico - específico ->

URI: website.com/users/john
website.com  - whole site
users        - collection of users
john         - item of the collection, or a resource

URI:website.com/users/john/posts/23
website.com  - whole site
users        - collection of users
john         - item of the collection, or a resource
posts        - collection of posts from john
23           - post from john with identifier 23, also a resource

Cuando usas POST eres siempre refiriéndose a un colección, así que cada vez que digas:

POST /users HTTP/1.1

está publicando un nuevo usuario en el usuarios  colección.

Si continúa y prueba algo como esto:

POST /users/john HTTP/1.1

funcionará, pero semánticamente está diciendo que desea agregar un recurso al John  colección bajo la usuarios  colección.

Una vez que está utilizando PUT, se está refiriendo a recurso o artículo individual, posiblemente dentro de una colección. Entonces cuando dices:

PUT /users/john HTTP/1.1

le está diciendo a la actualización del servidor, o crea si no existe, la John  recurso bajo la usuarios  colección.

Especulación:

Permítanme resaltar algunas partes importantes de la especificación:

ENVIAR

los ENVIAR método se utiliza para solicitar que el servidor de origen aceptar la entidad incluida en la solicitud como nuevo subordinar del recurso identificado por el URI de solicitud en la línea de solicitud

Por lo tanto, crea un nuevo recurso en un colección.

PONER

los PONER método solicita que la entidad adjunta sea almacenado bajo el Request-URI provisto. Si el URI de solicitud se refiere a un ya existe recurso, la entidad adjunta DEBERÍA considerarse como una versión modificada del que reside en el servidor de origen. Si el URI de solicitud lo hace no apuntar a un existente recurso, y ese URI es capaz de ser definido como un nuevo recurso por el agente de usuario solicitante, el servidor de origen puede crear el recurso con ese URI ".

Por lo tanto, crea o actualiza en función de la existencia del recurso.

Referencia:


165
2017-08-14 22:47



Me gustaría agregar mi consejo "pragmático". Use PUT cuando sepa el "id" por el cual se puede recuperar el objeto que está guardando. El uso de PUT no funcionará demasiado bien si necesita, por ejemplo, una identificación generada de base de datos que se le devolverá para que pueda realizar búsquedas o actualizaciones futuras.

Entonces: para guardar un usuario existente, o uno donde el cliente genera el id. Y se ha verificado que el id es único:

PUT /user/12345 HTTP/1.1  <-- create the user providing the id 12345
Host: mydomain.com

GET /user/12345 HTTP/1.1  <-- return that user
Host: mydomain.com

De lo contrario, use POST para crear inicialmente el objeto y PUT para actualizar el objeto:

POST /user HTTP/1.1   <--- create the user, server returns 12345
Host: mydomain.com

PUT /user/12345 HTTP/1.1  <--- update the user
Host: mydomain.com

156
2018-01-15 19:59



POST significa "crear nuevo" como en "Aquí está la entrada para crear un usuario, créelo por mí".

PUT significa "insertar, reemplazar si ya existe" como en "Aquí están los datos para el usuario 5".

Usted POST a example.com/users debido a que aún no conoce la URL del usuario, quiere que el servidor la cree.

Has PUT a example.com/users/id ya que quieres reemplazar / crear un específico usuario.

Publicar dos veces con los mismos datos significa crear dos usuarios idénticos con diferentes ID. Al presionar dos veces con los mismos datos, se crea el usuario el primero y se lo actualiza al mismo estado por segunda vez (sin cambios). Como termina con el mismo estado después de una PUT, sin importar cuántas veces lo realice, se dice que es "igualmente potente" cada vez - idempotente. Esto es útil para reintentar automáticamente las solicitudes. No más "¿estás seguro de que deseas reenviar?" Cuando presionas el botón Atrás en el navegador.

Un consejo general es usar POST cuando necesite que el servidor tenga el control de la generación de URL de sus recursos. Use PUT de lo contrario. Prefiere PUT sobre POST.


145
2017-10-23 14:27



Use POST para crear y PUT para actualizar. Así es como Ruby on Rails lo está haciendo, de todos modos.

PUT    /items/1      #=> update
POST   /items        #=> create

105
2018-03-10 14:28



REST es un muy concepto de alto nivel. De hecho, ¡ni siquiera menciona HTTP!

Si tiene alguna duda sobre cómo implementar REST en HTTP, siempre puede echarle un vistazo al Protocolo de publicación Atom (AtomPub) especificación. AtomPub es un estándar para escribir servicios web RESTful con HTTP que fue desarrollado por muchas luminarias HTTP y REST, con algunas aportaciones de Roy Fielding, el inventor de REST y (co) inventor de HTTP mismo.

De hecho, es posible que incluso pueda usar AtomPub directamente. Si bien salió de la comunidad de blogs, no está de ninguna manera restringido a los blogs: es un protocolo genérico para interactuar de forma RESTANTE con colecciones arbitrarias (anidadas) de recursos arbitrarios a través de HTTP. Si puede representar su aplicación como una colección anidada de recursos, entonces puede simplemente usar AtomPub y no preocuparse por si usar PUT o POST, qué códigos de estado HTTP devolver y todos esos detalles.

Esto es lo que AtomPub tiene que decir sobre la creación de recursos (sección 9.2):

Para agregar miembros a una Colección, los clientes envían solicitudes POST al URI de la Colección.


58
2018-03-10 15:27



La decisión de utilizar PUT o POST para crear un recurso en un servidor con una API HTTP + REST se basa en quién posee la estructura de la URL. Hacer que el cliente conozca o participe en la definición, la estructura URL es un acoplamiento innecesario similar a los acoplamientos indeseables que surgieron de SOA. Escapar tipos de acoplamientos es la razón por la que REST es tan popular. Por lo tanto, el método apropiado para usar es POST. Existen excepciones a esta regla y se producen cuando el cliente desea mantener el control sobre la estructura de ubicación de los recursos que implementa. Esto es raro y probablemente significa que algo más está mal.

En este punto, algunas personas argumentarán que si RESTful-URL's se utilizan, el cliente sabe la URL del recurso y, por lo tanto, es aceptable un PUT. Después de todo, esta es la razón por la que las URL de Django canónicas, normalizadas, Ruby on Rails son importantes, mira la API de Twitter ... bla, bla, bla. Esas personas necesitan entender no hay tal cosa como una Restful-URL y eso Roy Fielding mismo declara que:

Una API REST no debe definir nombres de recursos fijos o jerarquías (un   acoplamiento obvio de cliente y servidor). Los servidores deben tener la libertad   para controlar su propio espacio de nombres. En cambio, permita que los servidores instruyan   clientes sobre cómo construir URI apropiados, como se hace en HTML   formularios y plantillas de URI, definiendo esas instrucciones dentro de los medios   tipos y relaciones de enlace. [El fracaso aquí implica que los clientes son   asumiendo una estructura de recursos debido a la información fuera de banda, como   un estándar específico de dominio, que es el equivalente a datos   Acoplamiento funcional de RPC].

http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven

La idea de un RESTful-URL es en realidad una violación de REST ya que el servidor está a cargo de la estructura de la URL y debe ser libre de decidir cómo usarla para evitar el acoplamiento. Si esto te confunde, lee sobre la importancia del autodescubrimiento en el diseño de la API.

Usar POST para crear recursos viene con una consideración de diseño porque POST no es idempotente. Esto significa que repetir un POST varias veces no garantiza el mismo comportamiento cada vez. Esto asusta a las personas a usar PUT para crear recursos cuando no deberían. Saben que está mal (POST es para CREAR) pero lo hacen de todos modos porque no saben cómo resolver este problema. Esta preocupación se demuestra en la siguiente situación:

  1. El cliente POST un nuevo recurso para el servidor.
  2. El servidor procesa la solicitud y envía una respuesta.
  3. El cliente nunca recibe la respuesta.
  4. El servidor no sabe que el cliente no ha recibido la respuesta.
  5. El cliente no tiene una URL para el recurso (por lo tanto, PUT no es una opción) y repite el POST.
  6. POST no es idempotente y el servidor ...

El paso 6 es donde la gente comúnmente se confunde sobre qué hacer. Sin embargo, no hay ninguna razón para crear un kludge para resolver este problema. En cambio, HTTP puede usarse como se especifica en RFC 2616 y el servidor responde:

10.4.10 409 Conflicto

La solicitud no pudo completarse debido a un conflicto con el actual   estado del recurso. Este código solo está permitido en situaciones donde   se espera que el usuario pueda resolver el conflicto y   vuelva a enviar la solicitud. El cuerpo de respuesta DEBE incluir suficiente

información para que el usuario reconozca la fuente del conflicto.   Idealmente, la entidad de respuesta incluiría suficiente información para el   usuario o agente de usuario para arreglar el problema; sin embargo, eso podría no ser   posible y no es requerido.

Es más probable que se produzcan conflictos en respuesta a una solicitud PUT. por   ejemplo, si las versiones se estaban usando y la entidad se PUT   cambios incluidos a un recurso que entran en conflicto con los realizados por un   solicitud anterior (de terceros), el servidor podría usar la respuesta 409   para indicar que no puede completar la solicitud. En este caso, el   la entidad de respuesta probablemente contendría una lista de las diferencias entre   las dos versiones en un formato definido por la respuesta Content-Type.

Responder con un código de estado de 409 Conflicto es el recurso correcto porque:

  • La realización de una POST de datos que tiene una ID que coincide con un recurso que ya está en el sistema es "un conflicto con el estado actual del recurso".
  • Dado que la parte importante es que el cliente entienda que el servidor tiene el recurso y que tome las medidas apropiadas. Esta es una "situación (es) en la que se espera que el usuario pueda resolver el conflicto y volver a enviar la solicitud".
  • Una respuesta que contiene la URL del recurso con la ID conflictiva y las condiciones previas apropiadas para el recurso proporcionaría "información suficiente para que el usuario o el agente de usuario corrijan el problema", que es el caso ideal según RFC 2616.

Actualización basada en el lanzamiento de RFC 7231 para reemplazar 2616

RFC 7231 está diseñado para reemplazar 2616 y en Sección 4.3.3 describe la siguiente respuesta posible para un POST

Si el resultado del procesamiento de un POST sería equivalente a un   representación de un recurso existente, un servidor de origen PUEDE redirigir   el agente de usuario de ese recurso enviando una respuesta 303 (Ver Otro)   con el identificador del recurso existente en el campo Ubicación. Esta   tiene los beneficios de proporcionar al agente de usuario un identificador de recursos   y la transferencia de la representación a través de un método más adecuado para   almacenamiento en caché compartido, aunque a costa de una solicitud adicional si el usuario   agente ya no tiene la representación en caché.

Ahora puede ser tentador simplemente devolver un 303 en caso de que se repita una POST. Sin embargo, lo opuesto es verdadero. Devolver un 303 solo tendría sentido si múltiples solicitudes de creación (creando diferentes recursos) devuelven el mismo contenido. Un ejemplo sería un "gracias por enviar su mensaje de solicitud" que el cliente no necesita volver a descargar cada vez. RFC 7231 todavía mantiene en la sección 4.2.2 que POST no debe ser idempotente y continúa manteniendo que POST se debe usar para crear.

Para más información sobre esto, lea esto artículo.


54
2017-10-29 23:00



Me gusta este consejo, desde La definición de RFC 2616 de PUT:

La diferencia fundamental entre las solicitudes POST y PUT se refleja en el significado diferente de Request-URI. El URI en una solicitud POST identifica el recurso que manejará la entidad adjunta. Ese recurso puede ser un proceso de aceptación de datos, una puerta de enlace a algún otro protocolo o una entidad separada que acepta anotaciones. Por el contrario, el URI en una solicitud PUT identifica la entidad adjunta a la solicitud: el agente de usuario sabe qué URI está destinado y el servidor NO DEBE intentar aplicar la solicitud a algún otro recurso.

Esto concuerda con los otros consejos aquí, que PUT se aplica mejor a recursos que ya tienen un nombre, y POST es bueno para crear un nuevo objeto en un recurso existente (y dejar que el servidor lo nombre).

Interpreto esto, y los requisitos de idempotencia en PUT, en el sentido de que:

  • POST es bueno para crear nuevos objetos en una colección (y create no necesita ser idempotente)
  • PUT es bueno para actualizar objetos existentes (y la actualización debe ser idempotente)
  • POST también se puede usar para actualizaciones no idempotentes a objetos existentes (especialmente, cambiar parte de un objeto sin especificarlo todo; si lo piensas, crear un nuevo miembro de una colección es en realidad un caso especial de este tipo de actualización, desde la perspectiva de la colección)
  • PUT también se puede usar para crear si y solo si permite que el cliente nombre el recurso. Pero dado que los clientes de REST no deben hacer suposiciones sobre la estructura de la URL, esto es menos en el espíritu pretendido.

48
2018-01-11 17:18



Ambos se utilizan para la transmisión de datos entre el cliente y el servidor, pero existen diferencias sutiles entre ellos, que son:

Enter image description here

Analogía:

  • PON, es decir, tomar y PONER
  • POST como enviar correo en la oficina de correos.

enter image description here


41
2017-09-11 13:12